This is an automated email from the ASF dual-hosted git repository.

virajjasani pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/phoenix-adapters.git


The following commit(s) were added to refs/heads/main by this push:
     new 0851236  UpdateContinuousBackup API
0851236 is described below

commit 085123686316c96504a061d1a7eb72aacaa19d36
Author: Palash Chauhan <[email protected]>
AuthorDate: Tue May 19 13:10:07 2026 -0700

    UpdateContinuousBackup API
---
 .../org/apache/phoenix/ddb/rest/RootResource.java  |   7 +
 .../phoenix/ddb/rest/metrics/ApiOperation.java     |   1 +
 .../service/UpdateContinuousBackupsService.java    |  58 +++++++
 .../phoenix/ddb/UpdateContinuousBackupsIT.java     | 180 +++++++++++++++++++++
 .../org/apache/phoenix/ddb/utils/ApiMetadata.java  |   1 +
 5 files changed, 247 insertions(+)

diff --git 
a/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/RootResource.java 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/RootResource.java
index b99abcc..bd60624 100644
--- 
a/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/RootResource.java
+++ 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/RootResource.java
@@ -56,6 +56,7 @@ import org.apache.phoenix.ddb.service.PutItemService;
 import org.apache.phoenix.ddb.service.QueryService;
 import org.apache.phoenix.ddb.service.ScanService;
 import org.apache.phoenix.ddb.service.TTLService;
+import org.apache.phoenix.ddb.service.UpdateContinuousBackupsService;
 import org.apache.phoenix.ddb.service.UpdateItemService;
 import org.apache.phoenix.ddb.service.UpdateTableService;
 import org.apache.phoenix.ddb.service.exceptions.ConditionCheckFailedException;
@@ -138,6 +139,12 @@ public class RootResource {
                                     jdbcConnectionUrl);
                     break;
                 }
+                case ApiMetadata.UPDATE_CONTINUOUS_BACKUPS: {
+                    responseObject =
+                            
UpdateContinuousBackupsService.updateContinuousBackups(request,
+                                    jdbcConnectionUrl);
+                    break;
+                }
                 case ApiMetadata.LIST_TABLES: {
                     responseObject = ListTablesService.listTables(request, 
jdbcConnectionUrl);
                     break;
diff --git 
a/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/metrics/ApiOperation.java
 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/metrics/ApiOperation.java
index 9fbcbb0..473d7f6 100644
--- 
a/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/metrics/ApiOperation.java
+++ 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/rest/metrics/ApiOperation.java
@@ -7,6 +7,7 @@ public enum ApiOperation {
     DELETE_TABLE(ApiMetadata.DELETE_TABLE, "DeleteTable"),
     DESCRIBE_TABLE(ApiMetadata.DESCRIBE_TABLE, "DescribeTable"), 
DESCRIBE_CONTINUOUS_BACKUPS(
             ApiMetadata.DESCRIBE_CONTINUOUS_BACKUPS, 
"DescribeContinuousBackups"),
+    UPDATE_CONTINUOUS_BACKUPS(ApiMetadata.UPDATE_CONTINUOUS_BACKUPS, 
"UpdateContinuousBackups"),
     LIST_TABLES(ApiMetadata.LIST_TABLES, "ListTables"),
     UPDATE_TABLE(ApiMetadata.UPDATE_TABLE, "UpdateTable"),
     PUT_ITEM(ApiMetadata.PUT_ITEM, "PutItem"),
diff --git 
a/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/service/UpdateContinuousBackupsService.java
 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/service/UpdateContinuousBackupsService.java
new file mode 100644
index 0000000..3b9170e
--- /dev/null
+++ 
b/phoenix-ddb-rest/src/main/java/org/apache/phoenix/ddb/service/UpdateContinuousBackupsService.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.phoenix.ddb.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.phoenix.ddb.service.utils.TableDescriptorUtils;
+import org.apache.phoenix.ddb.utils.ApiMetadata;
+
+/**
+ * Service class for handling UpdateContinuousBackups API requests.
+ * Always returns DISABLED status as Phoenix does not support continuous 
backups.
+ * This is a no-op stub for KCL parity.
+ */
+public class UpdateContinuousBackupsService {
+
+    public static Map<String, Object> updateContinuousBackups(Map<String, 
Object> request,
+            String connectionUrl) {
+        String tableName = (String) request.get(ApiMetadata.TABLE_NAME);
+
+        // Check if table exists - this will throw appropriate exception if 
table doesn't exist
+        TableDescriptorUtils.getTableDescription(tableName, connectionUrl, 
"Table");
+
+        // Create response with DISABLED continuous backups (no-op - backups 
are not supported)
+        Map<String, Object> response = new HashMap<>();
+        Map<String, Object> continuousBackupsDescription = new HashMap<>();
+
+        // Set continuous backups status to DISABLED
+        continuousBackupsDescription.put("ContinuousBackupsStatus", 
"DISABLED");
+
+        // Add point in time recovery description (also disabled)
+        Map<String, Object> pointInTimeRecoveryDescription = new HashMap<>();
+        pointInTimeRecoveryDescription.put("PointInTimeRecoveryStatus", 
"DISABLED");
+        continuousBackupsDescription.put("PointInTimeRecoveryDescription",
+                pointInTimeRecoveryDescription);
+
+        response.put("ContinuousBackupsDescription", 
continuousBackupsDescription);
+
+        return response;
+    }
+}
diff --git 
a/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateContinuousBackupsIT.java
 
b/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateContinuousBackupsIT.java
new file mode 100644
index 0000000..c1eda09
--- /dev/null
+++ 
b/phoenix-ddb-rest/src/test/java/org/apache/phoenix/ddb/UpdateContinuousBackupsIT.java
@@ -0,0 +1,180 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.phoenix.ddb;
+
+import java.sql.DriverManager;
+import java.util.Map;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
+import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
+import 
software.amazon.awssdk.services.dynamodb.model.PointInTimeRecoverySpecification;
+import 
software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
+import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
+import 
software.amazon.awssdk.services.dynamodb.model.UpdateContinuousBackupsRequest;
+import 
software.amazon.awssdk.services.dynamodb.model.UpdateContinuousBackupsResponse;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseTestingUtility;
+import org.apache.phoenix.coprocessor.PhoenixMasterObserver;
+import org.apache.phoenix.ddb.rest.RESTServer;
+import org.apache.phoenix.end2end.ServerMetadataCacheTestImpl;
+import org.apache.phoenix.jdbc.PhoenixDriver;
+import org.apache.phoenix.jdbc.PhoenixTestDriver;
+import org.apache.phoenix.thirdparty.com.google.common.collect.Maps;
+import org.apache.phoenix.util.PhoenixRuntime;
+import org.apache.phoenix.util.ReadOnlyProps;
+import org.apache.phoenix.util.ServerUtil;
+
+import static org.apache.phoenix.query.BaseTest.setUpConfigForMiniCluster;
+
+/**
+ * Integration tests for UpdateContinuousBackups API.
+ */
+public class UpdateContinuousBackupsIT {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(UpdateContinuousBackupsIT.class);
+
+    private static final String NON_EXISTENT_TABLE_ERROR =
+            "Cannot do operations on a non-existent table (Service: DynamoDb, 
Status Code: 400,";
+
+    private static DynamoDbClient phoenixDBClientV2;
+
+    private static String url;
+    private static HBaseTestingUtility utility = null;
+    private static String tmpDir;
+    private static RESTServer restServer = null;
+
+    @Rule
+    public final TestName testName = new TestName();
+
+    @BeforeClass
+    public static void initialize() throws Exception {
+        tmpDir = System.getProperty("java.io.tmpdir");
+        LocalDynamoDbTestBase.localDynamoDb().start();
+        Configuration conf = TestUtils.getConfigForMiniCluster();
+        utility = new HBaseTestingUtility(conf);
+        Map<String, String> props = Maps.newHashMapWithExpectedSize(1);
+        props.put("hbase.coprocessor.master.classes", 
PhoenixMasterObserver.class.getName());
+        setUpConfigForMiniCluster(conf, new 
ReadOnlyProps(props.entrySet().iterator()));
+
+        utility.startMiniCluster();
+        String zkQuorum = "localhost:" + 
utility.getZkCluster().getClientPort();
+        url = PhoenixRuntime.JDBC_PROTOCOL + 
PhoenixRuntime.JDBC_PROTOCOL_SEPARATOR + zkQuorum;
+        DriverManager.registerDriver(new PhoenixTestDriver());
+
+        restServer = new RESTServer(utility.getConfiguration());
+        restServer.run();
+
+        LOGGER.info("started {} on port {}", restServer.getClass().getName(), 
restServer.getPort());
+        phoenixDBClientV2 = LocalDynamoDB.createV2Client("http://"; + 
restServer.getServerAddress());
+    }
+
+    @AfterClass
+    public static void stopLocalDynamoDb() throws Exception {
+        LocalDynamoDbTestBase.localDynamoDb().stop();
+        if (restServer != null) {
+            restServer.stop();
+        }
+        ServerUtil.ConnectionFactory.shutdown();
+        try {
+            DriverManager.deregisterDriver(PhoenixDriver.INSTANCE);
+        } finally {
+            if (utility != null) {
+                utility.shutdownMiniCluster();
+            }
+            ServerMetadataCacheTestImpl.resetCache();
+        }
+        System.setProperty("java.io.tmpdir", tmpDir);
+    }
+
+    @Test(timeout = 120000)
+    public void testUpdateContinuousBackupsReturnsDisabled() throws Exception {
+        final String tableName = testName.getMethodName();
+
+        // Create table first
+        CreateTableRequest createTableRequest =
+                DDLTestUtils.getCreateTableRequest(tableName, "hashKey", 
ScalarAttributeType.S,
+                        null, null);
+        phoenixDBClientV2.createTable(createTableRequest);
+
+        // Test UpdateContinuousBackups on Phoenix
+        UpdateContinuousBackupsRequest updateContinuousBackupsRequest =
+                UpdateContinuousBackupsRequest.builder()
+                        .tableName(tableName)
+                        .pointInTimeRecoverySpecification(
+                                PointInTimeRecoverySpecification.builder()
+                                        .pointInTimeRecoveryEnabled(true)
+                                        .build())
+                        .build();
+
+        UpdateContinuousBackupsResponse phoenixResponse =
+                
phoenixDBClientV2.updateContinuousBackups(updateContinuousBackupsRequest);
+
+        // Verify response structure and values
+        Assert.assertNotNull("Response should not be null", phoenixResponse);
+        Assert.assertNotNull("ContinuousBackupsDescription should not be null",
+                phoenixResponse.continuousBackupsDescription());
+
+        // Verify continuous backups status is DISABLED (no-op stub)
+        Assert.assertEquals("ContinuousBackupsStatus should be DISABLED", 
"DISABLED",
+                
phoenixResponse.continuousBackupsDescription().continuousBackupsStatusAsString());
+
+        // Verify point in time recovery is also disabled (no-op stub)
+        Assert.assertNotNull("PointInTimeRecoveryDescription should not be 
null",
+                
phoenixResponse.continuousBackupsDescription().pointInTimeRecoveryDescription());
+        Assert.assertEquals("PointInTimeRecoveryStatus should be DISABLED", 
"DISABLED",
+                
phoenixResponse.continuousBackupsDescription().pointInTimeRecoveryDescription()
+                        .pointInTimeRecoveryStatusAsString());
+    }
+
+    @Test(timeout = 120000)
+    public void testUpdateContinuousBackupsWithNonExistentTable() throws 
Exception {
+        final String nonExistentTableName = "non_existent_table_" + 
System.currentTimeMillis();
+
+        // Test UpdateContinuousBackups on non-existent table
+        UpdateContinuousBackupsRequest updateContinuousBackupsRequest =
+                UpdateContinuousBackupsRequest.builder()
+                        .tableName(nonExistentTableName)
+                        .pointInTimeRecoverySpecification(
+                                PointInTimeRecoverySpecification.builder()
+                                        .pointInTimeRecoveryEnabled(true)
+                                        .build())
+                        .build();
+
+        try {
+            UpdateContinuousBackupsResponse phoenixResponse =
+                    
phoenixDBClientV2.updateContinuousBackups(updateContinuousBackupsRequest);
+
+            // Should not reach here - expecting an exception for non-existent 
table
+            Assert.fail("Expected exception for non-existent table, but got 
response: "
+                    + phoenixResponse);
+
+        } catch (ResourceNotFoundException e) {
+            
Assert.assertTrue(e.getMessage().startsWith(NON_EXISTENT_TABLE_ERROR));
+        }
+    }
+}
diff --git 
a/phoenix-ddb-utils/src/main/java/org/apache/phoenix/ddb/utils/ApiMetadata.java 
b/phoenix-ddb-utils/src/main/java/org/apache/phoenix/ddb/utils/ApiMetadata.java
index ca2793b..de67a34 100644
--- 
a/phoenix-ddb-utils/src/main/java/org/apache/phoenix/ddb/utils/ApiMetadata.java
+++ 
b/phoenix-ddb-utils/src/main/java/org/apache/phoenix/ddb/utils/ApiMetadata.java
@@ -172,6 +172,7 @@ public class ApiMetadata {
     public static final String DELETE_TABLE = "DeleteTable";
     public static final String DESCRIBE_TABLE = "DescribeTable";
     public static final String DESCRIBE_CONTINUOUS_BACKUPS = 
"DescribeContinuousBackups";
+    public static final String UPDATE_CONTINUOUS_BACKUPS = 
"UpdateContinuousBackups";
     public static final String LIST_TABLES = "ListTables";
     public static final String UPDATE_TABLE = "UpdateTable";
     public static final String PUT_ITEM = "PutItem";

Reply via email to