Skip to content

[#11584] feat(iceberg-rest): Gate config endpoints by backend capabilities#11634

Open
laserninja wants to merge 2 commits into
apache:mainfrom
laserninja:fix/11584-config-endpoint-capabilities
Open

[#11584] feat(iceberg-rest): Gate config endpoints by backend capabilities#11634
laserninja wants to merge 2 commits into
apache:mainfrom
laserninja:fix/11584-config-endpoint-capabilities

Conversation

@laserninja

Copy link
Copy Markdown
Collaborator

What changes were proposed in this pull request?

Derive the advertised endpoint set in /v1/config from the backing catalog's capabilities rather than a hardcoded static list. Specifically, gate the V1_SUBMIT_TABLE_SCAN_PLAN endpoint behind CatalogWrapperForREST.supportsScanPlanOperations(), which returns true for non-REST backends (Hive, JDBC, Memory, Custom) where Gravitino performs scan planning locally, and false for REST backends where the upstream catalog owns scan planning.

Why are the changes needed?

IcebergConfigOperations advertises a hardcoded DEFAULT_ENDPOINTS list (including V1_SUBMIT_TABLE_SCAN_PLAN) for every catalog, regardless of whether the configured backend actually supports those operations. A client that trusts the advertised endpoints may call an operation the backend cannot serve, producing confusing runtime errors.

Fix: #11584

Does this PR introduce any user-facing change?

REST backend catalogs will no longer advertise the scan plan endpoint in the /v1/config response. Clients that rely on the advertised endpoints will now correctly see only the operations their catalog backend supports.

How was this patch tested?

  • Added TestIcebergConfigEndpointGating with tests verifying scan plan endpoint is omitted when not supported, and core endpoints are always present.
  • Added testConfigEndpointsContainScanPlanForNonRESTBackend to TestIcebergConfig verifying scan plan IS advertised for non-REST backends.
  • All existing tests pass (11 tests, 0 failures).

@laserninja laserninja force-pushed the fix/11584-config-endpoint-capabilities branch from 364686c to de16fa4 Compare June 13, 2026 04:38
@laserninja laserninja requested review from bharos and roryqi June 13, 2026 04:40
@github-actions

Copy link
Copy Markdown

Code Coverage Report

Overall Project 67.01% +0.04% 🟢
Files changed 78.26% 🟢

Module Coverage
aliyun 1.72% 🔴
api 46.82% 🟢
authorization-common 85.96% 🟢
aws 3.66% 🔴
azure 2.47% 🔴
catalog-common 10.4% 🔴
catalog-fileset 80.23% 🟢
catalog-glue 66.91% 🟢
catalog-hive 79.44% 🟢
catalog-jdbc-clickhouse 80.02% 🟢
catalog-jdbc-common 44.22% 🟢
catalog-jdbc-doris 80.28% 🟢
catalog-jdbc-hologres 54.03% 🟢
catalog-jdbc-mysql 79.23% 🟢
catalog-jdbc-oceanbase 78.38% 🟢
catalog-jdbc-postgresql 82.29% 🟢
catalog-jdbc-starrocks 78.51% 🟢
catalog-kafka 77.01% 🟢
catalog-lakehouse-generic 58.53% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 85.94% 🟢
catalog-lakehouse-paimon 80.02% 🟢
catalog-model 77.72% 🟢
cli 44.51% 🟢
client-java 78.01% 🟢
common 50.17% 🟢
core 82.38% 🟢
filesystem-hadoop3 77.27% 🟢
flink 0.0% 🔴
flink-common 45.72% 🟢
flink-runtime 0.0% 🔴
gcp 14.12% 🔴
hadoop-common 10.88% 🔴
hive-metastore-common 53.77% 🟢
iceberg-common 58.15% 🟢
iceberg-rest-server 73.98% +0.35% 🟢
idp-basic 86.18% 🟢
integration-test-common 0.0% 🔴
jobs 66.17% 🟢
lance-common 20.83% 🔴
lance-rest-server 60.54% 🟢
lineage 53.02% 🟢
optimizer 82.95% 🟢
optimizer-api 21.95% 🔴
server 85.73% 🟢
server-common 73.79% 🟢
spark 28.57% 🔴
spark-common 41.66% 🟢
trino-connector 40.13% 🟢
Files
Module File Coverage
iceberg-rest-server IcebergConfigOperations.java 98.33% 🟢
CatalogWrapperForREST.java 73.22% 🟢

IcebergCatalogWrapperManager icebergCatalogWrapperManager =
new IcebergCatalogWrapperManagerForTest(
catalogConf, configProvider, false, configProvider.getMetalakeName());
IcebergCatalogWrapperManager icebergCatalogWrapperManager;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we use reflection here?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reflection was used here to keep the overload generic, it accepts any Class<? extends IcebergCatalogWrapperManager> so tests can plug in different wrapper manager subclasses (e.g., NoScanPlanWrapperManager) without adding a new overload for each one.

That said, I can replace the reflection with a Supplier or a simple factory lambda instead, that's cleaner and avoids the unchecked reflection. Would you prefer that approach, or would you rather I just pass in an already-constructed instance?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should avoid reflection asap. Because reflection lacks necessary check in the compile stage. We can only find the issues in the runtime stage.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, agreed. I'll replace the reflection with a factory lambda (Function<..., IcebergCatalogWrapperManager>) so the constructor call is checked at compile time. Will push the update shortly.

Derive the advertised endpoint set from the backing catalog's capabilities
rather than a static list. Gate V1_SUBMIT_TABLE_SCAN_PLAN behind
CatalogWrapperForREST.supportsScanPlanOperations(), which returns true for
non-REST backends (Hive, JDBC, Memory, Custom) and false for REST backends
where the upstream catalog owns scan planning.

Fixes apache#11584
@laserninja laserninja force-pushed the fix/11584-config-endpoint-capabilities branch from de16fa4 to ee403d9 Compare June 17, 2026 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Improvement] Advertise /v1/config endpoints based on actual catalog backend capabilities

2 participants