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 Summary

    Fields
    Modifier and Type
    Field
    Description
    protected org.apache.iceberg.catalog.Catalog
     
    protected org.apache.iceberg.catalog.SupportsNamespaces
     
    static final String
     
    static final String
     
    protected org.apache.iceberg.catalog.ViewCatalog
     

    Fields inherited from class org.apache.polaris.service.catalog.common.CatalogHandler

    authenticatedPrincipal, authorizer, callContext, catalogName, entityManager, resolutionManifest, securityContext
  • Constructor Summary

    Constructors
    Constructor
    Description
    IcebergCatalogHandler(org.apache.polaris.core.context.CallContext callContext, org.apache.polaris.core.persistence.PolarisEntityManager entityManager, org.apache.polaris.core.persistence.PolarisMetaStoreManager metaStoreManager, org.apache.polaris.core.secrets.UserSecretsManager userSecretsManager, jakarta.ws.rs.core.SecurityContext securityContext, CallContextCatalogFactory catalogFactory, String catalogName, org.apache.polaris.core.auth.PolarisAuthorizer authorizer, ReservedProperties reservedProperties, CatalogHandlerUtils catalogHandlerUtils)
     
  • Method Summary

    Modifier and Type
    Method
    Description
    void
     
    void
    commitTransaction(org.apache.iceberg.rest.requests.CommitTransactionRequest commitTransactionRequest)
     
    org.apache.iceberg.rest.responses.CreateNamespaceResponse
    createNamespace(org.apache.iceberg.rest.requests.CreateNamespaceRequest request)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    createTableDirect(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
    Create a table.
    org.apache.iceberg.rest.responses.LoadTableResponse
    createTableDirectWithWriteDelegation(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
    Create a table.
    org.apache.iceberg.rest.responses.LoadTableResponse
    createTableStaged(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    createTableStagedWithWriteDelegation(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateTableRequest request)
     
    org.apache.iceberg.rest.responses.LoadViewResponse
    createView(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.CreateViewRequest request)
     
    void
    dropNamespace(org.apache.iceberg.catalog.Namespace namespace)
     
    void
    dropTableWithoutPurge(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
     
    void
    dropTableWithPurge(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
     
    void
    dropView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
     
    protected void
    Initialize the catalog once authorized.
    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.
    org.apache.iceberg.rest.responses.ListNamespacesResponse
    listNamespaces(org.apache.iceberg.catalog.Namespace parent)
     
    org.apache.iceberg.rest.responses.ListNamespacesResponse
    listNamespaces(org.apache.iceberg.catalog.Namespace parent, String pageToken, Integer pageSize)
     
    org.apache.iceberg.rest.responses.ListTablesResponse
    listTables(org.apache.iceberg.catalog.Namespace namespace)
     
    org.apache.iceberg.rest.responses.ListTablesResponse
    listTables(org.apache.iceberg.catalog.Namespace namespace, String pageToken, Integer pageSize)
     
    org.apache.iceberg.rest.responses.ListTablesResponse
    listViews(org.apache.iceberg.catalog.Namespace namespace)
     
    org.apache.iceberg.rest.responses.ListTablesResponse
    listViews(org.apache.iceberg.catalog.Namespace namespace, String pageToken, Integer pageSize)
     
    org.apache.iceberg.rest.responses.GetNamespaceResponse
    loadNamespaceMetadata(org.apache.iceberg.catalog.Namespace namespace)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    loadTable(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, String snapshots)
     
    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.
    org.apache.iceberg.rest.responses.LoadTableResponse
    loadTableWithAccessDelegation(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, String snapshots)
     
    Optional<org.apache.iceberg.rest.responses.LoadTableResponse>
    loadTableWithAccessDelegationIfStale(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, IfNoneMatch ifNoneMatch, String snapshots)
    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.
    org.apache.iceberg.rest.responses.LoadViewResponse
    loadView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
     
    void
    namespaceExists(org.apache.iceberg.catalog.Namespace namespace)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    registerTable(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.RegisterTableRequest request)
    Register a table.
    void
    renameTable(org.apache.iceberg.rest.requests.RenameTableRequest request)
     
    void
    renameView(org.apache.iceberg.rest.requests.RenameTableRequest request)
     
    org.apache.iceberg.rest.responses.LoadViewResponse
    replaceView(org.apache.iceberg.catalog.TableIdentifier viewIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
     
    boolean
    sendNotification(org.apache.iceberg.catalog.TableIdentifier identifier, org.apache.polaris.service.types.NotificationRequest request)
     
    void
    tableExists(org.apache.iceberg.catalog.TableIdentifier tableIdentifier)
     
    org.apache.iceberg.rest.responses.UpdateNamespacePropertiesResponse
    updateNamespaceProperties(org.apache.iceberg.catalog.Namespace namespace, org.apache.iceberg.rest.requests.UpdateNamespacePropertiesRequest request)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    updateTable(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
     
    org.apache.iceberg.rest.responses.LoadTableResponse
    updateTableForStagedCreate(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, org.apache.iceberg.rest.requests.UpdateTableRequest request)
     
    void
    viewExists(org.apache.iceberg.catalog.TableIdentifier viewIdentifier)
     

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • 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.context.CallContext callContext, org.apache.polaris.core.persistence.PolarisEntityManager entityManager, org.apache.polaris.core.persistence.PolarisMetaStoreManager metaStoreManager, org.apache.polaris.core.secrets.UserSecretsManager userSecretsManager, jakarta.ws.rs.core.SecurityContext securityContext, CallContextCatalogFactory catalogFactory, String catalogName, org.apache.polaris.core.auth.PolarisAuthorizer authorizer, ReservedProperties reservedProperties, CatalogHandlerUtils catalogHandlerUtils)
  • 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)
      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
    • 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)
    • 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)
    • loadTableWithAccessDelegationIfStale

      public Optional<org.apache.iceberg.rest.responses.LoadTableResponse> loadTableWithAccessDelegationIfStale(org.apache.iceberg.catalog.TableIdentifier tableIdentifier, IfNoneMatch ifNoneMatch, String snapshots)
      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
    • 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