This is an automated email from the ASF dual-hosted git repository.
roryqi pushed a commit to branch branch-1.2
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/branch-1.2 by this push:
new 195372abbd [Cherry-pick to branch-1.2] [#10841] fix(iceberg): Fix the
issues of the table plan endpoint (#10842) (#10858)
195372abbd is described below
commit 195372abbdb0086a7d4a7ed9bfd65ccd77d53c37
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Fri Apr 24 14:03:19 2026 +0800
[Cherry-pick to branch-1.2] [#10841] fix(iceberg): Fix the issues of the
table plan endpoint (#10842) (#10858)
**Cherry-pick Information:**
- Original commit: 6177bd0550e573bd4292a6e159217b1329f28702
- Target branch: `branch-1.2`
- Status: ✅ Clean cherry-pick (no conflicts)
Co-authored-by: roryqi <[email protected]>
---
.../service/rest/IcebergConfigOperations.java | 8 +++++-
.../service/rest/IcebergTableOperations.java | 2 +-
.../iceberg/service/rest/TestIcebergConfig.java | 33 ++++++++++++++++++++++
.../service/rest/TestIcebergTableOperations.java | 2 +-
4 files changed, 42 insertions(+), 3 deletions(-)
diff --git
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergConfigOperations.java
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergConfigOperations.java
index 719d75ce93..f8c0c28036 100644
---
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergConfigOperations.java
+++
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergConfigOperations.java
@@ -57,6 +57,12 @@ public class IcebergConfigOperations {
private final IcebergCatalogWrapperManager catalogWrapperManager;
+ // TODO: Iceberg 1.10.1's Endpoint.V1_SUBMIT_TABLE_SCAN_PLAN uses a broken
path that is missing
+ // the namespaces/{namespace} segment (fixed in apache/iceberg#14120,
targeting 1.11.x).
+ // We override it here with the correct namespace-scoped path until we
upgrade.
+ private static final Endpoint V1_SUBMIT_TABLE_SCAN_PLAN =
+ Endpoint.create("POST",
"/v1/{prefix}/namespaces/{namespace}/tables/{table}/plan");
+
private static final List<Endpoint> DEFAULT_ENDPOINTS =
ImmutableList.<Endpoint>builder()
.add(Endpoint.V1_LIST_NAMESPACES)
@@ -75,7 +81,7 @@ public class IcebergConfigOperations {
.add(Endpoint.V1_REGISTER_TABLE)
.add(Endpoint.V1_REPORT_METRICS)
.add(Endpoint.V1_TABLE_CREDENTIALS)
- .add(Endpoint.V1_SUBMIT_TABLE_SCAN_PLAN)
+ .add(V1_SUBMIT_TABLE_SCAN_PLAN)
.build();
private static final List<Endpoint> DEFAULT_VIEW_ENDPOINTS =
diff --git
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergTableOperations.java
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergTableOperations.java
index e15de6d51b..e943bb6245 100644
---
a/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergTableOperations.java
+++
b/iceberg/iceberg-rest-server/src/main/java/org/apache/gravitino/iceberg/service/rest/IcebergTableOperations.java
@@ -463,7 +463,7 @@ public class IcebergTableOperations {
* @return Response containing the scan plan with tasks
*/
@POST
- @Path("{table}/scan")
+ @Path("{table}/plan")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@Timed(name = "plan-table-scan." + MetricNames.HTTP_PROCESS_DURATION,
absolute = true)
diff --git
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergConfig.java
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergConfig.java
index 9fafca21bf..2fb36f8042 100644
---
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergConfig.java
+++
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergConfig.java
@@ -127,4 +127,37 @@ public class TestIcebergConfig extends IcebergTestBase {
hasViewListEndpoint,
"Config response should contain view list endpoint for catalog that
supports views");
}
+
+ @Test
+ public void testConfigScanPlanEndpointPathIsNamespaceScoped() {
+ // Iceberg 1.10.1's Endpoint.V1_SUBMIT_TABLE_SCAN_PLAN advertises the
wrong path
+ // (missing namespaces/{namespace}) — fixed in apache/iceberg#14120
(targeting 1.11.x).
+ // This test guards against regressing to the broken path after an Iceberg
upgrade.
+ Response resp = getConfigClientBuilder().get();
+ Assertions.assertEquals(Response.Status.OK.getStatusCode(),
resp.getStatus());
+
+ ConfigResponse response = resp.readEntity(ConfigResponse.class);
+
+ boolean hasScanPlanEndpoint =
+ response.endpoints().stream()
+ .anyMatch(
+ endpoint ->
+ "POST".equals(endpoint.httpMethod())
+ &&
endpoint.path().contains("namespaces/{namespace}/tables/{table}/plan"));
+ Assertions.assertTrue(
+ hasScanPlanEndpoint,
+ "Config response must advertise the namespace-scoped scan plan path: "
+ + "POST /v1/{prefix}/namespaces/{namespace}/tables/{table}/plan");
+
+ boolean hasBrokenScanPlanEndpoint =
+ response.endpoints().stream()
+ .anyMatch(
+ endpoint ->
+ "POST".equals(endpoint.httpMethod())
+ && endpoint.path().endsWith("/tables/{table}/plan")
+ &&
!endpoint.path().contains("namespaces/{namespace}"));
+ Assertions.assertFalse(
+ hasBrokenScanPlanEndpoint,
+ "Config response must not advertise the namespace-less scan plan path
from Iceberg 1.10.1");
+ }
}
diff --git
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergTableOperations.java
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergTableOperations.java
index 606367ecaa..26852f82ea 100644
---
a/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergTableOperations.java
+++
b/iceberg/iceberg-rest-server/src/test/java/org/apache/gravitino/iceberg/service/rest/TestIcebergTableOperations.java
@@ -485,7 +485,7 @@ public class TestIcebergTableOperations extends
IcebergNamespaceTestBase {
}
private Response doPlanTableScan(Namespace ns, String tableName,
PlanTableScanRequest request) {
- Invocation.Builder builder = getTableClientBuilder(ns,
Optional.of(tableName + "/scan"));
+ Invocation.Builder builder = getTableClientBuilder(ns,
Optional.of(tableName + "/plan"));
return builder.post(Entity.entity(request,
MediaType.APPLICATION_JSON_TYPE));
}