Class IcebergCatalogHandler

java.lang.Object
org.apache.polaris.service.catalog.common.CatalogHandler
org.apache.polaris.service.catalog.iceberg.IcebergCatalogHandler
All Implemented Interfaces:
AutoCloseable

public class IcebergCatalogHandler extends CatalogHandler implements AutoCloseable
Authorization-aware adapter between REST stubs and shared Iceberg SDK CatalogHandlers.

We must make authorization decisions based on entity resolution at this layer instead of the underlying PolarisIcebergCatalog layer, because this REST-adjacent layer captures intent of different REST calls that share underlying catalog calls (e.g. updateTable will call loadTable under the hood), and some features of the REST API aren't expressed at all in the underlying Catalog interfaces (e.g. credential-vending in createTable/loadTable).

We also want this layer to be independent of API-endpoint-specific idioms, such as dealing with jakarta.ws.rs.core.Response objects, and other implementations that expose different HTTP stubs or even tunnel the protocol over something like gRPC can still normalize on the Iceberg model objects used in this layer to still benefit from the shared implementation of authorization-aware catalog protocols.

  • Field Details

    • baseCatalog

      protected org.apache.iceberg.catalog.Catalog baseCatalog
    • namespaceCatalog

      protected org.apache.iceberg.catalog.SupportsNamespaces namespaceCatalog
    • viewCatalog

      protected org.apache.iceberg.catalog.ViewCatalog viewCatalog
    • SNAPSHOTS_ALL

      public static final String SNAPSHOTS_ALL
      See Also:
    • SNAPSHOTS_REFS

      public static final String SNAPSHOTS_REFS
      See Also:
  • Constructor Details

    • IcebergCatalogHandler

      public IcebergCatalogHandler(org.apache.polaris.core.PolarisDiagnostics diagnostics, org.apache.polaris.core.context.CallContext callContext, org.apache.polaris.core.persistence.resolver.ResolutionManifestFactory resolutionManifestFactory, org.apache.polaris.core.persistence.PolarisMetaStoreManager metaStoreManager, org.apache.polaris.core.credentials.PolarisCredentialManager credentialManager, org.apache.polaris.core.auth.PolarisPrincipal principal, CallContextCatalogFactory catalogFactory, String catalogName, org.apache.polaris.core.auth.PolarisAuthorizer authorizer, ReservedProperties reservedProperties, CatalogHandlerUtils catalogHandlerUtils, jakarta.enterprise.inject.Instance<org.apache.polaris.core.catalog.ExternalCatalogFactory> externalCatalogFactories, StorageAccessConfigProvider storageAccessConfigProvider)
  • Method Details

    • isCreate

      public static boolean isCreate(org.apache.iceberg.rest.requests.UpdateTableRequest request)
      TODO: Make the helper in org.apache.iceberg.rest.CatalogHandlers public instead of needing to copy/paste here.
    • listNamespaces

      public org.apache.iceberg.rest.responses.ListNamespacesResponse listNamespaces(org.apache.iceberg.catalog.Namespace parent, String pageToken, Integer pageSize)
    • initializeCatalog

      protected void initializeCatalog()
      Description copied from class: CatalogHandler
      Initialize the catalog once authorized. Called after all `authorize...` methods.
      Specified by:
      initializeCatalog in class CatalogHandler
    • listNamespaces

      public org.apache.iceberg.rest.responses.ListNamespacesResponse listNamespaces(org.apache.iceberg.catalog.Namespace parent)
    • createNamespace

      public org.apache.iceberg.rest.responses.CreateNamespaceResponse createNamespace(org.apache.iceberg.rest.requests.CreateNamespaceRequest request)
    • loadNamespaceMetadata

      public org.apache.iceberg.rest.responses.GetNamespaceResponse loadNamespaceMetadata(org.apache.iceberg.catalog.Namespace namespace)
    • namespaceExists

      public void namespaceExists(org.apache.iceberg.catalog.Namespace namespace)
    • dropNamespace

      public void dropNamespace(org.apache.iceberg.catalog.Namespace namespace)
    • updateNamespaceProperties

      public org.apache.iceberg.rest.responses.UpdateNamespacePropertiesResponse updateNamespaceProperties(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.UpdateNamespacePropertiesRequest request)
    • listTables

      public org.apache.iceberg.rest.responses.ListTablesResponse listTables(org.apache.iceberg.catalog.Namespace namespace, String pageToken, Integer pageSize)
    • listTables

      public org.apache.iceberg.rest.responses.ListTablesResponse listTables(org.apache.iceberg.catalog.Namespace namespace)
    • createTableDirect

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableDirect(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
      Create a table.
      Parameters:
      namespace - the namespace to create the table in
      request - the table creation request
      Returns:
      ETagged LoadTableResponse to uniquely identify the table metadata
    • createTableDirectWithWriteDelegation

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableDirectWithWriteDelegation(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request, Optional<String> refreshCredentialsEndpoint)
      Create a table.
      Parameters:
      namespace - the namespace to create the table in
      request - the table creation request
      Returns:
      ETagged LoadTableResponse to uniquely identify the table metadata
    • authorizeCreateTableDirect

      public void authorizeCreateTableDirect(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request, EnumSet<AccessDelegationMode> delegationModes)
    • createTableDirect

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableDirect(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request, EnumSet<AccessDelegationMode> delegationModes, Optional<String> refreshCredentialsEndpoint)
    • createTableStaged

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableStaged(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
    • createTableStagedWithWriteDelegation

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableStagedWithWriteDelegation(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request, Optional<String> refreshCredentialsEndpoint)
    • createTableStaged

      public org.apache.iceberg.rest.responses.LoadTableResponse createTableStaged(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request, EnumSet<AccessDelegationMode> delegationModes, Optional<String> refreshCredentialsEndpoint)
    • registerTable

      public org.apache.iceberg.rest.responses.LoadTableResponse registerTable(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.RegisterTableRequest request)
      Register a table.
      Parameters:
      namespace - The namespace to register the table in
      request - the register table request
      Returns:
      ETagged LoadTableResponse to uniquely identify the table metadata
    • sendNotification

      public boolean sendNotification(org.apache.iceberg.catalog.TableIdentifier identifier, org.apache.polaris.service.types.NotificationRequest request)
    • loadTable

      public org.apache.iceberg.rest.responses.LoadTableResponse loadTable(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, String snapshots)
    • loadTableIfStale

      public Optional<org.apache.iceberg.rest.responses.LoadTableResponse> loadTableIfStale(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, IfNoneMatch ifNoneMatch, String snapshots)
      Attempt to perform a loadTable operation only when the specified set of eTags do not match the current state of the table metadata.
      Parameters:
      tableIdentifier - The identifier of the table to load
      ifNoneMatch - set of entity-tags to check the metadata against for staleness
      snapshots -
      Returns:
      Optional.empty() if the ETag is current, an Optional containing the load table response, otherwise
    • loadTableWithAccessDelegation

      public org.apache.iceberg.rest.responses.LoadTableResponse loadTableWithAccessDelegation(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, String snapshots, Optional<String> refreshCredentialsEndpoint)
    • loadTableWithAccessDelegationIfStale

      public Optional<org.apache.iceberg.rest.responses.LoadTableResponse> loadTableWithAccessDelegationIfStale(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, IfNoneMatch ifNoneMatch, String snapshots, Optional<String> refreshCredentialsEndpoint)
      Attempt to perform a loadTable operation with access delegation only when the if none of the provided eTags match the current state of the table metadata.
      Parameters:
      tableIdentifier - The identifier of the table to load
      ifNoneMatch - set of entity-tags to check the metadata against for staleness
      snapshots -
      Returns:
      Optional.empty() if the ETag is current, an Optional containing the load table response, otherwise
    • loadTable

      public Optional<org.apache.iceberg.rest.responses.LoadTableResponse> loadTable(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, String snapshots, IfNoneMatch ifNoneMatch, EnumSet<AccessDelegationMode> delegationModes, Optional<String> refreshCredentialsEndpoint)
    • updateTable

      public org.apache.iceberg.rest.responses.LoadTableResponse updateTable(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
    • updateTableForStagedCreate

      public org.apache.iceberg.rest.responses.LoadTableResponse updateTableForStagedCreate(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
    • dropTableWithoutPurge

      public void dropTableWithoutPurge(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
    • dropTableWithPurge

      public void dropTableWithPurge(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
    • tableExists

      public void tableExists(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
    • renameTable

      public void renameTable(org.apache.iceberg.rest.requests.RenameTableRequest request)
    • commitTransaction

      public void commitTransaction(org.apache.iceberg.rest.requests.CommitTransactionRequest commitTransactionRequest)
    • listViews

      public org.apache.iceberg.rest.responses.ListTablesResponse listViews(org.apache.iceberg.catalog.Namespace namespace, String pageToken, Integer pageSize)
    • listViews

      public org.apache.iceberg.rest.responses.ListTablesResponse listViews(org.apache.iceberg.catalog.Namespace namespace)
    • createView

      public org.apache.iceberg.rest.responses.LoadViewResponse createView(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateViewRequest request)
    • loadView

      public org.apache.iceberg.rest.responses.LoadViewResponse loadView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
    • replaceView

      public org.apache.iceberg.rest.responses.LoadViewResponse replaceView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
    • dropView

      public void dropView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
    • viewExists

      public void viewExists(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
    • renameView

      public void renameView(org.apache.iceberg.rest.requests.RenameTableRequest request)
    • close

      public void close() throws Exception
      Specified by:
      close in interface AutoCloseable
      Throws:
      Exception