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";