liangyouze commented on issue #5936:
URL: https://github.com/apache/gravitino/issues/5936#issuecomment-5065565030

   I'd like to pick this up and propose a concrete design. This was also 
independently requested in #10607, which suggests putting the metalake into the 
request URI path — the proposal below follows that direction. Feedback welcome 
before I start on the first PR. 
   
     Goal
   
     Allow a single Iceberg REST server (both auxiliary and standalone mode) to 
serve catalogs from multiple metalakes, with authentication and authorization 
working correctly per metalake. Existing single-metalake deployments must keep 
working unchanged.
   
     Design overview
     
     The core change is moving the metalake from a process-level static value 
(resolved once at startup from gravitino.iceberg-rest.gravitino-metalake) to a 
request-level value resolved from the URL prefix.
   
     ## 1. Prefix encoding (no wire-protocol change)
   
     Reuse the existing single-segment prefix, encoded as {metalake}.{catalog}, 
e.g.:
   
    ` /iceberg/v1/mymetalake.mycatalog/namespaces/...`
   
     Clients simply set warehouse=mymetalake.mycatalog. The current prefix 
pattern {prefix:([^/]*/)?} already accepts dots, and /v1/config already echoes 
the warehouse back as the prefix, so no client-side or REST-spec change is 
needed. A prefix without a dot keeps today's semantics (catalog under the 
default metalake), which gives us backward compatibility for free.
   
     (Alternative considered: a two-segment path /v1/{metalake}/{catalog}/.... 
Rejected because the Iceberg REST spec models the prefix as a single opaque 
segment, and multi-segment prefixes break the existing JAX-RS routes and 
clients.)
   
     ## 2. Request context
   
     Add a metalakeName field to IcebergRequestContext, resolved from the 
prefix at the REST layer (one shared helper, e.g. 
IcebergRESTUtils.parseMetalakeAndCatalog(prefix)). All downstream layers read 
the metalake from the context instead of 
IcebergRESTServerContext.getInstance().metalakeName(), which is demoted to 
defaultMetalakeName() (used when the prefix carries no metalake).
   
     ## 3. Config provider SPI (backward compatible)
   
     Add a default method to IcebergConfigProvider:
   ```
     default Optional<IcebergConfig> getIcebergCatalogConfig(String 
metalakeName, String catalogName) {
       return getIcebergCatalogConfig(catalogName); // ignore metalake by 
default
     }
   ```
     Existing third-party providers keep compiling and behaving as before. 
DynamicIcebergConfigProvider implements the new method: the CatalogFetcher 
becomes per-metalake (trivial for the aux-mode internal fetcher; the standalone 
HTTP fetcher keeps a small cache of per-metalake GravitinoClients, since the 
client binds a metalake at build time).
   
     ## 4. Authorization path
     
     Three places currently pin the static metalake and would resolve it per 
request instead:
   
     - IcebergMetadataAuthorizationMethodInterceptor — builds all 
NameIdentifiers (metalake/catalog/schema/table) and runs checkCurrentUser 
against the static metalake. The prefix is already available as an annotated 
parameter, so the interceptor parses (metalake, catalog) from it. 
User-existence check and privilege evaluation then run against the requested 
metalake.
     - LoadTableAuthzHandler / LoadViewAuthzHandler / 
IcebergLoadAuthzHandlerHelper — same change.
     - The hook dispatchers (IcebergTableHookDispatcher, 
IcebergViewHookDispatcher, IcebergNamespaceHookDispatcher) plus 
IcebergOwnershipUtils, IcebergCleanupHelper, IcebergOrphanSchemaCleanup, and 
the event dispatchers — all take the metalake from IcebergRequestContext 
instead of a constructor-injected static value. This makes entity import and 
ownership assignment land under the correct metalake.
   
     ## 5. Security
     
     Since the metalake now comes from the URL, add an allowlist config, e.g. 
gravitino.iceberg-rest.allowed-metalakes (default: only the configured 
gravitino-metalake, preserving current behavior; * opts into all). Combined 
with the per-metalake checkCurrentUser, a user can only reach metalakes they 
belong to.
   
     ## 6. Misc
   
     - IcebergCatalogWrapperManager cache keys become metalake-qualified; the 
aux-mode catalog-cache-invalidation listener matches on the ident's metalake 
instead of the single configured one.
     - Credential-vending refresh endpoints already embed the raw prefix, so 
they keep working.
     - Events/audit will carry the request-level metalake as a natural 
consequence of the context change.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to