From 4f06ed0e18ff6ea8e62dcd506ab3668487fdbcea Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 7 Mar 2025 10:55:54 -0800 Subject: [PATCH 01/18] rename polarisbasecatalog --- .../quarkus/admin/PolarisAuthzTestBase.java | 6 +- ...st.java => PolarisIcebergCatalogTest.java} | 78 +++++++++---------- ...ava => PolarisIcebergCatalogViewTest.java} | 12 +-- .../catalog/PolarisCatalogHandlerWrapper.java | 14 ++-- ...atalog.java => PolarisIcebergCatalog.java} | 10 +-- .../service/catalog/io/FileIOUtil.java | 4 +- .../PolarisCallContextCatalogFactory.java | 6 +- .../service/catalog/io/FileIOFactoryTest.java | 12 +-- 8 files changed, 71 insertions(+), 71 deletions(-) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{BasePolarisCatalogTest.java => PolarisIcebergCatalogTest.java} (97%) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{BasePolarisCatalogViewTest.java => PolarisIcebergCatalogViewTest.java} (96%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{BasePolarisCatalog.java => PolarisIcebergCatalog.java} (99%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index 2b28e9f7f6..f0af61dd3b 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -75,7 +75,7 @@ import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.DefaultConfigurationStore; @@ -174,7 +174,7 @@ public Map getConfigOverrides() { @Inject protected Clock clock; @Inject protected FileIOFactory fileIOFactory; - protected BasePolarisCatalog baseCatalog; + protected PolarisIcebergCatalog baseCatalog; protected PolarisAdminService adminService; protected PolarisEntityManager entityManager; protected PolarisMetaStoreManager metaStoreManager; @@ -431,7 +431,7 @@ private void initBaseCatalog() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); this.baseCatalog = - new BasePolarisCatalog( + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java similarity index 97% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java index b7edeb6f3a..a3ef9ab3d0 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java @@ -107,7 +107,7 @@ import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; @@ -141,8 +141,8 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest -@TestProfile(BasePolarisCatalogTest.Profile.class) -public class BasePolarisCatalogTest extends CatalogTests { +@TestProfile(PolarisIcebergCatalogTest.Profile.class) +public class PolarisIcebergCatalogTest extends CatalogTests { public static class Profile implements QuarkusTestProfile { @@ -174,7 +174,7 @@ public Map getConfigOverrides() { @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; - private BasePolarisCatalog catalog; + private PolarisIcebergCatalog catalog; private CallContext callContext; private AwsStorageConfigInfo storageConfigModel; private StsClient stsClient; @@ -290,7 +290,7 @@ public void before(TestInfo testInfo) { .thenReturn((PolarisStorageIntegration) storageIntegration); this.catalog = - new BasePolarisCatalog( + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -311,7 +311,7 @@ public void after() throws IOException { } @Override - protected BasePolarisCatalog catalog() { + protected PolarisIcebergCatalog catalog() { return catalog; } @@ -376,7 +376,7 @@ public void testRenameTableMissingDestinationNamespace() { requiresNamespaceCreate(), "Only applicable if namespaces must be created before adding children"); - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); catalog.createNamespace(NS); Assertions.assertThat(catalog.tableExists(TABLE)) @@ -420,7 +420,7 @@ public void testCreateNestedNamespaceUnderMissingParent() { Assumptions.assumeTrue( supportsNestedNamespaces(), "Only applicable if nested namespaces are supoprted"); - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace child1 = Namespace.of("parent", "child1"); @@ -441,7 +441,7 @@ public void testValidateNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/validate_table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -504,7 +504,7 @@ public void testValidateNotificationInDisallowedLocation() { // filename. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -548,8 +548,8 @@ public void testValidateNotificationFailToCreateFileIO() { new RealmEntityManagerFactory(createMockMetaStoreManagerFactory()), managerFactory, configurationStore)); - BasePolarisCatalog catalog = - new BasePolarisCatalog( + PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -594,7 +594,7 @@ public void testUpdateNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -638,7 +638,7 @@ public void testUpdateNotificationCreateTableInDisallowedLocation() { // The location of the metadata JSON file specified in the create will be forbidden. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -689,7 +689,7 @@ public void testCreateNotificationCreateTableInExternalLocation() { .addProperty( PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); TableMetadata tableMetadata = TableMetadata.buildFromEmpty() .assignUUID() @@ -746,7 +746,7 @@ public void testCreateNotificationCreateTableOutsideOfMetadataLocation() { .addProperty( PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); TableMetadata tableMetadata = TableMetadata.buildFromEmpty() .assignUUID() @@ -800,7 +800,7 @@ public void testUpdateNotificationCreateTableInExternalLocation() { .addProperty( PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); InMemoryFileIO fileIO = (InMemoryFileIO) catalog.getIo(); fileIO.addFile( @@ -872,8 +872,8 @@ public void testUpdateNotificationCreateTableWithLocalFilePrefix() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, catalogWithoutStorage); TaskExecutor taskExecutor = Mockito.mock(); - BasePolarisCatalog catalog = - new BasePolarisCatalog( + PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -936,8 +936,8 @@ public void testUpdateNotificationCreateTableWithHttpPrefix() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, catalogName); TaskExecutor taskExecutor = Mockito.mock(); - BasePolarisCatalog catalog = - new BasePolarisCatalog( + PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1014,7 +1014,7 @@ public void testUpdateNotificationWhenNamespacesExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1060,7 +1060,7 @@ public void testUpdateNotificationWhenTableExists() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1113,7 +1113,7 @@ public void testUpdateNotificationWhenTableExistsInDisallowedLocation() { // The location of the metadata JSON file specified in the update will be forbidden. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1159,7 +1159,7 @@ public void testUpdateNotificationRejectOutOfOrderTimestamp() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -1224,7 +1224,7 @@ public void testUpdateNotificationWhenTableExistsFileSpecifiesDisallowedLocation final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1273,7 +1273,7 @@ public void testDropNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -1308,7 +1308,7 @@ public void testDropNotificationWhenNamespacesExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1354,7 +1354,7 @@ public void testDropNotificationWhenTableExists() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1477,8 +1477,8 @@ public void testDropTableWithPurgeDisabled() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, noPurgeCatalogName); - BasePolarisCatalog noPurgeCatalog = - new BasePolarisCatalog( + PolarisIcebergCatalog noPurgeCatalog = + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1535,7 +1535,7 @@ private void createNonExistingNamespaces(Namespace namespace) { @ParameterizedTest @MethodSource public void testRetriableException(Exception exception, boolean shouldRetry) { - Assertions.assertThat(BasePolarisCatalog.SHOULD_RETRY_REFRESH_PREDICATE.test(exception)) + Assertions.assertThat(PolarisIcebergCatalog.SHOULD_RETRY_REFRESH_PREDICATE.test(exception)) .isEqualTo(shouldRetry); } @@ -1585,8 +1585,8 @@ public void testFileIOWrapper() { new RealmEntityManagerFactory(createMockMetaStoreManagerFactory()), managerFactory, configurationStore); - BasePolarisCatalog catalog = - new BasePolarisCatalog( + PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1658,7 +1658,7 @@ public FileIO loadFileIO( @Test public void testRegisterTableWithSlashlessMetadataLocation() { - BasePolarisCatalog catalog = catalog(); + PolarisIcebergCatalog catalog = catalog(); Assertions.assertThatThrownBy( () -> catalog.registerTable(TABLE, "metadata_location_without_slashes")) .isInstanceOf(IllegalArgumentException.class) @@ -1682,8 +1682,8 @@ public void testConcurrencyConflictCreateTableUpdatedDuringFinalTransaction() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); - final BasePolarisCatalog catalog = - new BasePolarisCatalog( + final PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, spyMetaStore, callContext, @@ -1730,8 +1730,8 @@ public void testConcurrencyConflictUpdateTableDuringFinalTransaction() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); - final BasePolarisCatalog catalog = - new BasePolarisCatalog( + final PolarisIcebergCatalog catalog = + new PolarisIcebergCatalog( entityManager, spyMetaStore, callContext, diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java similarity index 96% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java index b85443faf2..ebd2a7f463 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/BasePolarisCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java @@ -59,7 +59,7 @@ import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; @@ -73,8 +73,8 @@ import org.mockito.Mockito; @QuarkusTest -@TestProfile(BasePolarisCatalogViewTest.Profile.class) -public class BasePolarisCatalogViewTest extends ViewCatalogTests { +@TestProfile(PolarisIcebergCatalogViewTest.Profile.class) +public class PolarisIcebergCatalogViewTest extends ViewCatalogTests { public static class Profile implements QuarkusTestProfile { @@ -100,7 +100,7 @@ public Map getConfigOverrides() { @Inject PolarisConfigurationStore configurationStore; @Inject PolarisDiagnostics diagServices; - private BasePolarisCatalog catalog; + private PolarisIcebergCatalog catalog; private String realmName; private PolarisMetaStoreManager metaStoreManager; @@ -188,7 +188,7 @@ public void before(TestInfo testInfo) { new DefaultFileIOFactory( new RealmEntityManagerFactory(managerFactory), managerFactory, configurationStore); this.catalog = - new BasePolarisCatalog( + new PolarisIcebergCatalog( entityManager, metaStoreManager, callContext, @@ -209,7 +209,7 @@ public void after() throws IOException { } @Override - protected BasePolarisCatalog catalog() { + protected PolarisIcebergCatalog catalog() { return catalog; } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java index 489ccd488a..66a582339e 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java @@ -470,7 +470,7 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { } authorizeCreateNamespaceUnderNamespaceOperationOrThrow(op, namespace); - if (namespaceCatalog instanceof BasePolarisCatalog) { + if (namespaceCatalog instanceof PolarisIcebergCatalog) { // Note: The CatalogHandlers' default implementation will non-atomically create the // namespace and then fetch its properties using loadNamespaceMetadata for the response. // However, the latest namespace metadata technically isn't the same authorized instance, @@ -673,9 +673,9 @@ private TableMetadata stageTableCreateHelper(Namespace namespace, CreateTableReq if (request.location() != null) { // Even if the request provides a location, run it through the catalog's TableBuilder // to inherit any override behaviors if applicable. - if (baseCatalog instanceof BasePolarisCatalog) { + if (baseCatalog instanceof PolarisIcebergCatalog) { location = - ((BasePolarisCatalog) baseCatalog).transformTableLikeLocation(request.location()); + ((PolarisIcebergCatalog) baseCatalog).transformTableLikeLocation(request.location()); } else { location = request.location(); } @@ -896,11 +896,11 @@ private UpdateTableRequest applyUpdateFilters(UpdateTableRequest request) { request.updates().stream() .map( update -> { - if (baseCatalog instanceof BasePolarisCatalog + if (baseCatalog instanceof PolarisIcebergCatalog && update instanceof MetadataUpdate.SetLocation) { String requestedLocation = ((MetadataUpdate.SetLocation) update).location(); String filteredLocation = - ((BasePolarisCatalog) baseCatalog) + ((PolarisIcebergCatalog) baseCatalog) .transformTableLikeLocation(requestedLocation); return new MetadataUpdate.SetLocation(filteredLocation); } else { @@ -1019,7 +1019,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) throw new BadRequestException("Cannot update table on external catalogs."); } - if (!(baseCatalog instanceof BasePolarisCatalog)) { + if (!(baseCatalog instanceof PolarisIcebergCatalog)) { throw new BadRequestException( "Unsupported operation: commitTransaction with baseCatalog type: %s", baseCatalog.getClass().getName()); @@ -1030,7 +1030,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) // validations. TransactionWorkspaceMetaStoreManager transactionMetaStoreManager = new TransactionWorkspaceMetaStoreManager(metaStoreManager); - ((BasePolarisCatalog) baseCatalog).setMetaStoreManager(transactionMetaStoreManager); + ((PolarisIcebergCatalog) baseCatalog).setMetaStoreManager(transactionMetaStoreManager); commitTransactionRequest.tableChanges().stream() .forEach( diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java similarity index 99% rename from service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java index ca9771ef29..9eb8f1da3b 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/BasePolarisCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java @@ -116,9 +116,9 @@ import org.slf4j.LoggerFactory; /** Defines the relationship between PolarisEntities and Iceberg's business logic. */ -public class BasePolarisCatalog extends BaseMetastoreViewCatalog +public class PolarisIcebergCatalog extends BaseMetastoreViewCatalog implements SupportsNamespaces, SupportsNotifications, Closeable, SupportsCredentialDelegation { - private static final Logger LOGGER = LoggerFactory.getLogger(BasePolarisCatalog.class); + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisIcebergCatalog.class); private static final Joiner SLASH = Joiner.on("/"); @@ -176,7 +176,7 @@ public class BasePolarisCatalog extends BaseMetastoreViewCatalog * this catalog instance only interacts with authorized resolved paths. * @param taskExecutor Executor we use to register cleanup task handlers */ - public BasePolarisCatalog( + public PolarisIcebergCatalog( PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, CallContext callContext, @@ -564,7 +564,7 @@ private String resolveNamespaceLocation(Namespace namespace, Map .reversed() .stream() .map(entity -> baseLocation(callContext, entity)) - .map(BasePolarisCatalog::stripLeadingTrailingSlash) + .map(PolarisIcebergCatalog::stripLeadingTrailingSlash) .collect(Collectors.joining("/")); } @@ -1210,7 +1210,7 @@ public BasePolarisCatalogViewBuilder(TableIdentifier identifier) { super(identifier); withProperties( PropertyUtil.propertiesWithPrefix( - BasePolarisCatalog.this.properties(), "table-default.")); + PolarisIcebergCatalog.this.properties(), "table-default.")); } @Override diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index e0bed634ff..a4ea75595c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -31,7 +31,7 @@ import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.storage.PolarisCredentialVendor; import org.apache.polaris.core.storage.PolarisStorageActions; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +69,7 @@ public static Optional findStorageInfoFromHierarchy( *

Use cases: * *

    - *
  • In {@link BasePolarisCatalog}, subscoped credentials are generated or refreshed when the + *
  • In {@link PolarisIcebergCatalog}, subscoped credentials are generated or refreshed when the * client sends a loadTable request to vend credentials. *
  • In {@link DefaultFileIOFactory}, subscoped credentials are obtained to access the storage * and read/write metadata JSON files. diff --git a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java index c341ea6fa4..08cfc79bfa 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java @@ -34,7 +34,7 @@ import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; import org.apache.polaris.service.task.TaskExecutor; @@ -83,8 +83,8 @@ public Catalog createCallContextCatalog( PolarisEntityManager entityManager = entityManagerFactory.getOrCreateEntityManager(context.getRealmContext()); - BasePolarisCatalog catalogInstance = - new BasePolarisCatalog( + PolarisIcebergCatalog catalogInstance = + new PolarisIcebergCatalog( entityManager, metaStoreManagerFactory.getOrCreateMetaStoreManager(context.getRealmContext()), context, diff --git a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java index 6c808e77e9..67d700e64c 100644 --- a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java @@ -47,7 +47,7 @@ import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.*; import org.apache.polaris.service.TestServices; -import org.apache.polaris.service.catalog.BasePolarisCatalog; +import org.apache.polaris.service.catalog.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.task.TaskFileIOSupplier; import org.assertj.core.api.Assertions; @@ -157,7 +157,7 @@ public void after() {} @Test public void testLoadFileIOForTableLike() { - BasePolarisCatalog catalog = createCatalog(testServices); + PolarisIcebergCatalog catalog = createCatalog(testServices); catalog.createNamespace(NS); catalog.createTable(TABLE, SCHEMA); @@ -175,7 +175,7 @@ public void testLoadFileIOForTableLike() { @Test public void testLoadFileIOForCleanupTask() { - BasePolarisCatalog catalog = createCatalog(testServices); + PolarisIcebergCatalog catalog = createCatalog(testServices); catalog.createNamespace(NS); catalog.createTable(TABLE, SCHEMA); catalog.dropTable(TABLE, true); @@ -206,7 +206,7 @@ public void testLoadFileIOForCleanupTask() { Mockito.any()); } - BasePolarisCatalog createCatalog(TestServices services) { + PolarisIcebergCatalog createCatalog(TestServices services) { String storageLocation = "s3://my-bucket/path/to/data"; AwsStorageConfigInfo awsStorageConfigInfo = AwsStorageConfigInfo.builder() @@ -234,8 +234,8 @@ BasePolarisCatalog createCatalog(TestServices services) { services.entityManagerFactory().getOrCreateEntityManager(realmContext), services.securityContext(), CATALOG_NAME); - BasePolarisCatalog polarisCatalog = - new BasePolarisCatalog( + PolarisIcebergCatalog polarisCatalog = + new PolarisIcebergCatalog( services.entityManagerFactory().getOrCreateEntityManager(realmContext), services.metaStoreManagerFactory().getOrCreateMetaStoreManager(realmContext), callContext, From ba481bf8bcb9627185bebc20a992f87926de58b3 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 7 Mar 2025 10:58:44 -0800 Subject: [PATCH 02/18] move catalog files --- .../quarkus/admin/PolarisAuthzTestBase.java | 2 +- ...cebergCatalogHandlerWrapperAuthzTest.java} | 22 +++++++++---------- .../catalog/PolarisIcebergCatalogTest.java | 2 +- .../PolarisIcebergCatalogViewTest.java | 2 +- .../DefaultIcebergCatalogPrefixParser.java | 2 +- .../{ => iceberg}/IcebergCatalogAdapter.java | 13 ++++++----- .../IcebergCatalogHandlerWrapper.java} | 9 ++++---- .../IcebergCatalogPrefixParser.java | 2 +- .../{ => iceberg}/PolarisIcebergCatalog.java | 3 ++- .../SupportsCredentialDelegation.java | 2 +- .../service/catalog/io/FileIOUtil.java | 2 +- .../PolarisCallContextCatalogFactory.java | 2 +- .../service/catalog/io/FileIOFactoryTest.java | 2 +- .../apache/polaris/service/TestServices.java | 4 ++-- 14 files changed, 36 insertions(+), 33 deletions(-) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisCatalogHandlerWrapperAuthzTest.java => IcebergCatalogHandlerWrapperAuthzTest.java} (99%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{ => iceberg}/DefaultIcebergCatalogPrefixParser.java (96%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{ => iceberg}/IcebergCatalogAdapter.java (98%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{PolarisCatalogHandlerWrapper.java => iceberg/IcebergCatalogHandlerWrapper.java} (99%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{ => iceberg}/IcebergCatalogPrefixParser.java (97%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{ => iceberg}/PolarisIcebergCatalog.java (99%) rename service/common/src/main/java/org/apache/polaris/service/catalog/{ => iceberg}/SupportsCredentialDelegation.java (96%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index f0af61dd3b..deecacf487 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -75,7 +75,7 @@ import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.DefaultConfigurationStore; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerWrapperAuthzTest.java similarity index 99% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerWrapperAuthzTest.java index 29d0bd90c1..47cc445f5f 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogHandlerWrapperAuthzTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerWrapperAuthzTest.java @@ -64,7 +64,7 @@ import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.dao.entity.CreatePrincipalResult; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; -import org.apache.polaris.service.catalog.PolarisCatalogHandlerWrapper; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalogHandlerWrapper; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; import org.apache.polaris.service.context.CallContextCatalogFactory; @@ -78,8 +78,8 @@ import org.mockito.Mockito; @QuarkusTest -@TestProfile(PolarisCatalogHandlerWrapperAuthzTest.Profile.class) -public class PolarisCatalogHandlerWrapperAuthzTest extends PolarisAuthzTestBase { +@TestProfile(IcebergCatalogHandlerWrapperAuthzTest.Profile.class) +public class IcebergCatalogHandlerWrapperAuthzTest extends PolarisAuthzTestBase { public static class Profile extends PolarisAuthzTestBase.Profile { @@ -93,19 +93,19 @@ public Map getConfigOverrides() { } } - private PolarisCatalogHandlerWrapper newWrapper() { + private IcebergCatalogHandlerWrapper newWrapper() { return newWrapper(Set.of()); } - private PolarisCatalogHandlerWrapper newWrapper(Set activatedPrincipalRoles) { + private IcebergCatalogHandlerWrapper newWrapper(Set activatedPrincipalRoles) { return newWrapper(activatedPrincipalRoles, CATALOG_NAME, callContextCatalogFactory); } - private PolarisCatalogHandlerWrapper newWrapper( + private IcebergCatalogHandlerWrapper newWrapper( Set activatedPrincipalRoles, String catalogName, CallContextCatalogFactory factory) { final AuthenticatedPolarisPrincipal authenticatedPrincipal = new AuthenticatedPolarisPrincipal(principalEntity, activatedPrincipalRoles); - return new PolarisCatalogHandlerWrapper( + return new IcebergCatalogHandlerWrapper( callContext, entityManager, metaStoreManager, @@ -242,8 +242,8 @@ public void testInsufficientPermissionsPriorToSecretRotation() { new AuthenticatedPolarisPrincipal( PrincipalEntity.of(newPrincipal.getPrincipal()), Set.of(PRINCIPAL_ROLE1, PRINCIPAL_ROLE2)); - PolarisCatalogHandlerWrapper wrapper = - new PolarisCatalogHandlerWrapper( + IcebergCatalogHandlerWrapper wrapper = + new IcebergCatalogHandlerWrapper( callContext, entityManager, metaStoreManager, @@ -274,8 +274,8 @@ public void testInsufficientPermissionsPriorToSecretRotation() { final AuthenticatedPolarisPrincipal authenticatedPrincipal1 = new AuthenticatedPolarisPrincipal( PrincipalEntity.of(refreshPrincipal), Set.of(PRINCIPAL_ROLE1, PRINCIPAL_ROLE2)); - PolarisCatalogHandlerWrapper refreshedWrapper = - new PolarisCatalogHandlerWrapper( + IcebergCatalogHandlerWrapper refreshedWrapper = + new IcebergCatalogHandlerWrapper( callContext, entityManager, metaStoreManager, diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java index a3ef9ab3d0..6152a1f76a 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java @@ -107,7 +107,7 @@ import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java index ebd2a7f463..438c1537a9 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java @@ -59,7 +59,7 @@ import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/DefaultIcebergCatalogPrefixParser.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java similarity index 96% rename from service/common/src/main/java/org/apache/polaris/service/catalog/DefaultIcebergCatalogPrefixParser.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java index 42b15bca64..47efeb66f6 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/DefaultIcebergCatalogPrefixParser.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import jakarta.enterprise.context.ApplicationScoped; import org.apache.polaris.core.context.RealmContext; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java similarity index 98% rename from service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java index 968d9c5fda..16210eb356 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogAdapter.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import static org.apache.polaris.service.catalog.AccessDelegationMode.VENDED_CREDENTIALS; @@ -68,6 +68,7 @@ import org.apache.polaris.core.persistence.resolver.Resolver; import org.apache.polaris.core.persistence.resolver.ResolverStatus; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; +import org.apache.polaris.service.catalog.AccessDelegationMode; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; import org.apache.polaris.service.catalog.api.IcebergRestConfigurationApiService; import org.apache.polaris.service.context.CallContextCatalogFactory; @@ -165,9 +166,9 @@ public IcebergCatalogAdapter( private Response withCatalog( SecurityContext securityContext, String prefix, - Function action) { + Function action) { String catalogName = prefixParser.prefixToCatalogName(realmContext, prefix); - try (PolarisCatalogHandlerWrapper wrapper = + try (IcebergCatalogHandlerWrapper wrapper = newHandlerWrapper(realmContext, securityContext, catalogName)) { return action.apply(wrapper); } catch (RuntimeException e) { @@ -179,7 +180,7 @@ private Response withCatalog( } } - private PolarisCatalogHandlerWrapper newHandlerWrapper( + private IcebergCatalogHandlerWrapper newHandlerWrapper( RealmContext realmContext, SecurityContext securityContext, String catalogName) { AuthenticatedPolarisPrincipal authenticatedPrincipal = (AuthenticatedPolarisPrincipal) securityContext.getUserPrincipal(); @@ -187,7 +188,7 @@ private PolarisCatalogHandlerWrapper newHandlerWrapper( throw new NotAuthorizedException("Failed to find authenticatedPrincipal in SecurityContext"); } - return new PolarisCatalogHandlerWrapper( + return new IcebergCatalogHandlerWrapper( callContext, entityManager, metaStoreManager, @@ -421,7 +422,7 @@ public Response updateTable( Namespace ns = decodeNamespace(namespace); TableIdentifier tableIdentifier = TableIdentifier.of(ns, RESTUtil.decodeString(table)); - if (PolarisCatalogHandlerWrapper.isCreate(commitTableRequest)) { + if (IcebergCatalogHandlerWrapper.isCreate(commitTableRequest)) { return Response.ok( newHandlerWrapper(realmContext, securityContext, prefix) .updateTableForStagedCreate(tableIdentifier, commitTableRequest)) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java similarity index 99% rename from service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index 66a582339e..b52dad2dcd 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; @@ -92,6 +92,7 @@ import org.apache.polaris.core.persistence.resolver.ResolverPath; import org.apache.polaris.core.persistence.resolver.ResolverStatus; import org.apache.polaris.core.storage.PolarisStorageActions; +import org.apache.polaris.service.catalog.SupportsNotifications; import org.apache.polaris.service.context.CallContextCatalogFactory; import org.apache.polaris.service.types.NotificationRequest; import org.slf4j.Logger; @@ -112,8 +113,8 @@ * model objects used in this layer to still benefit from the shared implementation of * authorization-aware catalog protocols. */ -public class PolarisCatalogHandlerWrapper implements AutoCloseable { - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCatalogHandlerWrapper.class); +public class IcebergCatalogHandlerWrapper implements AutoCloseable { + private static final Logger LOGGER = LoggerFactory.getLogger(IcebergCatalogHandlerWrapper.class); private final CallContext callContext; private final PolarisEntityManager entityManager; @@ -133,7 +134,7 @@ public class PolarisCatalogHandlerWrapper implements AutoCloseable { private SupportsNamespaces namespaceCatalog = null; private ViewCatalog viewCatalog = null; - public PolarisCatalogHandlerWrapper( + public IcebergCatalogHandlerWrapper( CallContext callContext, PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogPrefixParser.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java similarity index 97% rename from service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogPrefixParser.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java index 43055fc5ce..7b1409f43f 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/IcebergCatalogPrefixParser.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import org.apache.polaris.core.context.RealmContext; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java similarity index 99% rename from service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java index 9eb8f1da3b..c1127950e2 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/PolarisIcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import static org.apache.polaris.service.exception.IcebergExceptionMapper.isStorageProviderRetryableException; @@ -107,6 +107,7 @@ import org.apache.polaris.core.storage.PolarisStorageConfigurationInfo; import org.apache.polaris.core.storage.PolarisStorageIntegration; import org.apache.polaris.core.storage.StorageLocation; +import org.apache.polaris.service.catalog.SupportsNotifications; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.FileIOUtil; import org.apache.polaris.service.task.TaskExecutor; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/SupportsCredentialDelegation.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java similarity index 96% rename from service/common/src/main/java/org/apache/polaris/service/catalog/SupportsCredentialDelegation.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java index 554358765e..06ca7fbde6 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/SupportsCredentialDelegation.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog; +package org.apache.polaris.service.catalog.iceberg; import java.util.Map; import java.util.Set; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index a4ea75595c..8527a30c61 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -31,7 +31,7 @@ import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.storage.PolarisCredentialVendor; import org.apache.polaris.core.storage.PolarisStorageActions; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java index 08cfc79bfa..1bd2259e9d 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java @@ -34,7 +34,7 @@ import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; import org.apache.polaris.service.task.TaskExecutor; diff --git a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java index 67d700e64c..85625c6506 100644 --- a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java @@ -47,7 +47,7 @@ import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.*; import org.apache.polaris.service.TestServices; -import org.apache.polaris.service.catalog.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; import org.apache.polaris.service.task.TaskFileIOSupplier; import org.assertj.core.api.Assertions; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index 7dd4f68045..8036cb1a51 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -44,8 +44,8 @@ import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisServiceImpl; import org.apache.polaris.service.admin.api.PolarisCatalogsApi; -import org.apache.polaris.service.catalog.DefaultIcebergCatalogPrefixParser; -import org.apache.polaris.service.catalog.IcebergCatalogAdapter; +import org.apache.polaris.service.catalog.iceberg.DefaultIcebergCatalogPrefixParser; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; import org.apache.polaris.service.catalog.io.FileIOFactory; From fc49085f1bcdf2433f4d99eb26bdafb8c2e465bd Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 7 Mar 2025 11:13:41 -0800 Subject: [PATCH 03/18] more renames; introduce class --- ...ntity.java => IcebergTableLikeEntity.java} | 0 .../generic/PolarisGenericTableCatalog.java | 44 +++++++++++++++++++ 2 files changed, 44 insertions(+) rename polaris-core/src/main/java/org/apache/polaris/core/entity/{TableLikeEntity.java => IcebergTableLikeEntity.java} (100%) create mode 100644 service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java similarity index 100% rename from polaris-core/src/main/java/org/apache/polaris/core/entity/TableLikeEntity.java rename to polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java new file mode 100644 index 0000000000..f9d4bd19dd --- /dev/null +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.service.catalog.generic; + +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; + +public class PolarisGenericTableCatalog { + /** + * Caller must fill in all entity fields except parentId, since the caller may not want to + * duplicate the logic to try to resolve parentIds before constructing the proposed entity. This + * method will fill in the parentId if needed upon resolution. + */ + private void createTableLike(TableIdentifier identifier, PolarisEntity entity) { + PolarisResolvedPathWrapper resolvedParent = + resolvedEntityView.getResolvedPath(identifier.namespace()); + if (resolvedParent == null) { + // Illegal state because the namespace should've already been in the static resolution set. + throw new IllegalStateException( + String.format("Failed to fetch resolved parent for TableIdentifier '%s'", identifier)); + } + + createTableLike(identifier, entity, resolvedParent); + } + +} From f47bfafbcf0900919e9e8800f43cd5f1d8bf3a8f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 7 Mar 2025 15:07:01 -0800 Subject: [PATCH 04/18] add basic create/load methods --- .../core/entity/GenericTableEntity.java | 95 ++++++++++++ .../core/entity/IcebergTableLikeEntity.java | 18 +-- .../core/entity/PolarisBaseEntity.java | 2 +- .../core/entity/PolarisEntitySubType.java | 4 +- .../core/entity/PolarisEntityType.java | 5 +- .../polaris/core/entity/PolarisPrivilege.java | 30 ++-- .../core/persistence/resolver/Resolver.java | 3 +- .../PolarisStorageConfigurationInfo.java | 6 +- .../storage/cache/StorageCredentialCache.java | 2 +- .../core/persistence/EntityCacheTest.java | 7 +- .../core/persistence/ResolverTest.java | 17 +- .../PolarisTestMetaStoreManager.java | 98 +++++++----- .../quarkus/admin/PolarisAuthzTestBase.java | 2 +- .../catalog/PolarisIcebergCatalogTest.java | 2 +- .../PolarisIcebergCatalogViewTest.java | 2 +- .../task/TableCleanupTaskHandlerTest.java | 16 +- .../service/admin/PolarisAdminService.java | 16 +- .../generic/PolarisGenericTableCatalog.java | 146 ++++++++++++++++-- .../iceberg/IcebergCatalogHandlerWrapper.java | 16 +- .../iceberg/PolarisIcebergCatalog.java | 116 ++++++++------ .../service/catalog/io/FileIOUtil.java | 4 +- .../service/task/TableCleanupTaskHandler.java | 10 +- .../service/task/TaskFileIOSupplier.java | 4 +- .../service/catalog/io/FileIOFactoryTest.java | 2 +- .../apache/polaris/service/TestServices.java | 4 +- .../PolarisPassthroughResolutionView.java | 4 +- 26 files changed, 443 insertions(+), 188 deletions(-) create mode 100644 polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java new file mode 100644 index 0000000000..a9756d55b1 --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.core.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import org.apache.iceberg.catalog.Namespace; +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.rest.RESTUtil; + +/** + * A {@link PolarisEntity} implementation for generic tables. These tables are not Iceberg-like in + * that they may not have a schema or base location. Similarly to {@link IcebergTableLikeEntity} + * however, these tables have an identifier and a parent namespace. + */ +public class GenericTableEntity extends PolarisEntity { + + public static final String FORMAT_KEY = "format"; + + public GenericTableEntity(PolarisBaseEntity sourceEntity) { + super(sourceEntity); + } + + public static GenericTableEntity of(PolarisBaseEntity sourceEntity) { + if (sourceEntity != null) { + return new GenericTableEntity(sourceEntity); + } + return null; + } + + @JsonIgnore + public String getFormat() { + return getPropertiesAsMap().get(GenericTableEntity.FORMAT_KEY); + } + + @JsonIgnore + public Namespace getParentNamespace() { + String encodedNamespace = + getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); + if (encodedNamespace == null) { + return Namespace.empty(); + } + return RESTUtil.decodeNamespace(encodedNamespace); + } + + public static class Builder + extends PolarisEntity.BaseBuilder { + public Builder(String format) { + super(); + setType(PolarisEntityType.GENERIC_TABLE); + setFormat(format); + } + + public GenericTableEntity.Builder setFormat(String format) { + // TODO in the future, we may validate the format and require certain properties + properties.put(GenericTableEntity.FORMAT_KEY, format); + return this; + } + + public GenericTableEntity.Builder setTableIdentifier(TableIdentifier identifier) { + Namespace namespace = identifier.namespace(); + setParentNamespace(namespace); + setName(identifier.name()); + return this; + } + + public GenericTableEntity.Builder setParentNamespace(Namespace namespace) { + if (namespace != null && !namespace.isEmpty()) { + internalProperties.put( + NamespaceEntity.PARENT_NAMESPACE_KEY, RESTUtil.encodeNamespace(namespace)); + } + return this; + } + + @Override + public GenericTableEntity build() { + return new GenericTableEntity(buildBase()); + } + } +} diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java index 968598b93e..e7e1810754 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/IcebergTableLikeEntity.java @@ -24,7 +24,7 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.rest.RESTUtil; -public class TableLikeEntity extends PolarisEntity { +public class IcebergTableLikeEntity extends PolarisEntity { // For applicable types, this key on the "internalProperties" map will return the location // of the internalProperties JSON file. public static final String METADATA_LOCATION_KEY = "metadata-location"; @@ -35,13 +35,13 @@ public class TableLikeEntity extends PolarisEntity { public static final String LAST_ADMITTED_NOTIFICATION_TIMESTAMP_KEY = "last-notification-timestamp"; - public TableLikeEntity(PolarisBaseEntity sourceEntity) { + public IcebergTableLikeEntity(PolarisBaseEntity sourceEntity) { super(sourceEntity); } - public static TableLikeEntity of(PolarisBaseEntity sourceEntity) { + public static IcebergTableLikeEntity of(PolarisBaseEntity sourceEntity) { if (sourceEntity != null) { - return new TableLikeEntity(sourceEntity); + return new IcebergTableLikeEntity(sourceEntity); } return null; } @@ -79,21 +79,21 @@ public String getBaseLocation() { return getPropertiesAsMap().get(PolarisEntityConstants.ENTITY_BASE_LOCATION); } - public static class Builder extends PolarisEntity.BaseBuilder { + public static class Builder extends PolarisEntity.BaseBuilder { public Builder(TableIdentifier identifier, String metadataLocation) { super(); - setType(PolarisEntityType.TABLE_LIKE); + setType(PolarisEntityType.ICEBERG_TABLE_LIKE); setTableIdentifier(identifier); setMetadataLocation(metadataLocation); } - public Builder(TableLikeEntity original) { + public Builder(IcebergTableLikeEntity original) { super(original); } @Override - public TableLikeEntity build() { - return new TableLikeEntity(buildBase()); + public IcebergTableLikeEntity build() { + return new IcebergTableLikeEntity(buildBase()); } public Builder setTableIdentifier(TableIdentifier identifier) { diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java index 148733f52d..b9b4e1c006 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisBaseEntity.java @@ -28,7 +28,7 @@ /** * Base polaris entity representing all attributes of a Polaris Entity. This is used to exchange - * full entity information between the client and the GS backend + * full entity information between the client and the backend */ public class PolarisBaseEntity extends PolarisEntityCore { diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java index c206d07894..e45f4d910f 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntitySubType.java @@ -30,8 +30,8 @@ public enum PolarisEntitySubType { ANY_SUBTYPE(-1, null), // the NULL value is used when an entity has no subtype, i.e. NOT_APPLICABLE really NULL_SUBTYPE(0, null), - TABLE(2, PolarisEntityType.TABLE_LIKE), - VIEW(3, PolarisEntityType.TABLE_LIKE); + TABLE(2, PolarisEntityType.ICEBERG_TABLE_LIKE), + VIEW(3, PolarisEntityType.ICEBERG_TABLE_LIKE); // to efficiently map the code of a subtype to its corresponding subtype enum, use a reverse // array which is initialized below diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java index af50eed6ff..f7af4ee7c9 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java @@ -32,9 +32,10 @@ public enum PolarisEntityType { CATALOG_ROLE(5, CATALOG, true, false), NAMESPACE(6, CATALOG, false, true), // generic table is either a view or a real table - TABLE_LIKE(7, NAMESPACE, false, false), + ICEBERG_TABLE_LIKE(7, NAMESPACE, false, false), TASK(8, ROOT, false, false), - FILE(9, TABLE_LIKE, false, false); + FILE(9, ICEBERG_TABLE_LIKE, false, false), + GENERIC_TABLE(9, NAMESPACE, false, false); // to efficiently map a code to its corresponding entity type, use a reverse array which // is initialized below diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java index b674af2678..122d39a4ce 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisPrivilege.java @@ -41,22 +41,22 @@ public enum PolarisPrivilege { TABLE_CREATE(6, PolarisEntityType.NAMESPACE), VIEW_CREATE(7, PolarisEntityType.NAMESPACE), NAMESPACE_DROP(8, PolarisEntityType.NAMESPACE), - TABLE_DROP(9, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_DROP(10, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_DROP(9, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_DROP(10, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), NAMESPACE_LIST(11, PolarisEntityType.NAMESPACE), TABLE_LIST(12, PolarisEntityType.NAMESPACE), VIEW_LIST(13, PolarisEntityType.NAMESPACE), NAMESPACE_READ_PROPERTIES(14, PolarisEntityType.NAMESPACE), - TABLE_READ_PROPERTIES(15, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_READ_PROPERTIES(16, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_READ_PROPERTIES(15, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_READ_PROPERTIES(16, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), NAMESPACE_WRITE_PROPERTIES(17, PolarisEntityType.NAMESPACE), - TABLE_WRITE_PROPERTIES(18, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_WRITE_PROPERTIES(19, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), - TABLE_READ_DATA(20, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - TABLE_WRITE_DATA(21, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), + TABLE_WRITE_PROPERTIES(18, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_WRITE_PROPERTIES(19, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_READ_DATA(20, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + TABLE_WRITE_DATA(21, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), NAMESPACE_FULL_METADATA(22, PolarisEntityType.NAMESPACE), - TABLE_FULL_METADATA(23, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_FULL_METADATA(24, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_FULL_METADATA(23, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_FULL_METADATA(24, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), CATALOG_CREATE(25, PolarisEntityType.ROOT), CATALOG_DROP(26, PolarisEntityType.CATALOG), CATALOG_LIST(27, PolarisEntityType.ROOT), @@ -70,12 +70,14 @@ public enum PolarisPrivilege { CATALOG_ROLE_LIST_GRANTS(35, PolarisEntityType.PRINCIPAL), CATALOG_LIST_GRANTS(36, PolarisEntityType.CATALOG), NAMESPACE_LIST_GRANTS(37, PolarisEntityType.NAMESPACE), - TABLE_LIST_GRANTS(38, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_LIST_GRANTS(39, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_LIST_GRANTS(38, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_LIST_GRANTS(39, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), CATALOG_MANAGE_GRANTS_ON_SECURABLE(40, PolarisEntityType.CATALOG), NAMESPACE_MANAGE_GRANTS_ON_SECURABLE(41, PolarisEntityType.NAMESPACE), - TABLE_MANAGE_GRANTS_ON_SECURABLE(42, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE), - VIEW_MANAGE_GRANTS_ON_SECURABLE(43, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW), + TABLE_MANAGE_GRANTS_ON_SECURABLE( + 42, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE), + VIEW_MANAGE_GRANTS_ON_SECURABLE( + 43, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW), PRINCIPAL_CREATE(44, PolarisEntityType.ROOT), PRINCIPAL_DROP(45, PolarisEntityType.PRINCIPAL), PRINCIPAL_LIST(46, PolarisEntityType.ROOT), diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java index bb5837297c..72715d1347 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java @@ -373,7 +373,8 @@ public ResolverStatus resolveAll() { // validate input diagnostics.check( - entityType != PolarisEntityType.NAMESPACE && entityType != PolarisEntityType.TABLE_LIKE, + entityType != PolarisEntityType.NAMESPACE + && entityType != PolarisEntityType.ICEBERG_TABLE_LIKE, "cannot_be_path"); diagnostics.check( entityType.isTopLevel() || this.referenceCatalogName != null, "reference_catalog_expected"); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java index 6b0638e837..72c89fb1cf 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/PolarisStorageConfigurationInfo.java @@ -41,9 +41,9 @@ import org.apache.polaris.core.admin.model.Catalog; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.apache.polaris.core.storage.azure.AzureStorageConfigurationInfo; import org.apache.polaris.core.storage.gcp.GcpStorageConfigurationInfo; @@ -198,8 +198,8 @@ private static List userSpecifiedWriteLocations(Map prop .map( p -> Stream.of( - p.get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY), - p.get(TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)) + p.get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY), + p.get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)) .filter(Objects::nonNull) .collect(Collectors.toList())) .orElse(List.of()); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java index e92053852b..19a4b14d7e 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/storage/cache/StorageCredentialCache.java @@ -175,7 +175,7 @@ public Map getIfPresent(StorageCredentialCacheKey key) { private boolean isTypeSupported(PolarisEntityType type) { return type == PolarisEntityType.CATALOG || type == PolarisEntityType.NAMESPACE - || type == PolarisEntityType.TABLE_LIKE + || type == PolarisEntityType.ICEBERG_TABLE_LIKE || type == PolarisEntityType.TASK; } diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java index 0a3986357c..a086408da7 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/EntityCacheTest.java @@ -298,7 +298,7 @@ void testRefresh() { PolarisBaseEntity T6v1 = this.tm.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T6"); Assertions.assertThat(T6v1).isNotNull(); @@ -435,7 +435,8 @@ void testRenameAndCacheDestinationBeforeLoadingSource() { Assertions.assertThat(lookup).isNotNull(); EntityCacheByNameKey T4_name = - new EntityCacheByNameKey(N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4"); + new EntityCacheByNameKey( + N1.getCatalogId(), N1.getId(), PolarisEntityType.ICEBERG_TABLE_LIKE, "T4"); lookup = cache.getOrLoadEntityByName(callCtx, T4_name); Assertions.assertThat(lookup).isNotNull(); ResolvedPolarisEntity cacheEntry_T4 = lookup.getCacheEntry(); @@ -450,7 +451,7 @@ void testRenameAndCacheDestinationBeforeLoadingSource() { // load the renamed entity into cache EntityCacheByNameKey T4_renamed = new EntityCacheByNameKey( - N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "T4_renamed"); + N1.getCatalogId(), N1.getId(), PolarisEntityType.ICEBERG_TABLE_LIKE, "T4_renamed"); lookup = cache.getOrLoadEntityByName(callCtx, T4_renamed); Assertions.assertThat(lookup).isNotNull(); ResolvedPolarisEntity cacheEntry_T4_renamed = lookup.getCacheEntry(); diff --git a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java index fbcb2f9c94..ba7c25fce7 100644 --- a/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java +++ b/polaris-core/src/test/java/org/apache/polaris/core/persistence/ResolverTest.java @@ -213,12 +213,12 @@ void testResolvePath(boolean useCache) { // N1/N2/T1 which exists ResolverPath N1_N2_T1 = - new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N2_T1, null, null); // N1/N2/T1 which exists ResolverPath N1_N2_V1 = - new ResolverPath(List.of("N1", "N2", "V1"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "V1"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N2_V1, null, null); // N5/N6 which exists @@ -227,12 +227,12 @@ void testResolvePath(boolean useCache) { // N5/N6/T5 which exists ResolverPath N5_N6_T5 = - new ResolverPath(List.of("N5", "N6", "T5"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N5", "N6", "T5"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver(this.cache, "test", N5_N6_T5, null, null); // Error scenarios: N5/N6/T8 which does not exists ResolverPath N5_N6_T8 = - new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver( this.cache, "test", @@ -242,7 +242,7 @@ void testResolvePath(boolean useCache) { // Error scenarios: N8/N6/T8 which does not exists ResolverPath N8_N6_T8 = - new ResolverPath(List.of("N8", "N6", "T8"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N8", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver( this.cache, "test", @@ -261,7 +261,8 @@ void testResolvePath(boolean useCache) { ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED); // except if the optional flag is specified - N5_N6_T8 = new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.TABLE_LIKE, true); + N5_N6_T8 = + new ResolverPath(List.of("N5", "N6", "T8"), PolarisEntityType.ICEBERG_TABLE_LIKE, true); Resolver resolver = this.resolveDriver(this.cache, "test", null, List.of(N1, N5_N6_T8, N5_N6_T5, N1_N2), null); // get all the resolved paths @@ -349,7 +350,7 @@ void testPathConsistency(boolean useCache) { ResolverPath N1_N2_PATH = new ResolverPath(List.of("N1", "N2"), PolarisEntityType.NAMESPACE); this.resolveDriver(this.cache, "test", N1_N2_PATH, null, null); ResolverPath N1_N2_T1_PATH = - new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N1", "N2", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); Resolver resolver = this.resolveDriver(this.cache, "test", N1_N2_T1_PATH, null, null); // get the catalog @@ -383,7 +384,7 @@ void testPathConsistency(boolean useCache) { // but we should be able to resolve it under N1/N3 ResolverPath N1_N3_T1_PATH = - new ResolverPath(List.of("N1", "N3", "T1"), PolarisEntityType.TABLE_LIKE); + new ResolverPath(List.of("N1", "N3", "T1"), PolarisEntityType.ICEBERG_TABLE_LIKE); this.resolveDriver(this.cache, "test", N1_N3_T1_PATH, null, null); } diff --git a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java index 81271305c1..a0bc55fe74 100644 --- a/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java +++ b/polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java @@ -702,7 +702,7 @@ void dropEntity(List catalogPath, PolarisEntityCore entityToD .listEntities( this.polarisCallContext, path, - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE) .getEntities(); Assertions.assertThat(children).isNotNull(); @@ -964,27 +964,36 @@ PolarisBaseEntity createTestCatalog(String catalogName) { this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N2"); this.createEntity( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T1"); this.createEntity( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T2"); this.createEntity( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); + List.of(catalog, N1, N1_N2), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.VIEW, + "V1"); PolarisBaseEntity N1_N3 = this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.createEntity( List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T3"); this.createEntity( - List.of(catalog, N1, N1_N3), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); + List.of(catalog, N1, N1_N3), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.VIEW, + "V2"); this.createEntity( - List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE, "T4"); + List.of(catalog, N1), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.TABLE, + "T4"); this.createEntity(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N4"); PolarisBaseEntity N5 = this.createEntity(List.of(catalog), PolarisEntityType.NAMESPACE, "N5"); PolarisBaseEntity N5_N6 = @@ -992,12 +1001,12 @@ PolarisBaseEntity createTestCatalog(String catalogName) { PolarisBaseEntity N5_N6_T5 = this.createEntity( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T5"); this.createEntity( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T6"); @@ -1611,40 +1620,46 @@ void testCreateTestCatalog() { this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N2"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T2"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T2"); this.ensureExistsByName( - List.of(catalog, N1, N1_N2), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); + List.of(catalog, N1, N1_N2), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.VIEW, + "V1"); this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "V1"); PolarisBaseEntity N1_N3 = this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N3"); this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T3"); this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "V2"); this.ensureExistsByName( - List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE, "T4"); + List.of(catalog, N1), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.TABLE, + "T4"); this.ensureExistsByName(List.of(catalog, N1), PolarisEntityType.NAMESPACE, "N4"); PolarisBaseEntity N5 = this.ensureExistsByName(List.of(catalog), PolarisEntityType.NAMESPACE, "N5"); @@ -1656,18 +1671,18 @@ void testCreateTestCatalog() { "N6"); this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T5"); PolarisBaseEntity N5_N6_T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T5"); this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T6"); PolarisBaseEntity R1 = @@ -1750,7 +1765,7 @@ void testBrowse() { ImmutablePair.of("N4", PolarisEntitySubType.NULL_SUBTYPE))); this.validateListReturn( List.of(catalog, N1), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, List.of(ImmutablePair.of("T4", PolarisEntitySubType.TABLE))); PolarisBaseEntity N5 = @@ -1766,7 +1781,7 @@ void testBrowse() { // table or view object this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, List.of( ImmutablePair.of("T1", PolarisEntitySubType.TABLE), @@ -1775,7 +1790,7 @@ void testBrowse() { // table object only this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, List.of( ImmutablePair.of("T1", PolarisEntitySubType.TABLE), @@ -1783,7 +1798,7 @@ void testBrowse() { // view object only this.validateListReturn( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW, List.of(ImmutablePair.of("V1", PolarisEntitySubType.VIEW))); // list all principals @@ -1820,7 +1835,7 @@ void testUpdateEntities() { PolarisBaseEntity T6v1 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T6"); Assertions.assertThat(T6v1).isNotNull(); @@ -1857,7 +1872,7 @@ void testUpdateEntities() { PolarisBaseEntity T5v1 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T5"); T5v1.setId(100000L); @@ -1898,7 +1913,7 @@ void testDropEntities() { PolarisBaseEntity T6 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T6"); Assertions.assertThat(T6).isNotNull(); @@ -1918,21 +1933,21 @@ void testDropEntities() { PolarisBaseEntity T1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T1"); this.dropEntity(List.of(catalog, N1, N1_N2), T1); PolarisBaseEntity T2 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T2"); this.dropEntity(List.of(catalog, N1, N1_N2), T2); PolarisBaseEntity V1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW, "V1"); this.dropEntity(List.of(catalog, N1, N1_N2), V1); @@ -1943,14 +1958,14 @@ void testDropEntities() { PolarisBaseEntity T3 = this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T3"); this.dropEntity(List.of(catalog, N1, N1_N3), T3); PolarisBaseEntity V2 = this.ensureExistsByName( List.of(catalog, N1, N1_N3), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW, "V2"); this.dropEntity(List.of(catalog, N1, N1_N3), V2); @@ -1958,14 +1973,17 @@ void testDropEntities() { PolarisBaseEntity T4 = this.ensureExistsByName( - List.of(catalog, N1), PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.TABLE, "T4"); + List.of(catalog, N1), + PolarisEntityType.ICEBERG_TABLE_LIKE, + PolarisEntitySubType.TABLE, + "T4"); this.dropEntity(List.of(catalog, N1), T4); this.dropEntity(List.of(catalog), N1); PolarisBaseEntity T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE, "T5"); this.dropEntity(List.of(catalog, N5, N5_N6), T5); @@ -2065,7 +2083,7 @@ public void testPrivileges() { PolarisBaseEntity N5_N6_T5 = this.ensureExistsByName( List.of(catalog, N5, N5_N6), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T5"); @@ -2236,7 +2254,7 @@ public void testRename() { PolarisBaseEntity N1_N2_T1 = this.ensureExistsByName( List.of(catalog, N1, N1_N2), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE, "T1"); // view with the same name exists, should fail @@ -2331,11 +2349,15 @@ public void testEntityCache() { // now validate that load something which does not exist, will also work this.loadCacheEntryByName( - N1.getCatalogId(), N1.getId(), PolarisEntityType.TABLE_LIKE, "do_not_exists", false); + N1.getCatalogId(), + N1.getId(), + PolarisEntityType.ICEBERG_TABLE_LIKE, + "do_not_exists", + false); this.loadCacheEntryById(N1.getCatalogId() + 1000, N1.getId(), N1.getType(), false); // refresh a purged entity this.refreshCacheEntry( - 1, 1, PolarisEntityType.TABLE_LIKE, N1.getCatalogId() + 1000, N1.getId(), false); + 1, 1, PolarisEntityType.ICEBERG_TABLE_LIKE, N1.getCatalogId() + 1000, N1.getId(), false); } } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index deecacf487..7f9e20e802 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -75,8 +75,8 @@ import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.DefaultConfigurationStore; import org.apache.polaris.service.config.RealmEntityManagerFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java index 6152a1f76a..5daec0f694 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java @@ -107,8 +107,8 @@ import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java index 438c1537a9..0e12bc00d4 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java @@ -59,8 +59,8 @@ import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java index ad2d0f055c..f9cce1310d 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/task/TableCleanupTaskHandlerTest.java @@ -43,10 +43,10 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.AsyncTaskType; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisTaskConstants; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.entity.TaskEntity; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -126,7 +126,7 @@ public void testTableCleanup() throws IOException { .setName("cleanup_" + tableIdentifier) .withTaskType(AsyncTaskType.ENTITY_CLEANUP_SCHEDULER) .withData( - new TableLikeEntity.Builder(tableIdentifier, metadataFile) + new IcebergTableLikeEntity.Builder(tableIdentifier, metadataFile) .setName("table1") .setCatalogId(1) .setCreateTimestamp(100) @@ -198,8 +198,8 @@ public void close() { String metadataFile = "v1-49494949.metadata.json"; TaskTestUtils.writeTableMetadata(fileIO, metadataFile, snapshot); - TableLikeEntity tableLikeEntity = - new TableLikeEntity.Builder(tableIdentifier, metadataFile) + IcebergTableLikeEntity icebergTableLikeEntity = + new IcebergTableLikeEntity.Builder(tableIdentifier, metadataFile) .setName("table1") .setCatalogId(1) .setCreateTimestamp(100) @@ -208,7 +208,7 @@ public void close() { new TaskEntity.Builder() .setName("cleanup_" + tableIdentifier) .withTaskType(AsyncTaskType.ENTITY_CLEANUP_SCHEDULER) - .withData(tableLikeEntity) + .withData(icebergTableLikeEntity) .build(); addTaskLocation(task); Assertions.assertThatPredicate(handler::canHandleTask).accepts(task); @@ -265,7 +265,7 @@ public void close() { .setName("cleanup_" + tableIdentifier) .withTaskType(AsyncTaskType.ENTITY_CLEANUP_SCHEDULER) .withData( - new TableLikeEntity.Builder(tableIdentifier, metadataFile) + new IcebergTableLikeEntity.Builder(tableIdentifier, metadataFile) .setName("table1") .setCatalogId(1) .setCreateTimestamp(100) @@ -396,7 +396,7 @@ public void testTableCleanupMultipleSnapshots() throws IOException { .setName("cleanup_" + tableIdentifier) .withTaskType(AsyncTaskType.ENTITY_CLEANUP_SCHEDULER) .withData( - new TableLikeEntity.Builder(tableIdentifier, metadataFile) + new IcebergTableLikeEntity.Builder(tableIdentifier, metadataFile) .setName("table1") .setCatalogId(1) .setCreateTimestamp(100) @@ -554,7 +554,7 @@ public void testTableCleanupMultipleMetadata() throws IOException { .setName("cleanup_" + tableIdentifier) .withTaskType(AsyncTaskType.ENTITY_CLEANUP_SCHEDULER) .withData( - new TableLikeEntity.Builder(tableIdentifier, secondMetadataFile) + new IcebergTableLikeEntity.Builder(tableIdentifier, secondMetadataFile) .setName("table1") .setCatalogId(1) .setCreateTimestamp(100) diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index c05a6b2a3d..e65a3fbebf 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -70,6 +70,7 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.CatalogRoleEntity; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; @@ -80,7 +81,6 @@ import org.apache.polaris.core.entity.PolarisPrivilege; import org.apache.polaris.core.entity.PrincipalEntity; import org.apache.polaris.core.entity.PrincipalRoleEntity; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -461,7 +461,8 @@ private void authorizeGrantOnTableLikeOperationOrThrow( entityManager.prepareResolutionManifest(callContext, securityContext, catalogName); resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(identifier), PolarisEntityType.TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(identifier), + PolarisEntityType.ICEBERG_TABLE_LIKE), identifier); resolutionManifest.addPath( new ResolverPath(List.of(catalogRoleName), PolarisEntityType.CATALOG_ROLE), @@ -471,7 +472,8 @@ private void authorizeGrantOnTableLikeOperationOrThrow( if (status.getStatus() == ResolverStatus.StatusEnum.ENTITY_COULD_NOT_BE_RESOLVED) { throw new NotFoundException("Catalog not found: %s", catalogName); } else if (status.getStatus() == ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED) { - if (status.getFailedToResolvePath().getLastEntityType() == PolarisEntityType.TABLE_LIKE) { + if (status.getFailedToResolvePath().getLastEntityType() + == PolarisEntityType.ICEBERG_TABLE_LIKE) { if (subType == PolarisEntitySubType.TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); } else { @@ -1617,10 +1619,11 @@ public List listGrantsForCatalogRole(String catalogName, String c namespaceGrants.add(grant); break; } - case TABLE_LIKE: + case ICEBERG_TABLE_LIKE: { if (baseEntity.getSubType() == PolarisEntitySubType.TABLE) { - TableIdentifier identifier = TableLikeEntity.of(baseEntity).getTableIdentifier(); + TableIdentifier identifier = + IcebergTableLikeEntity.of(baseEntity).getTableIdentifier(); TableGrant grant = new TableGrant( List.of(identifier.namespace().levels()), @@ -1629,7 +1632,8 @@ public List listGrantsForCatalogRole(String catalogName, String c GrantResource.TypeEnum.TABLE); tableGrants.add(grant); } else { - TableIdentifier identifier = TableLikeEntity.of(baseEntity).getTableIdentifier(); + TableIdentifier identifier = + IcebergTableLikeEntity.of(baseEntity).getTableIdentifier(); ViewGrant grant = new ViewGrant( List.of(identifier.namespace().levels()), diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java index f9d4bd19dd..be7f79ca5c 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java @@ -16,29 +16,143 @@ * specific language governing permissions and limitations * under the License. */ - package org.apache.polaris.service.catalog.generic; +import jakarta.ws.rs.core.SecurityContext; +import java.util.List; +import java.util.Map; import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.iceberg.exceptions.AlreadyExistsException; +import org.apache.iceberg.exceptions.NoSuchTableException; +import org.apache.polaris.core.context.CallContext; +import org.apache.polaris.core.entity.CatalogEntity; +import org.apache.polaris.core.entity.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.persistence.PolarisEntityManager; +import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; +import org.apache.polaris.core.persistence.dao.entity.BaseResult; +import org.apache.polaris.core.persistence.dao.entity.EntityResult; +import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifestCatalogView; +import org.apache.polaris.service.catalog.io.FileIOFactory; +import org.apache.polaris.service.task.TaskExecutor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PolarisGenericTableCatalog { - /** - * Caller must fill in all entity fields except parentId, since the caller may not want to - * duplicate the logic to try to resolve parentIds before constructing the proposed entity. This - * method will fill in the parentId if needed upon resolution. - */ - private void createTableLike(TableIdentifier identifier, PolarisEntity entity) { - PolarisResolvedPathWrapper resolvedParent = - resolvedEntityView.getResolvedPath(identifier.namespace()); - if (resolvedParent == null) { - // Illegal state because the namespace should've already been in the static resolution set. - throw new IllegalStateException( - String.format("Failed to fetch resolved parent for TableIdentifier '%s'", identifier)); - } - - createTableLike(identifier, entity, resolvedParent); + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericTableCatalog.class); + + private final PolarisEntityManager entityManager; + private final CallContext callContext; + private final PolarisResolutionManifestCatalogView resolvedEntityView; + private final CatalogEntity catalogEntity; + private final TaskExecutor taskExecutor; + private final SecurityContext securityContext; + private final String catalogName; + private long catalogId = -1; + private FileIOFactory fileIOFactory; + private PolarisMetaStoreManager metaStoreManager; + + /** + * @param entityManager provides handle to underlying PolarisMetaStoreManager with which to + * perform mutations on entities. + * @param callContext the current CallContext + * @param resolvedEntityView accessor to resolved entity paths that have been pre-vetted to ensure + * this catalog instance only interacts with authorized resolved paths. + * @param taskExecutor Executor we use to register cleanup task handlers + */ + public PolarisGenericTableCatalog( + PolarisEntityManager entityManager, + PolarisMetaStoreManager metaStoreManager, + CallContext callContext, + PolarisResolutionManifestCatalogView resolvedEntityView, + SecurityContext securityContext, + TaskExecutor taskExecutor, + FileIOFactory fileIOFactory) { + this.entityManager = entityManager; + this.callContext = callContext; + this.resolvedEntityView = resolvedEntityView; + this.catalogEntity = + CatalogEntity.of(resolvedEntityView.getResolvedReferenceCatalogEntity().getRawLeafEntity()); + this.securityContext = securityContext; + this.taskExecutor = taskExecutor; + this.catalogId = catalogEntity.getId(); + this.catalogName = catalogEntity.getName(); + this.fileIOFactory = fileIOFactory; + this.metaStoreManager = metaStoreManager; + } + + public void createGenericTable( + TableIdentifier tableIdentifier, String format, Map properties) { + PolarisResolvedPathWrapper resolvedParent = + resolvedEntityView.getResolvedPath(tableIdentifier.namespace()); + if (resolvedParent == null) { + // Illegal state because the namespace should've already been in the static resolution set. + throw new IllegalStateException( + String.format( + "Failed to fetch resolved parent for TableIdentifier '%s'", tableIdentifier)); } + List catalogPath = resolvedParent.getRawFullPath(); + + // TODO we need to filter by type here? + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntitySubType.ANY_SUBTYPE); + GenericTableEntity entity = + GenericTableEntity.of( + resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + if (null == entity) { + entity = + new GenericTableEntity.Builder(format) + .setCatalogId(this.catalogId) + .setId( + this.metaStoreManager + .generateNewEntityId(this.callContext.getPolarisCallContext()) + .getId()) + .setProperties(properties) + .build(); + } else { + throw new AlreadyExistsException( + "Iceberg table, view, or generic table already exists: %s", tableIdentifier); + } + + EntityResult res = + this.metaStoreManager.createEntityIfNotExists( + this.callContext.getPolarisCallContext(), + PolarisEntity.toCoreList(catalogPath), + entity); + if (!res.isSuccess()) { + switch (res.getReturnStatus()) { + case BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS: + throw new AlreadyExistsException( + "Iceberg table, view, or generic table already exists: %s", tableIdentifier); + + default: + throw new IllegalStateException( + String.format( + "Unknown error status for identifier %s: %s with extraInfo: %s", + tableIdentifier, res.getReturnStatus(), res.getExtraInformation())); + } + } + PolarisEntity resultEntity = PolarisEntity.of(res); + LOGGER.debug( + "Created GenericTable entity {} with TableIdentifier {}", resultEntity, tableIdentifier); + } + + public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { + // TODO we need to filter by type here? + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntitySubType.ANY_SUBTYPE); + GenericTableEntity entity = + GenericTableEntity.of( + resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + if (null == entity) { + throw new NoSuchTableException("Table does not exist: %s", tableIdentifier); + } else { + return entity; + } + } } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index b52dad2dcd..3866fe3529 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -102,7 +102,7 @@ * 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 BasePolarisCatalog layer, because this REST-adjacent layer captures intent of + * 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). @@ -219,7 +219,7 @@ private void authorizeBasicNamespaceOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(id), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, true /* optional */), id); } @@ -291,7 +291,7 @@ private void authorizeCreateTableLikeUnderNamespaceOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, true /* optional */), identifier); resolutionManifest.resolveAll(); @@ -318,7 +318,7 @@ private void authorizeBasicTableLikeOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, true /* optional */), identifier); resolutionManifest.resolveAll(); @@ -352,7 +352,7 @@ private void authorizeCollectionOfTableLikeOperationOrThrow( resolutionManifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE), + PolarisEntityType.ICEBERG_TABLE_LIKE), identifier)); ResolverStatus status = resolutionManifest.resolveAll(); @@ -404,7 +404,7 @@ private void authorizeRenameTableLikeOperationOrThrow( // Add src, dstParent, and dst(optional) resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(src), PolarisEntityType.TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(src), PolarisEntityType.ICEBERG_TABLE_LIKE), src); resolutionManifest.addPath( new ResolverPath(Arrays.asList(dst.namespace().levels()), PolarisEntityType.NAMESPACE), @@ -412,7 +412,7 @@ private void authorizeRenameTableLikeOperationOrThrow( resolutionManifest.addPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(dst), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, true /* optional */), dst); ResolverStatus status = resolutionManifest.resolveAll(); @@ -773,7 +773,7 @@ public boolean sendNotification(TableIdentifier identifier, NotificationRequest PolarisAuthorizableOperation op = PolarisAuthorizableOperation.SEND_NOTIFICATIONS; // For now, just require the full set of privileges on the base Catalog entity, which we can - // also express just as the "root" Namespace for purposes of the BasePolarisCatalog being + // also express just as the "root" Namespace for purposes of the PolarisIcebergCatalog being // able to fetch Namespace.empty() as path key. List extraPassthroughTableLikes = List.of(identifier); List extraPassthroughNamespaces = new ArrayList<>(); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java index c1127950e2..c0012af8c0 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java @@ -82,13 +82,13 @@ import org.apache.polaris.core.catalog.PolarisCatalogHelpers; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.NamespaceEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityConstants; import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisTaskConstants; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -131,7 +131,7 @@ public class PolarisIcebergCatalog extends BaseMetastoreViewCatalog // Config key for initializing a default "catalogFileIO" that is available either via getIo() // or for any TableOperations/ViewOperations instantiated, via ops.io() before entity-specific // FileIO initialization is triggered for any such operations. - // Typically this should only be used in test scenarios where a BasePolarisCatalog instance + // Typically this should only be used in test scenarios where a PolarisIcebergCatalog instance // is used for both the "client-side" and "server-side" logic instead of being access through // a REST layer. static final String INITIALIZE_DEFAULT_CATALOG_FILEIO_FOR_TEST = @@ -337,12 +337,12 @@ public Table registerTable(TableIdentifier identifier, String metadataFileLocati @Override public TableBuilder buildTable(TableIdentifier identifier, Schema schema) { - return new BasePolarisCatalogTableBuilder(identifier, schema); + return new PolarisIcebergCatalogTableBuilder(identifier, schema); } @Override public ViewBuilder buildView(TableIdentifier identifier) { - return new BasePolarisCatalogViewBuilder(identifier); + return new PolarisIcebergCatalogViewBuilder(identifier); } @Override @@ -381,17 +381,19 @@ private Set getLocationsAllowedToBeAccessed(TableMetadata tableMetadata) locations.add(tableMetadata.location()); if (tableMetadata .properties() - .containsKey(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)) { + .containsKey(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)) { locations.add( - tableMetadata.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)); + tableMetadata + .properties() + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)); } if (tableMetadata .properties() - .containsKey(TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)) { + .containsKey(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)) { locations.add( tableMetadata .properties() - .get(TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)); + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)); } return locations; } @@ -1111,7 +1113,7 @@ private void validateNoLocationOverlap( parentPath.stream() .map(PolarisEntity::toCore) .collect(Collectors.toList()), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (!siblingTablesResult.isSuccess()) { throw new IllegalStateException( @@ -1146,7 +1148,8 @@ private void validateNoLocationOverlap( tbl -> resolutionManifest.addPath( new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(tbl), PolarisEntityType.TABLE_LIKE), + PolarisCatalogHelpers.tableIdentifierToList(tbl), + PolarisEntityType.ICEBERG_TABLE_LIKE), tbl)); siblingNamespaces.forEach( ns -> @@ -1167,7 +1170,7 @@ private void validateNoLocationOverlap( tbl -> { PolarisResolvedPathWrapper resolveTablePath = resolutionManifest.getResolvedPath(tbl); - return TableLikeEntity.of(resolveTablePath.getRawLeafEntity()) + return IcebergTableLikeEntity.of(resolveTablePath.getRawLeafEntity()) .getBaseLocation(); }), siblingNamespaces.stream() @@ -1192,10 +1195,10 @@ private void validateNoLocationOverlap( }); } - private class BasePolarisCatalogTableBuilder + private class PolarisIcebergCatalogTableBuilder extends BaseMetastoreViewCatalog.BaseMetastoreViewCatalogTableBuilder { - public BasePolarisCatalogTableBuilder(TableIdentifier identifier, Schema schema) { + public PolarisIcebergCatalogTableBuilder(TableIdentifier identifier, Schema schema) { super(identifier, schema); } @@ -1205,9 +1208,9 @@ public TableBuilder withLocation(String newLocation) { } } - private class BasePolarisCatalogViewBuilder extends BaseMetastoreViewCatalog.BaseViewBuilder { + private class PolarisIcebergCatalogViewBuilder extends BaseMetastoreViewCatalog.BaseViewBuilder { - public BasePolarisCatalogViewBuilder(TableIdentifier identifier) { + public PolarisIcebergCatalogViewBuilder(TableIdentifier identifier) { super(identifier); withProperties( PropertyUtil.propertiesWithPrefix( @@ -1240,10 +1243,10 @@ public void doRefresh() { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntitySubType.TABLE); - TableLikeEntity entity = null; + IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { - entity = TableLikeEntity.of(resolvedEntities.getRawLeafEntity()); + entity = IcebergTableLikeEntity.of(resolvedEntities.getRawLeafEntity()); if (!tableIdentifier.equals(entity.getTableIdentifier())) { LOGGER .atError() @@ -1321,23 +1324,29 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { if (base == null || !metadata.location().equals(base.location()) || !Objects.equal( - base.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY), - metadata.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY))) { + base.properties().get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY), + metadata + .properties() + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY))) { // If location is changing then we must validate that the requested location is valid // for the storage configuration inherited under this entity's path. Set dataLocations = new HashSet<>(); dataLocations.add(metadata.location()); - if (metadata.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY) + if (metadata.properties().get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY) != null) { dataLocations.add( - metadata.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)); + metadata + .properties() + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY)); } - if (metadata.properties().get(TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY) + if (metadata + .properties() + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY) != null) { dataLocations.add( metadata .properties() - .get(TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)); + .get(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY)); } validateLocationsForTableLike(tableIdentifier, dataLocations, resolvedStorageEntity); // also validate that the table location doesn't overlap an existing table @@ -1369,13 +1378,14 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( tableIdentifier, PolarisEntitySubType.TABLE); - TableLikeEntity entity = - TableLikeEntity.of(resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + IcebergTableLikeEntity entity = + IcebergTableLikeEntity.of( + resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); String existingLocation; if (null == entity) { existingLocation = null; entity = - new TableLikeEntity.Builder(tableIdentifier, newLocation) + new IcebergTableLikeEntity.Builder(tableIdentifier, newLocation) .setCatalogId(getCatalogId()) .setSubType(PolarisEntitySubType.TABLE) .setBaseLocation(metadata.location()) @@ -1385,7 +1395,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { } else { existingLocation = entity.getMetadataLocation(); entity = - new TableLikeEntity.Builder(entity) + new IcebergTableLikeEntity.Builder(entity) .setBaseLocation(metadata.location()) .setMetadataLocation(newLocation) .build(); @@ -1465,10 +1475,10 @@ private class BasePolarisViewOperations extends BaseViewOperations { public void doRefresh() { PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath(identifier, PolarisEntitySubType.VIEW); - TableLikeEntity entity = null; + IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { - entity = TableLikeEntity.of(resolvedEntities.getRawLeafEntity()); + entity = IcebergTableLikeEntity.of(resolvedEntities.getRawLeafEntity()); if (!identifier.equals(entity.getTableIdentifier())) { LOGGER .atError() @@ -1559,13 +1569,14 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { String newLocation = writeNewMetadataIfRequired(metadata); String oldLocation = base == null ? null : currentMetadataLocation(); - TableLikeEntity entity = - TableLikeEntity.of(resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + IcebergTableLikeEntity entity = + IcebergTableLikeEntity.of( + resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); String existingLocation; if (null == entity) { existingLocation = null; entity = - new TableLikeEntity.Builder(identifier, newLocation) + new IcebergTableLikeEntity.Builder(identifier, newLocation) .setCatalogId(getCatalogId()) .setSubType(PolarisEntitySubType.VIEW) .setId( @@ -1573,7 +1584,8 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { .build(); } else { existingLocation = entity.getMetadataLocation(); - entity = new TableLikeEntity.Builder(entity).setMetadataLocation(newLocation).build(); + entity = + new IcebergTableLikeEntity.Builder(entity).setMetadataLocation(newLocation).build(); } if (!Objects.equal(existingLocation, oldLocation)) { if (null == base) { @@ -1668,7 +1680,7 @@ private void renameTableLike( } List catalogPath = resolvedEntities.getRawParentPath(); PolarisEntity leafEntity = resolvedEntities.getRawLeafEntity(); - final TableLikeEntity toEntity; + final IcebergTableLikeEntity toEntity; List newCatalogPath = null; if (!from.namespace().equals(to.namespace())) { PolarisResolvedPathWrapper resolvedNewParentEntities = @@ -1681,14 +1693,14 @@ private void renameTableLike( // the "to" table has a new parent and a new name / namespace path toEntity = - new TableLikeEntity.Builder(TableLikeEntity.of(leafEntity)) + new IcebergTableLikeEntity.Builder(IcebergTableLikeEntity.of(leafEntity)) .setTableIdentifier(to) .setParentId(resolvedNewParentEntities.getResolvedLeafEntity().getEntity().getId()) .build(); } else { // only the name of the entity is changed toEntity = - new TableLikeEntity.Builder(TableLikeEntity.of(leafEntity)) + new IcebergTableLikeEntity.Builder(IcebergTableLikeEntity.of(leafEntity)) .setTableIdentifier(to) .build(); } @@ -1748,7 +1760,8 @@ private void renameTableLike( "Unknown error status " + returnedEntityResult.getReturnStatus()); } } else { - TableLikeEntity returnedEntity = TableLikeEntity.of(returnedEntityResult.getEntity()); + IcebergTableLikeEntity returnedEntity = + IcebergTableLikeEntity.of(returnedEntityResult.getEntity()); if (!toEntity.getTableIdentifier().equals(returnedEntity.getTableIdentifier())) { // As long as there are older deployments which don't support the atomic update of the // internalProperties during rename, we can log and then patch it up explicitly @@ -1762,7 +1775,7 @@ private void renameTableLike( .updateEntityPropertiesIfNotChanged( getCurrentPolarisContext(), PolarisEntity.toCoreList(newCatalogPath), - new TableLikeEntity.Builder(returnedEntity).setTableIdentifier(to).build()); + new IcebergTableLikeEntity.Builder(returnedEntity).setTableIdentifier(to).build()); } } } @@ -1787,7 +1800,7 @@ private void createTableLike(TableIdentifier identifier, PolarisEntity entity) { private void createTableLike( TableIdentifier identifier, PolarisEntity entity, PolarisResolvedPathWrapper resolvedParent) { // Make sure the metadata file is valid for our allowed locations. - String metadataLocation = TableLikeEntity.of(entity).getMetadataLocation(); + String metadataLocation = IcebergTableLikeEntity.of(entity).getMetadataLocation(); validateLocationForTableLike(identifier, metadataLocation, resolvedParent); List catalogPath = resolvedParent.getRawFullPath(); @@ -1812,8 +1825,8 @@ private void createTableLike( throw new NotFoundException("Parent path does not exist for %s", identifier); case BaseResult.ReturnStatus.ENTITY_ALREADY_EXISTS: - throw new AlreadyExistsException("Table or View already exists: %s", identifier); - + throw new AlreadyExistsException( + "Iceberg table, view, or generic table already exists: %s", identifier); default: throw new IllegalStateException( String.format( @@ -1835,7 +1848,7 @@ private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { } // Make sure the metadata file is valid for our allowed locations. - String metadataLocation = TableLikeEntity.of(entity).getMetadataLocation(); + String metadataLocation = IcebergTableLikeEntity.of(entity).getMetadataLocation(); validateLocationForTableLike(identifier, metadataLocation, resolvedEntities); List catalogPath = resolvedEntities.getRawParentPath(); @@ -1976,15 +1989,16 @@ private boolean sendNotificationForTableLike( PolarisResolvedPathWrapper resolvedParent = resolvedEntityView.getPassthroughResolvedPath(ns); - TableLikeEntity entity = - TableLikeEntity.of(resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); + IcebergTableLikeEntity entity = + IcebergTableLikeEntity.of( + resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); String existingLocation; String newLocation = transformTableLikeLocation(request.getPayload().getMetadataLocation()); if (null == entity) { existingLocation = null; entity = - new TableLikeEntity.Builder(tableIdentifier, newLocation) + new IcebergTableLikeEntity.Builder(tableIdentifier, newLocation) .setCatalogId(getCatalogId()) .setSubType(PolarisEntitySubType.TABLE) .setId( @@ -2002,7 +2016,7 @@ private boolean sendNotificationForTableLike( } existingLocation = entity.getMetadataLocation(); entity = - new TableLikeEntity.Builder(entity) + new IcebergTableLikeEntity.Builder(entity) .setMetadataLocation(newLocation) .setLastNotificationTimestamp(request.getPayload().getTimestamp()) .build(); @@ -2078,7 +2092,7 @@ private List listTableLike(PolarisEntitySubType subType, Namesp .listEntities( getCurrentPolarisContext(), PolarisEntity.toCoreList(catalogPath), - PolarisEntityType.TABLE_LIKE, + PolarisEntityType.ICEBERG_TABLE_LIKE, subType) .getEntities()); return PolarisCatalogHelpers.nameAndIdToTableIdentifiers(catalogPath, entities); @@ -2092,8 +2106,8 @@ private List listTableLike(PolarisEntitySubType subType, Namesp * @return FileIO object */ private FileIO loadFileIO(String ioImpl, Map properties) { - TableLikeEntity tableLikeEntity = TableLikeEntity.of(catalogEntity); - TableIdentifier identifier = tableLikeEntity.getTableIdentifier(); + IcebergTableLikeEntity icebergTableLikeEntity = IcebergTableLikeEntity.of(catalogEntity); + TableIdentifier identifier = icebergTableLikeEntity.getTableIdentifier(); Set locations = Set.of(catalogEntity.getDefaultBaseLocation()); ResolvedPolarisEntity resolvedCatalogEntity = new ResolvedPolarisEntity(catalogEntity, List.of(), List.of()); @@ -2106,9 +2120,9 @@ private FileIO loadFileIO(String ioImpl, Map properties) { private void blockedUserSpecifiedWriteLocation(Map properties) { if (properties != null - && (properties.containsKey(TableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY) + && (properties.containsKey(IcebergTableLikeEntity.USER_SPECIFIED_WRITE_DATA_LOCATION_KEY) || properties.containsKey( - TableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY))) { + IcebergTableLikeEntity.USER_SPECIFIED_WRITE_METADATA_LOCATION_KEY))) { throw new ForbiddenException( "Delegate access to table with user-specified write location is temporarily not supported."); } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index 8527a30c61..306ffb23f9 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -69,8 +69,8 @@ public static Optional findStorageInfoFromHierarchy( *

    Use cases: * *

      - *
    • In {@link PolarisIcebergCatalog}, subscoped credentials are generated or refreshed when the - * client sends a loadTable request to vend credentials. + *
    • In {@link PolarisIcebergCatalog}, subscoped credentials are generated or refreshed when + * the client sends a loadTable request to vend credentials. *
    • In {@link DefaultFileIOFactory}, subscoped credentials are obtained to access the storage * and read/write metadata JSON files. *
    diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java index 3a9cab8f15..35873dc088 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TableCleanupTaskHandler.java @@ -33,10 +33,10 @@ import org.apache.polaris.core.PolarisCallContext; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.AsyncTaskType; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntityType; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.entity.TaskEntity; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; @@ -71,7 +71,7 @@ public boolean canHandleTask(TaskEntity task) { private boolean taskEntityIsTable(TaskEntity task) { PolarisEntity entity = PolarisEntity.of((task.readData(PolarisBaseEntity.class))); - return entity.getType().equals(PolarisEntityType.TABLE_LIKE); + return entity.getType().equals(PolarisEntityType.ICEBERG_TABLE_LIKE); } @Override @@ -79,7 +79,7 @@ public boolean handleTask(TaskEntity cleanupTask, CallContext callContext) { PolarisBaseEntity entity = cleanupTask.readData(PolarisBaseEntity.class); PolarisMetaStoreManager metaStoreManager = metaStoreManagerFactory.getOrCreateMetaStoreManager(callContext.getRealmContext()); - TableLikeEntity tableEntity = TableLikeEntity.of(entity); + IcebergTableLikeEntity tableEntity = IcebergTableLikeEntity.of(entity); PolarisCallContext polarisCallContext = callContext.getPolarisCallContext(); LOGGER .atInfo() @@ -153,7 +153,7 @@ private Stream getManifestTaskStream( TaskEntity cleanupTask, TableMetadata tableMetadata, FileIO fileIO, - TableLikeEntity tableEntity, + IcebergTableLikeEntity tableEntity, PolarisMetaStoreManager metaStoreManager, PolarisCallContext polarisCallContext) { // read the manifest list for each snapshot. dedupe the manifest files and schedule a @@ -204,7 +204,7 @@ private Stream getMetadataTaskStream( TaskEntity cleanupTask, TableMetadata tableMetadata, FileIO fileIO, - TableLikeEntity tableEntity, + IcebergTableLikeEntity tableEntity, PolarisMetaStoreManager metaStoreManager, PolarisCallContext polarisCallContext) { int batchSize = diff --git a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java index 679d48060b..b87c062718 100644 --- a/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java +++ b/service/common/src/main/java/org/apache/polaris/service/task/TaskFileIOSupplier.java @@ -29,8 +29,8 @@ import org.apache.iceberg.catalog.TableIdentifier; import org.apache.iceberg.io.FileIO; import org.apache.polaris.core.context.CallContext; +import org.apache.polaris.core.entity.IcebergTableLikeEntity; import org.apache.polaris.core.entity.PolarisTaskConstants; -import org.apache.polaris.core.entity.TableLikeEntity; import org.apache.polaris.core.entity.TaskEntity; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.persistence.ResolvedPolarisEntity; @@ -51,7 +51,7 @@ public FileIO apply(TaskEntity task, CallContext callContext) { Map internalProperties = task.getInternalPropertiesAsMap(); Map properties = new HashMap<>(internalProperties); - TableLikeEntity tableEntity = TableLikeEntity.of(task); + IcebergTableLikeEntity tableEntity = IcebergTableLikeEntity.of(task); TableIdentifier identifier = tableEntity.getTableIdentifier(); String location = properties.get(PolarisTaskConstants.STORAGE_LOCATION); Set locations = Set.of(location); diff --git a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java index 85625c6506..8f9f9f48cf 100644 --- a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java @@ -47,8 +47,8 @@ import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.*; import org.apache.polaris.service.TestServices; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.task.TaskFileIOSupplier; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index 8036cb1a51..cdf44fbd91 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -44,10 +44,10 @@ import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisServiceImpl; import org.apache.polaris.service.admin.api.PolarisCatalogsApi; -import org.apache.polaris.service.catalog.iceberg.DefaultIcebergCatalogPrefixParser; -import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; +import org.apache.polaris.service.catalog.iceberg.DefaultIcebergCatalogPrefixParser; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; import org.apache.polaris.service.config.DefaultConfigurationStore; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java index 4b7de659fe..35902e1a34 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java @@ -91,7 +91,7 @@ public PolarisResolvedPathWrapper getResolvedPath(Object key, PolarisEntitySubTy manifest.addPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE), + PolarisEntityType.ICEBERG_TABLE_LIKE), identifier); manifest.resolveAll(); return manifest.getResolvedPath(identifier, subType); @@ -130,7 +130,7 @@ public PolarisResolvedPathWrapper getPassthroughResolvedPath( manifest.addPassthroughPath( new ResolverPath( PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.TABLE_LIKE), + PolarisEntityType.ICEBERG_TABLE_LIKE), identifier); return manifest.getPassthroughResolvedPath(identifier, subType); } else { From c55fc54da14b6f97279dd32068eb79d182c9a83d Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Sun, 9 Mar 2025 23:09:01 -0700 Subject: [PATCH 05/18] some refactoring --- .../core/entity/GenericTableEntity.java | 3 +- .../resolver/PolarisResolutionManifest.java | 12 +- .../PolarisResolutionManifestCatalogView.java | 7 +- .../persistence/resolver/ResolverPath.java | 21 +- .../PolarisGenericTableCatalogTest.java | 321 ++++++++++++++++++ .../service/admin/PolarisAdminService.java | 9 +- .../generic/PolarisGenericTableCatalog.java | 8 +- .../iceberg/IcebergCatalogHandlerWrapper.java | 14 +- .../iceberg/PolarisIcebergCatalog.java | 35 +- .../PolarisPassthroughResolutionView.java | 21 +- 10 files changed, 402 insertions(+), 49 deletions(-) create mode 100644 quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java index a9756d55b1..ebad73c3a0 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java @@ -60,9 +60,10 @@ public Namespace getParentNamespace() { public static class Builder extends PolarisEntity.BaseBuilder { - public Builder(String format) { + public Builder(TableIdentifier tableIdentifier, String format) { super(); setType(PolarisEntityType.GENERIC_TABLE); + setTableIdentifier(tableIdentifier); setFormat(format); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifest.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifest.java index d37e2ce2ff..fd000a167a 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifest.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifest.java @@ -180,8 +180,9 @@ public PolarisResolvedPathWrapper getResolvedPath(Object key) { * "optional", or if it was resolved but the subType doesn't match the specified subType. */ @Override - public PolarisResolvedPathWrapper getResolvedPath(Object key, PolarisEntitySubType subType) { - return getResolvedPath(key, subType, false); + public PolarisResolvedPathWrapper getResolvedPath( + Object key, PolarisEntityType entityType, PolarisEntitySubType subType) { + return getResolvedPath(key, entityType, subType, false); } /** @@ -237,7 +238,7 @@ public PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key) { */ @Override public PolarisResolvedPathWrapper getPassthroughResolvedPath( - Object key, PolarisEntitySubType subType) { + Object key, PolarisEntityType entityType, PolarisEntitySubType subType) { PolarisResolvedPathWrapper resolvedPath = getPassthroughResolvedPath(key); if (resolvedPath == null) { return null; @@ -374,7 +375,10 @@ public PolarisResolvedPathWrapper getResolvedPath(Object key, boolean prependRoo * "optional", or if it was resolved but the subType doesn't match the specified subType. */ public PolarisResolvedPathWrapper getResolvedPath( - Object key, PolarisEntitySubType subType, boolean prependRootContainer) { + Object key, + PolarisEntityType entityType, + PolarisEntitySubType subType, + boolean prependRootContainer) { PolarisResolvedPathWrapper resolvedPath = getResolvedPath(key, prependRootContainer); if (resolvedPath == null) { return null; diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifestCatalogView.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifestCatalogView.java index 21e16f5757..e3d91cad12 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifestCatalogView.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/PolarisResolutionManifestCatalogView.java @@ -19,6 +19,7 @@ package org.apache.polaris.core.persistence.resolver; import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; /** @@ -30,9 +31,11 @@ public interface PolarisResolutionManifestCatalogView { PolarisResolvedPathWrapper getResolvedPath(Object key); - PolarisResolvedPathWrapper getResolvedPath(Object key, PolarisEntitySubType subType); + PolarisResolvedPathWrapper getResolvedPath( + Object key, PolarisEntityType entityType, PolarisEntitySubType subType); PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key); - PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key, PolarisEntitySubType subType); + PolarisResolvedPathWrapper getPassthroughResolvedPath( + Object key, PolarisEntityType entityType, PolarisEntitySubType subType); } diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverPath.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverPath.java index ca349ccaa9..cf092d2c8b 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverPath.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverPath.java @@ -29,7 +29,7 @@ public class ResolverPath { // catalog private final List entityNames; - // all entities in a path are namespaces except the last one which can be a table_like entity + // all entities in a path are namespaces except the last one which can be a table_like entity // versus a namespace private final PolarisEntityType lastEntityType; @@ -39,9 +39,17 @@ public class ResolverPath { /** * Constructor for an optional path * - * @param entityNames set of entity names, all are namespaces except the last one which is either - * a namespace or a table_like entity - * @param lastEntityType type of the last entity, either namespace or table_like + * @param entityNames set of entity names, all are namespaces except the last one a namespa + */ + public ResolverPath(List entityNames) { + this(entityNames, null, false); + } + + /** + * Constructor for an optional path + * + * @param entityNames set of entity names, all are namespaces except the last one + * @param lastEntityType type of the last entity */ public ResolverPath(List entityNames, PolarisEntityType lastEntityType) { this(entityNames, lastEntityType, false); @@ -50,9 +58,8 @@ public ResolverPath(List entityNames, PolarisEntityType lastEntityType) /** * Constructor for an optional path * - * @param entityNames set of entity names, all are namespaces except the last one which is either - * a namespace or a table_like entity - * @param lastEntityType type of the last entity, either namespace or table_like + * @param entityNames set of entity names, all are namespaces except the last one + * @param lastEntityType type of the last entity * @param isOptional true if optional */ public ResolverPath( diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java new file mode 100644 index 0000000000..a6514a8ebf --- /dev/null +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java @@ -0,0 +1,321 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.service.quarkus.catalog; + +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.when; + +import io.quarkus.test.junit.QuarkusMock; +import io.quarkus.test.junit.QuarkusTest; +import io.quarkus.test.junit.QuarkusTestProfile; +import io.quarkus.test.junit.TestProfile; +import jakarta.inject.Inject; +import jakarta.ws.rs.core.SecurityContext; +import java.io.IOException; +import java.lang.reflect.Method; +import java.time.Clock; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import org.apache.commons.lang3.NotImplementedException; +import org.apache.iceberg.catalog.Namespace; +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.polaris.core.PolarisCallContext; +import org.apache.polaris.core.PolarisConfiguration; +import org.apache.polaris.core.PolarisConfigurationStore; +import org.apache.polaris.core.PolarisDiagnostics; +import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; +import org.apache.polaris.core.admin.model.StorageConfigInfo; +import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; +import org.apache.polaris.core.auth.PolarisAuthorizerImpl; +import org.apache.polaris.core.auth.PolarisSecretsManager; +import org.apache.polaris.core.context.CallContext; +import org.apache.polaris.core.context.RealmContext; +import org.apache.polaris.core.entity.CatalogEntity; +import org.apache.polaris.core.entity.GenericTableEntity; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; +import org.apache.polaris.core.entity.PrincipalEntity; +import org.apache.polaris.core.persistence.MetaStoreManagerFactory; +import org.apache.polaris.core.persistence.PolarisEntityManager; +import org.apache.polaris.core.persistence.PolarisMetaStoreManager; +import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; +import org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet; +import org.apache.polaris.core.persistence.cache.EntityCache; +import org.apache.polaris.core.persistence.dao.entity.BaseResult; +import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; +import org.apache.polaris.core.storage.PolarisStorageIntegration; +import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider; +import org.apache.polaris.core.storage.aws.AwsCredentialsStorageIntegration; +import org.apache.polaris.core.storage.aws.AwsStorageConfigurationInfo; +import org.apache.polaris.core.storage.cache.StorageCredentialCache; +import org.apache.polaris.service.admin.PolarisAdminService; +import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; +import org.apache.polaris.service.catalog.generic.PolarisGenericTableCatalog; +import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.io.FileIOFactory; +import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl; +import org.apache.polaris.service.task.TaskExecutor; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInfo; +import org.mockito.Mockito; +import software.amazon.awssdk.services.sts.StsClient; +import software.amazon.awssdk.services.sts.model.AssumeRoleRequest; +import software.amazon.awssdk.services.sts.model.AssumeRoleResponse; +import software.amazon.awssdk.services.sts.model.Credentials; + +@QuarkusTest +@TestProfile(PolarisGenericTableCatalogTest.Profile.class) +public class PolarisGenericTableCatalogTest { + public static class Profile implements QuarkusTestProfile { + + @Override + public Map getConfigOverrides() { + return Map.of(); + } + } + + protected static final Namespace NS = Namespace.of("newdb"); + protected static final TableIdentifier TABLE = TableIdentifier.of(NS, "table"); + public static final String CATALOG_NAME = "polaris-catalog"; + public static final String TEST_ACCESS_KEY = "test_access_key"; + public static final String SECRET_ACCESS_KEY = "secret_access_key"; + public static final String SESSION_TOKEN = "session_token"; + + @Inject MetaStoreManagerFactory managerFactory; + @Inject PolarisConfigurationStore configurationStore; + @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; + @Inject PolarisDiagnostics diagServices; + + private PolarisGenericTableCatalog genericTableCatalog; + private PolarisIcebergCatalog icebergCatalog; + private CallContext callContext; + private AwsStorageConfigInfo storageConfigModel; + private String realmName; + private PolarisMetaStoreManager metaStoreManager; + private PolarisCallContext polarisContext; + private PolarisAdminService adminService; + private PolarisEntityManager entityManager; + private FileIOFactory fileIOFactory; + private AuthenticatedPolarisPrincipal authenticatedRoot; + private PolarisEntity catalogEntity; + private SecurityContext securityContext; + + @BeforeAll + public static void setUpMocks() { + PolarisStorageIntegrationProviderImpl mock = + Mockito.mock(PolarisStorageIntegrationProviderImpl.class); + QuarkusMock.installMockForType(mock, PolarisStorageIntegrationProviderImpl.class); + } + + @BeforeEach + @SuppressWarnings("unchecked") + public void before(TestInfo testInfo) { + realmName = + "realm_%s_%s" + .formatted( + testInfo.getTestMethod().map(Method::getName).orElse("test"), System.nanoTime()); + RealmContext realmContext = () -> realmName; + metaStoreManager = managerFactory.getOrCreateMetaStoreManager(realmContext); + polarisContext = + new PolarisCallContext( + managerFactory.getOrCreateSessionSupplier(realmContext).get(), + diagServices, + configurationStore, + Clock.systemDefaultZone()); + entityManager = + new PolarisEntityManager( + metaStoreManager, new StorageCredentialCache(), new EntityCache(metaStoreManager)); + + callContext = CallContext.of(realmContext, polarisContext); + + PrincipalEntity rootEntity = + new PrincipalEntity( + PolarisEntity.of( + metaStoreManager + .readEntityByName( + polarisContext, + null, + PolarisEntityType.PRINCIPAL, + PolarisEntitySubType.NULL_SUBTYPE, + "root") + .getEntity())); + + authenticatedRoot = new AuthenticatedPolarisPrincipal(rootEntity, Set.of()); + + securityContext = Mockito.mock(SecurityContext.class); + when(securityContext.getUserPrincipal()).thenReturn(authenticatedRoot); + when(securityContext.isUserInRole(isA(String.class))).thenReturn(true); + adminService = + new PolarisAdminService( + callContext, + entityManager, + metaStoreManager, + securityContext, + new PolarisAuthorizerImpl(new PolarisConfigurationStore() {})); + + String storageLocation = "s3://my-bucket/path/to/data"; + storageConfigModel = + AwsStorageConfigInfo.builder() + .setRoleArn("arn:aws:iam::012345678901:role/jdoe") + .setExternalId("externalId") + .setUserArn("aws::a:user:arn") + .setStorageType(StorageConfigInfo.StorageTypeEnum.S3) + .setAllowedLocations(List.of(storageLocation, "s3://externally-owned-bucket")) + .build(); + catalogEntity = + adminService.createCatalog( + new CatalogEntity.Builder() + .setName(CATALOG_NAME) + .setDefaultBaseLocation(storageLocation) + .setReplaceNewLocationPrefixWithCatalogDefault("file:") + .addProperty( + PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + .addProperty( + PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + .setStorageConfigurationInfo(storageConfigModel, storageLocation) + .build()); + + PolarisPassthroughResolutionView passthroughView = + new PolarisPassthroughResolutionView( + callContext, entityManager, securityContext, CATALOG_NAME); + TaskExecutor taskExecutor = Mockito.mock(); + + StsClient stsClient = Mockito.mock(StsClient.class); + when(stsClient.assumeRole(isA(AssumeRoleRequest.class))) + .thenReturn( + AssumeRoleResponse.builder() + .credentials( + Credentials.builder() + .accessKeyId(TEST_ACCESS_KEY) + .secretAccessKey(SECRET_ACCESS_KEY) + .sessionToken(SESSION_TOKEN) + .build()) + .build()); + PolarisStorageIntegration storageIntegration = + new AwsCredentialsStorageIntegration(stsClient); + when(storageIntegrationProvider.getStorageIntegrationForConfig( + isA(AwsStorageConfigurationInfo.class))) + .thenReturn((PolarisStorageIntegration) storageIntegration); + + this.genericTableCatalog = + new PolarisGenericTableCatalog( + entityManager, + metaStoreManager, + callContext, + passthroughView, + securityContext, + taskExecutor, + fileIOFactory); + this.icebergCatalog = + new PolarisIcebergCatalog( + entityManager, + metaStoreManager, + callContext, + passthroughView, + securityContext, + taskExecutor, + fileIOFactory); + } + + @AfterEach + public void after() throws IOException { + metaStoreManager.purge(polarisContext); + } + + private MetaStoreManagerFactory createMockMetaStoreManagerFactory() { + return new MetaStoreManagerFactory() { + @Override + public PolarisMetaStoreManager getOrCreateMetaStoreManager(RealmContext realmContext) { + return metaStoreManager; + } + + @Override + public Supplier getOrCreateSessionSupplier( + RealmContext realmContext) { + return () -> polarisContext.getMetaStore(); + } + + @Override + public StorageCredentialCache getOrCreateStorageCredentialCache(RealmContext realmContext) { + return new StorageCredentialCache(); + } + + @Override + public EntityCache getOrCreateEntityCache(RealmContext realmContext) { + return new EntityCache(metaStoreManager); + } + + @Override + public Map bootstrapRealms( + Iterable realms, RootCredentialsSet rootCredentialsSet) { + throw new NotImplementedException("Bootstrapping realms is not supported"); + } + + @Override + public Map purgeRealms(Iterable realms) { + throw new NotImplementedException("Purging realms is not supported"); + } + }; + } + + @Test + public void testCreateGenericTableDoesNotThrow() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + Assertions.assertThatCode( + () -> + genericTableCatalog.createGenericTable( + TableIdentifier.of("ns", "t1"), "test-format", Map.of())) + .doesNotThrowAnyException(); + } + + @Test + public void testGenericTableRoundTrip() { + Namespace namespace = Namespace.of("ns"); + icebergCatalog.createNamespace(namespace); + + String tableName = "t1"; + Map properties = Map.of("a", "b", "c", "d"); + String format = "round-trip-format"; + + genericTableCatalog.createGenericTable(TableIdentifier.of("ns", tableName), format, properties); + + // todo remove debugging + PolarisPassthroughResolutionView passthroughView = + new PolarisPassthroughResolutionView( + callContext, entityManager, securityContext, CATALOG_NAME); + PolarisResolvedPathWrapper dbg = passthroughView.getPassthroughResolvedPath(namespace); + System.out.println(dbg); + // todo end of debugging + + GenericTableEntity resultEntity = + genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", tableName)); + + Assertions.assertThat(resultEntity.getFormat()).isEqualTo(format); + Assertions.assertThat(resultEntity.getProperties()).isEqualTo(properties); + Assertions.assertThat(resultEntity.getName()).isEqualTo(tableName); + } +} diff --git a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java index e65a3fbebf..048a3a9d28 100644 --- a/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java +++ b/service/common/src/main/java/org/apache/polaris/service/admin/PolarisAdminService.java @@ -485,7 +485,8 @@ private void authorizeGrantOnTableLikeOperationOrThrow( } PolarisResolvedPathWrapper tableLikeWrapper = - resolutionManifest.getResolvedPath(identifier, subType, true); + resolutionManifest.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); PolarisResolvedPathWrapper catalogRoleWrapper = resolutionManifest.getResolvedPath(catalogRoleName, true); @@ -1719,7 +1720,8 @@ private boolean grantPrivilegeOnTableLikeToRole( .orElseThrow(() -> new NotFoundException("CatalogRole %s not found", catalogRoleName)); PolarisResolvedPathWrapper resolvedPathWrapper = - resolutionManifest.getResolvedPath(identifier, subType); + resolutionManifest.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); @@ -1757,7 +1759,8 @@ private boolean revokePrivilegeOnTableLikeFromRole( .orElseThrow(() -> new NotFoundException("CatalogRole %s not found", catalogRoleName)); PolarisResolvedPathWrapper resolvedPathWrapper = - resolutionManifest.getResolvedPath(identifier, subType); + resolutionManifest.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); if (resolvedPathWrapper == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NotFoundException("View %s not found", identifier); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java index be7f79ca5c..eb03b099f3 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java @@ -29,6 +29,7 @@ import org.apache.polaris.core.entity.GenericTableEntity; import org.apache.polaris.core.entity.PolarisEntity; import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; @@ -99,19 +100,20 @@ public void createGenericTable( // TODO we need to filter by type here? PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); if (null == entity) { entity = - new GenericTableEntity.Builder(format) + new GenericTableEntity.Builder(tableIdentifier, format) .setCatalogId(this.catalogId) .setId( this.metaStoreManager .generateNewEntityId(this.callContext.getPolarisCallContext()) .getId()) .setProperties(properties) + .setCreateTimestamp(System.currentTimeMillis()) .build(); } else { throw new AlreadyExistsException( @@ -145,7 +147,7 @@ public GenericTableEntity loadGenericTable(TableIdentifier tableIdentifier) { // TODO we need to filter by type here? PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntitySubType.ANY_SUBTYPE); + tableIdentifier, PolarisEntityType.GENERIC_TABLE, PolarisEntitySubType.ANY_SUBTYPE); GenericTableEntity entity = GenericTableEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index 3866fe3529..91edf21aeb 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -323,7 +323,8 @@ private void authorizeBasicTableLikeOperationOrThrow( identifier); resolutionManifest.resolveAll(); PolarisResolvedPathWrapper target = - resolutionManifest.getResolvedPath(identifier, subType, true); + resolutionManifest.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); if (target == null) { if (subType == PolarisEntitySubType.TABLE) { throw new NoSuchTableException("Table does not exist: %s", identifier); @@ -375,7 +376,8 @@ private void authorizeCollectionOfTableLikeOperationOrThrow( .map( identifier -> Optional.ofNullable( - resolutionManifest.getResolvedPath(identifier, subType, true)) + resolutionManifest.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true)) .orElseThrow( () -> subType == PolarisEntitySubType.TABLE @@ -419,7 +421,9 @@ private void authorizeRenameTableLikeOperationOrThrow( if (status.getStatus() == ResolverStatus.StatusEnum.PATH_COULD_NOT_BE_FULLY_RESOLVED && status.getFailedToResolvePath().getLastEntityType() == PolarisEntityType.NAMESPACE) { throw new NoSuchNamespaceException("Namespace does not exist: %s", dst.namespace()); - } else if (resolutionManifest.getResolvedPath(src, subType) == null) { + } else if (resolutionManifest.getResolvedPath( + src, PolarisEntityType.ICEBERG_TABLE_LIKE, subType) + == null) { if (subType == PolarisEntitySubType.TABLE) { throw new NoSuchTableException("Table does not exist: %s", src); } else { @@ -441,7 +445,9 @@ private void authorizeRenameTableLikeOperationOrThrow( throw new AlreadyExistsException("Cannot rename %s to %s. View already exists", src, dst); } - PolarisResolvedPathWrapper target = resolutionManifest.getResolvedPath(src, subType, true); + PolarisResolvedPathWrapper target = + resolutionManifest.getResolvedPath( + src, PolarisEntityType.ICEBERG_TABLE_LIKE, subType, true); PolarisResolvedPathWrapper secondary = resolutionManifest.getResolvedPath(dst.namespace(), true); authorizer.authorizeOrThrow( diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java index c0012af8c0..ed34781920 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java @@ -876,7 +876,8 @@ public String transformTableLikeLocation(String specifiedTableLikeLocation) { private @Nonnull Optional findStorageInfo(TableIdentifier tableIdentifier) { PolarisResolvedPathWrapper resolvedTableEntities = - resolvedEntityView.getResolvedPath(tableIdentifier, PolarisEntitySubType.TABLE); + resolvedEntityView.getResolvedPath( + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); PolarisResolvedPathWrapper resolvedStorageEntity = resolvedTableEntities == null @@ -947,7 +948,8 @@ private Map refreshCredentials( */ private void validateLocationForTableLike(TableIdentifier identifier, String location) { PolarisResolvedPathWrapper resolvedStorageEntity = - resolvedEntityView.getResolvedPath(identifier, PolarisEntitySubType.ANY_SUBTYPE); + resolvedEntityView.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.ANY_SUBTYPE); if (resolvedStorageEntity == null) { resolvedStorageEntity = resolvedEntityView.getResolvedPath(identifier.namespace()); } @@ -1242,7 +1244,7 @@ public void doRefresh() { // table entity instead of the statically-resolved authz resolution set. PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { @@ -1296,7 +1298,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { PolarisResolvedPathWrapper resolvedTableEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); // Fetch credentials for the resolved entity. The entity could be the table itself (if it has // already been stored and credentials have been configured directly) or it could be the @@ -1364,7 +1366,8 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { String oldLocation = base == null ? null : base.metadataFileLocation(); PolarisResolvedPathWrapper resolvedView = - resolvedEntityView.getPassthroughResolvedPath(tableIdentifier, PolarisEntitySubType.VIEW); + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); if (resolvedView != null) { throw new AlreadyExistsException("View with same name already exists: %s", tableIdentifier); } @@ -1377,7 +1380,7 @@ public void doCommit(TableMetadata base, TableMetadata metadata) { // persistence-layer commit). PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getPassthroughResolvedPath( - tableIdentifier, PolarisEntitySubType.TABLE); + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); IcebergTableLikeEntity entity = IcebergTableLikeEntity.of( resolvedEntities == null ? null : resolvedEntities.getRawLeafEntity()); @@ -1474,7 +1477,8 @@ private class BasePolarisViewOperations extends BaseViewOperations { @Override public void doRefresh() { PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getPassthroughResolvedPath(identifier, PolarisEntitySubType.VIEW); + resolvedEntityView.getPassthroughResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); IcebergTableLikeEntity entity = null; if (resolvedEntities != null) { @@ -1528,13 +1532,15 @@ public void doCommit(ViewMetadata base, ViewMetadata metadata) { } PolarisResolvedPathWrapper resolvedTable = - resolvedEntityView.getPassthroughResolvedPath(identifier, PolarisEntitySubType.TABLE); + resolvedEntityView.getPassthroughResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.TABLE); if (resolvedTable != null) { throw new AlreadyExistsException("Table with same name already exists: %s", identifier); } PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getPassthroughResolvedPath(identifier, PolarisEntitySubType.VIEW); + resolvedEntityView.getPassthroughResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, PolarisEntitySubType.VIEW); // Fetch credentials for the resolved entity. The entity could be the view itself (if it has // already been stored and credentials have been configured directly) or it could be the @@ -1670,7 +1676,8 @@ long getCatalogId() { private void renameTableLike( PolarisEntitySubType subType, TableIdentifier from, TableIdentifier to) { LOGGER.debug("Renaming tableLike from {} to {}", from, to); - PolarisResolvedPathWrapper resolvedEntities = resolvedEntityView.getResolvedPath(from, subType); + PolarisResolvedPathWrapper resolvedEntities = + resolvedEntityView.getResolvedPath(from, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); if (resolvedEntities == null) { if (subType == PolarisEntitySubType.VIEW) { throw new NoSuchViewException("Cannot rename %s to %s. View does not exist", from, to); @@ -1840,7 +1847,7 @@ private void createTableLike( private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getResolvedPath(identifier, entity.getSubType()); + resolvedEntityView.getResolvedPath(identifier, entity.getType(), entity.getSubType()); if (resolvedEntities == null) { // Illegal state because the identifier should've already been in the static resolution set. throw new IllegalStateException( @@ -1883,7 +1890,8 @@ private void updateTableLike(TableIdentifier identifier, PolarisEntity entity) { Map storageProperties, boolean purge) { PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getResolvedPath(identifier, subType); + resolvedEntityView.getResolvedPath( + identifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); if (resolvedEntities == null) { // TODO: Error? return new DropEntityResult(BaseResult.ReturnStatus.ENTITY_NOT_FOUND, null); @@ -1927,7 +1935,8 @@ private boolean sendNotificationForTableLike( LOGGER.debug( "Handling notification request {} for tableIdentifier {}", request, tableIdentifier); PolarisResolvedPathWrapper resolvedEntities = - resolvedEntityView.getPassthroughResolvedPath(tableIdentifier, subType); + resolvedEntityView.getPassthroughResolvedPath( + tableIdentifier, PolarisEntityType.ICEBERG_TABLE_LIKE, subType); NotificationType notificationType = request.getNotificationType(); diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java index 35902e1a34..8c98e910b1 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/catalog/PolarisPassthroughResolutionView.java @@ -83,23 +83,22 @@ public PolarisResolvedPathWrapper getResolvedPath(Object key) { } @Override - public PolarisResolvedPathWrapper getResolvedPath(Object key, PolarisEntitySubType subType) { + public PolarisResolvedPathWrapper getResolvedPath( + Object key, PolarisEntityType entityType, PolarisEntitySubType subType) { PolarisResolutionManifest manifest = entityManager.prepareResolutionManifest(callContext, securityContext, catalogName); if (key instanceof TableIdentifier identifier) { manifest.addPath( - new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE), + new ResolverPath(PolarisCatalogHelpers.tableIdentifierToList(identifier), entityType), identifier); manifest.resolveAll(); - return manifest.getResolvedPath(identifier, subType); + return manifest.getResolvedPath(identifier, entityType, subType); } else { throw new IllegalStateException( String.format( - "Trying to getResolvedPath(key, subType) for %s with class %s and subType %s", - key, key.getClass(), subType)); + "Trying to getResolvedPath(key, subType) for %s with class %s and type %s / %s", + key, key.getClass(), entityType, subType)); } } @@ -122,17 +121,15 @@ public PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key) { @Override public PolarisResolvedPathWrapper getPassthroughResolvedPath( - Object key, PolarisEntitySubType subType) { + Object key, PolarisEntityType entityType, PolarisEntitySubType subType) { PolarisResolutionManifest manifest = entityManager.prepareResolutionManifest(callContext, securityContext, catalogName); if (key instanceof TableIdentifier identifier) { manifest.addPassthroughPath( - new ResolverPath( - PolarisCatalogHelpers.tableIdentifierToList(identifier), - PolarisEntityType.ICEBERG_TABLE_LIKE), + new ResolverPath(PolarisCatalogHelpers.tableIdentifierToList(identifier), entityType), identifier); - return manifest.getPassthroughResolvedPath(identifier, subType); + return manifest.getPassthroughResolvedPath(identifier, entityType, subType); } else { throw new IllegalStateException( String.format( From fc1e716b0eed1173679310e14f0cd83ed107eb1c Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Sun, 9 Mar 2025 23:52:29 -0700 Subject: [PATCH 06/18] test stable --- .../polaris/core/entity/GenericTableEntity.java | 14 ++------------ .../catalog/PolarisGenericTableCatalogTest.java | 11 +---------- .../generic/PolarisGenericTableCatalog.java | 2 ++ 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java index ebad73c3a0..5553b1a46c 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/GenericTableEntity.java @@ -45,17 +45,7 @@ public static GenericTableEntity of(PolarisBaseEntity sourceEntity) { @JsonIgnore public String getFormat() { - return getPropertiesAsMap().get(GenericTableEntity.FORMAT_KEY); - } - - @JsonIgnore - public Namespace getParentNamespace() { - String encodedNamespace = - getInternalPropertiesAsMap().get(NamespaceEntity.PARENT_NAMESPACE_KEY); - if (encodedNamespace == null) { - return Namespace.empty(); - } - return RESTUtil.decodeNamespace(encodedNamespace); + return getInternalPropertiesAsMap().get(GenericTableEntity.FORMAT_KEY); } public static class Builder @@ -69,7 +59,7 @@ public Builder(TableIdentifier tableIdentifier, String format) { public GenericTableEntity.Builder setFormat(String format) { // TODO in the future, we may validate the format and require certain properties - properties.put(GenericTableEntity.FORMAT_KEY, format); + internalProperties.put(GenericTableEntity.FORMAT_KEY, format); return this; } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java index a6514a8ebf..d29f4391dd 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java @@ -57,7 +57,6 @@ import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; -import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet; import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.persistence.dao.entity.BaseResult; @@ -303,19 +302,11 @@ public void testGenericTableRoundTrip() { genericTableCatalog.createGenericTable(TableIdentifier.of("ns", tableName), format, properties); - // todo remove debugging - PolarisPassthroughResolutionView passthroughView = - new PolarisPassthroughResolutionView( - callContext, entityManager, securityContext, CATALOG_NAME); - PolarisResolvedPathWrapper dbg = passthroughView.getPassthroughResolvedPath(namespace); - System.out.println(dbg); - // todo end of debugging - GenericTableEntity resultEntity = genericTableCatalog.loadGenericTable(TableIdentifier.of("ns", tableName)); Assertions.assertThat(resultEntity.getFormat()).isEqualTo(format); - Assertions.assertThat(resultEntity.getProperties()).isEqualTo(properties); + Assertions.assertThat(resultEntity.getPropertiesAsMap()).isEqualTo(properties); Assertions.assertThat(resultEntity.getName()).isEqualTo(tableName); } } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java index eb03b099f3..247f1dd226 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java @@ -108,6 +108,8 @@ public void createGenericTable( entity = new GenericTableEntity.Builder(tableIdentifier, format) .setCatalogId(this.catalogId) + .setParentNamespace(tableIdentifier.namespace()) + .setParentId(resolvedParent.getRawLeafEntity().getId()) .setId( this.metaStoreManager .generateNewEntityId(this.callContext.getPolarisCallContext()) From 517da82dac475ff34e8266f97d4c65e2f98f3fdf Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 10 Mar 2025 10:46:01 -0700 Subject: [PATCH 07/18] small rename --- ...CatalogTest.java => PolarisGenericCatalogTest.java} | 10 +++++----- ...ricTableCatalog.java => PolarisGenericCatalog.java} | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisGenericTableCatalogTest.java => PolarisGenericCatalogTest.java} (98%) rename service/common/src/main/java/org/apache/polaris/service/catalog/generic/{PolarisGenericTableCatalog.java => PolarisGenericCatalog.java} (98%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java similarity index 98% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java index d29f4391dd..7a4795ea80 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java @@ -68,7 +68,7 @@ import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.generic.PolarisGenericTableCatalog; +import org.apache.polaris.service.catalog.generic.PolarisGenericCatalog; import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl; @@ -86,8 +86,8 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest -@TestProfile(PolarisGenericTableCatalogTest.Profile.class) -public class PolarisGenericTableCatalogTest { +@TestProfile(PolarisGenericCatalogTest.Profile.class) +public class PolarisGenericCatalogTest { public static class Profile implements QuarkusTestProfile { @Override @@ -108,7 +108,7 @@ public Map getConfigOverrides() { @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; - private PolarisGenericTableCatalog genericTableCatalog; + private PolarisGenericCatalog genericTableCatalog; private PolarisIcebergCatalog icebergCatalog; private CallContext callContext; private AwsStorageConfigInfo storageConfigModel; @@ -220,7 +220,7 @@ public void before(TestInfo testInfo) { .thenReturn((PolarisStorageIntegration) storageIntegration); this.genericTableCatalog = - new PolarisGenericTableCatalog( + new PolarisGenericCatalog( entityManager, metaStoreManager, callContext, diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java similarity index 98% rename from service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java index 247f1dd226..08c765252d 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java @@ -41,8 +41,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PolarisGenericTableCatalog { - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericTableCatalog.class); +public class PolarisGenericCatalog { + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericCatalog.class); private final PolarisEntityManager entityManager; private final CallContext callContext; @@ -63,7 +63,7 @@ public class PolarisGenericTableCatalog { * this catalog instance only interacts with authorized resolved paths. * @param taskExecutor Executor we use to register cleanup task handlers */ - public PolarisGenericTableCatalog( + public PolarisGenericCatalog( PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, CallContext callContext, From 589d8016386eb1824731268965f333a5f3ad3849 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 12 Mar 2025 10:22:49 -0700 Subject: [PATCH 08/18] rename per review --- ...ogTest.java => PolarisGenericTableCatalogTest.java} | 10 +++++----- ...ricCatalog.java => PolarisGenericTableCatalog.java} | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisGenericCatalogTest.java => PolarisGenericTableCatalogTest.java} (98%) rename service/common/src/main/java/org/apache/polaris/service/catalog/generic/{PolarisGenericCatalog.java => PolarisGenericTableCatalog.java} (98%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java similarity index 98% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java index 7a4795ea80..d29f4391dd 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java @@ -68,7 +68,7 @@ import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.generic.PolarisGenericCatalog; +import org.apache.polaris.service.catalog.generic.PolarisGenericTableCatalog; import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl; @@ -86,8 +86,8 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest -@TestProfile(PolarisGenericCatalogTest.Profile.class) -public class PolarisGenericCatalogTest { +@TestProfile(PolarisGenericTableCatalogTest.Profile.class) +public class PolarisGenericTableCatalogTest { public static class Profile implements QuarkusTestProfile { @Override @@ -108,7 +108,7 @@ public Map getConfigOverrides() { @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; - private PolarisGenericCatalog genericTableCatalog; + private PolarisGenericTableCatalog genericTableCatalog; private PolarisIcebergCatalog icebergCatalog; private CallContext callContext; private AwsStorageConfigInfo storageConfigModel; @@ -220,7 +220,7 @@ public void before(TestInfo testInfo) { .thenReturn((PolarisStorageIntegration) storageIntegration); this.genericTableCatalog = - new PolarisGenericCatalog( + new PolarisGenericTableCatalog( entityManager, metaStoreManager, callContext, diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java similarity index 98% rename from service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java index 08c765252d..247f1dd226 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java @@ -41,8 +41,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PolarisGenericCatalog { - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericCatalog.class); +public class PolarisGenericTableCatalog { + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericTableCatalog.class); private final PolarisEntityManager entityManager; private final CallContext callContext; @@ -63,7 +63,7 @@ public class PolarisGenericCatalog { * this catalog instance only interacts with authorized resolved paths. * @param taskExecutor Executor we use to register cleanup task handlers */ - public PolarisGenericCatalog( + public PolarisGenericTableCatalog( PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, CallContext callContext, From 84277aa3fa23c8531e6b373e34b45b1897ab427a Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Wed, 12 Mar 2025 12:11:17 -0700 Subject: [PATCH 09/18] bump id --- .../java/org/apache/polaris/core/entity/PolarisEntityType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java index f7af4ee7c9..c78de96cbc 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java @@ -35,7 +35,7 @@ public enum PolarisEntityType { ICEBERG_TABLE_LIKE(7, NAMESPACE, false, false), TASK(8, ROOT, false, false), FILE(9, ICEBERG_TABLE_LIKE, false, false), - GENERIC_TABLE(9, NAMESPACE, false, false); + GENERIC_TABLE(10, NAMESPACE, false, false); // to efficiently map a code to its corresponding entity type, use a reverse array which // is initialized below From 7774527d6d1883f3f8b3f6277d678b2dda5aad89 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Thu, 13 Mar 2025 22:11:24 -0700 Subject: [PATCH 10/18] move a file --- ...bergCatalogPrefixParser.java => CatalogPrefixParser.java} | 4 ++-- ...alogPrefixParser.java => DefaultCatalogPrefixParser.java} | 3 ++- .../service/catalog/iceberg/IcebergCatalogAdapter.java | 5 +++-- .../java/org/apache/polaris/service/TestServices.java | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) rename service/common/src/main/java/org/apache/polaris/service/catalog/{iceberg/IcebergCatalogPrefixParser.java => CatalogPrefixParser.java} (94%) rename service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/{DefaultIcebergCatalogPrefixParser.java => DefaultCatalogPrefixParser.java} (89%) diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java b/service/common/src/main/java/org/apache/polaris/service/catalog/CatalogPrefixParser.java similarity index 94% rename from service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/CatalogPrefixParser.java index 7b1409f43f..7af8fac022 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogPrefixParser.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/CatalogPrefixParser.java @@ -16,12 +16,12 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog.iceberg; +package org.apache.polaris.service.catalog; import org.apache.polaris.core.context.RealmContext; /** An extension point for converting Iceberg REST API "prefix" values to Polaris Catalog names. */ -public interface IcebergCatalogPrefixParser { +public interface CatalogPrefixParser { /** * Produces the name of a Polaris catalog from the given Iceberg Catalog REST API "prefix" for the diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java similarity index 89% rename from service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java index 47efeb66f6..cc9781a4bb 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultIcebergCatalogPrefixParser.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java @@ -20,9 +20,10 @@ import jakarta.enterprise.context.ApplicationScoped; import org.apache.polaris.core.context.RealmContext; +import org.apache.polaris.service.catalog.CatalogPrefixParser; @ApplicationScoped -public class DefaultIcebergCatalogPrefixParser implements IcebergCatalogPrefixParser { +public class DefaultCatalogPrefixParser implements CatalogPrefixParser { @Override public String prefixToCatalogName(RealmContext realm, String prefix) { return prefix; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java index 16210eb356..cbd0d9b879 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java @@ -69,6 +69,7 @@ import org.apache.polaris.core.persistence.resolver.ResolverStatus; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.catalog.AccessDelegationMode; +import org.apache.polaris.service.catalog.CatalogPrefixParser; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; import org.apache.polaris.service.catalog.api.IcebergRestConfigurationApiService; import org.apache.polaris.service.context.CallContextCatalogFactory; @@ -130,7 +131,7 @@ public class IcebergCatalogAdapter private final PolarisConfigurationStore configurationStore; private final PolarisDiagnostics diagnostics; private final PolarisAuthorizer polarisAuthorizer; - private final IcebergCatalogPrefixParser prefixParser; + private final CatalogPrefixParser prefixParser; @Inject public IcebergCatalogAdapter( @@ -143,7 +144,7 @@ public IcebergCatalogAdapter( PolarisConfigurationStore configurationStore, PolarisDiagnostics diagnostics, PolarisAuthorizer polarisAuthorizer, - IcebergCatalogPrefixParser prefixParser) { + CatalogPrefixParser prefixParser) { this.realmContext = realmContext; this.callContext = callContext; this.catalogFactory = catalogFactory; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index cdf44fbd91..7ecc04cb42 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -46,7 +46,7 @@ import org.apache.polaris.service.admin.api.PolarisCatalogsApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; -import org.apache.polaris.service.catalog.iceberg.DefaultIcebergCatalogPrefixParser; +import org.apache.polaris.service.catalog.iceberg.DefaultCatalogPrefixParser; import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; @@ -181,7 +181,7 @@ public Map contextVariables() { configurationStore, polarisDiagnostics, authorizer, - new DefaultIcebergCatalogPrefixParser()); + new DefaultCatalogPrefixParser()); IcebergRestCatalogApi restApi = new IcebergRestCatalogApi(service); From 37049fefe08b81ec19384666096b3af3766b7899 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 14 Mar 2025 09:55:21 -0700 Subject: [PATCH 11/18] autolint --- .../service/quarkus/catalog/PolarisIcebergCatalogTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java index a12a3bb826..39d5b543e6 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java @@ -35,7 +35,6 @@ import io.quarkus.test.junit.QuarkusTestProfile; import io.quarkus.test.junit.TestProfile; import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; From ab63c47ce533e813ee1593759335842d0bdd0eb2 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 14 Mar 2025 10:04:25 -0700 Subject: [PATCH 12/18] rebase --- .../catalog/PolarisCatalogNoEntityCacheTest.java | 4 ++-- .../catalog/PolarisCatalogWithEntityCacheTest.java | 4 ++-- .../catalog/PolarisGenericTableCatalogTest.java | 14 ++++++++------ .../quarkus/catalog/PolarisIcebergCatalogTest.java | 6 +++++- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java index 5389dcd826..bb047379d2 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java @@ -25,8 +25,8 @@ import org.apache.polaris.core.persistence.cache.EntityCache; @QuarkusTest -@TestProfile(BasePolarisCatalogTest.Profile.class) -public class PolarisCatalogNoEntityCacheTest extends BasePolarisCatalogTest { +@TestProfile(PolarisIcebergCatalogTest.Profile.class) +public class PolarisCatalogNoEntityCacheTest extends PolarisIcebergCatalogTest { @Nullable @Override diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java index f408267d07..ab54402ad8 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java @@ -25,8 +25,8 @@ import org.apache.polaris.core.persistence.cache.EntityCache; @QuarkusTest -@TestProfile(BasePolarisCatalogTest.Profile.class) -public class PolarisCatalogWithEntityCacheTest extends BasePolarisCatalogTest { +@TestProfile(PolarisIcebergCatalogTest.Profile.class) +public class PolarisCatalogWithEntityCacheTest extends PolarisIcebergCatalogTest { @Nullable @Override diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java index d29f4391dd..cc3aa364e8 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java @@ -38,14 +38,14 @@ import org.apache.iceberg.catalog.Namespace; import org.apache.iceberg.catalog.TableIdentifier; import org.apache.polaris.core.PolarisCallContext; -import org.apache.polaris.core.PolarisConfiguration; -import org.apache.polaris.core.PolarisConfigurationStore; import org.apache.polaris.core.PolarisDiagnostics; import org.apache.polaris.core.admin.model.AwsStorageConfigInfo; import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; import org.apache.polaris.core.auth.PolarisSecretsManager; +import org.apache.polaris.core.config.FeatureConfiguration; +import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.entity.CatalogEntity; @@ -54,12 +54,14 @@ import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PrincipalEntity; +import org.apache.polaris.core.persistence.BasePersistence; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.bootstrap.RootCredentialsSet; import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.persistence.dao.entity.BaseResult; +import org.apache.polaris.core.persistence.dao.entity.PrincipalSecretsResult; import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.core.storage.PolarisStorageIntegration; import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider; @@ -191,9 +193,9 @@ public void before(TestInfo testInfo) { .setDefaultBaseLocation(storageLocation) .setReplaceNewLocationPrefixWithCatalogDefault("file:") .addProperty( - PolarisConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_EXTERNAL_TABLE_LOCATION.catalogConfig(), "true") .addProperty( - PolarisConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") + FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .setStorageConfigurationInfo(storageConfigModel, storageLocation) .build()); @@ -252,7 +254,7 @@ public PolarisMetaStoreManager getOrCreateMetaStoreManager(RealmContext realmCon } @Override - public Supplier getOrCreateSessionSupplier( + public Supplier getOrCreateSessionSupplier( RealmContext realmContext) { return () -> polarisContext.getMetaStore(); } @@ -268,7 +270,7 @@ public EntityCache getOrCreateEntityCache(RealmContext realmContext) { } @Override - public Map bootstrapRealms( + public Map bootstrapRealms( Iterable realms, RootCredentialsSet rootCredentialsSet) { throw new NotImplementedException("Bootstrapping realms is not supported"); } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java index 39d5b543e6..426d95a470 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java @@ -35,6 +35,7 @@ import io.quarkus.test.junit.QuarkusTestProfile; import io.quarkus.test.junit.TestProfile; import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; @@ -143,7 +144,7 @@ @QuarkusTest @TestProfile(PolarisIcebergCatalogTest.Profile.class) -public class PolarisIcebergCatalogTest extends CatalogTests { +public abstract class PolarisIcebergCatalogTest extends CatalogTests { public static class Profile implements QuarkusTestProfile { @@ -196,6 +197,9 @@ public static void setUpMocks() { QuarkusMock.installMockForType(mock, PolarisStorageIntegrationProviderImpl.class); } + @Nullable + protected abstract EntityCache createEntityCache(PolarisMetaStoreManager metaStoreManager); + @BeforeEach @SuppressWarnings("unchecked") public void before(TestInfo testInfo) { From a0a320a787030c915da927ca830d2ce580113430 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Fri, 14 Mar 2025 10:04:28 -0700 Subject: [PATCH 13/18] autolint --- .../quarkus/catalog/PolarisGenericTableCatalogTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java index cc3aa364e8..1a664fb31a 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java @@ -43,7 +43,6 @@ import org.apache.polaris.core.admin.model.StorageConfigInfo; import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal; import org.apache.polaris.core.auth.PolarisAuthorizerImpl; -import org.apache.polaris.core.auth.PolarisSecretsManager; import org.apache.polaris.core.config.FeatureConfiguration; import org.apache.polaris.core.config.PolarisConfigurationStore; import org.apache.polaris.core.context.CallContext; @@ -62,7 +61,6 @@ import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.persistence.dao.entity.BaseResult; import org.apache.polaris.core.persistence.dao.entity.PrincipalSecretsResult; -import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.core.storage.PolarisStorageIntegration; import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider; import org.apache.polaris.core.storage.aws.AwsCredentialsStorageIntegration; @@ -254,8 +252,7 @@ public PolarisMetaStoreManager getOrCreateMetaStoreManager(RealmContext realmCon } @Override - public Supplier getOrCreateSessionSupplier( - RealmContext realmContext) { + public Supplier getOrCreateSessionSupplier(RealmContext realmContext) { return () -> polarisContext.getMetaStore(); } From d126fcf6863474155aca8013c63910f86f06ee93 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 17 Mar 2025 22:07:40 -0700 Subject: [PATCH 14/18] changes per review --- .../quarkus/admin/PolarisAuthzTestBase.java | 6 +- ...est.java => CatalogNoEntityCacheTest.java} | 4 +- ...Test.java => GenericTableCatalogTest.java} | 16 ++-- ...talogTest.java => IcebergCatalogTest.java} | 81 +++++++++---------- ...wTest.java => IcebergCatalogViewTest.java} | 12 +-- .../PolarisCatalogWithEntityCacheTest.java | 4 +- ...eCatalog.java => GenericTableCatalog.java} | 6 +- ...cebergCatalog.java => IcebergCatalog.java} | 10 +-- .../iceberg/IcebergCatalogHandlerWrapper.java | 14 ++-- .../service/catalog/io/FileIOUtil.java | 4 +- .../PolarisCallContextCatalogFactory.java | 6 +- .../service/catalog/io/FileIOFactoryTest.java | 12 +-- 12 files changed, 87 insertions(+), 88 deletions(-) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisCatalogNoEntityCacheTest.java => CatalogNoEntityCacheTest.java} (90%) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisGenericTableCatalogTest.java => GenericTableCatalogTest.java} (96%) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisIcebergCatalogTest.java => IcebergCatalogTest.java} (97%) rename quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/{PolarisIcebergCatalogViewTest.java => IcebergCatalogViewTest.java} (96%) rename service/common/src/main/java/org/apache/polaris/service/catalog/generic/{PolarisGenericTableCatalog.java => GenericTableCatalog.java} (97%) rename service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/{PolarisIcebergCatalog.java => IcebergCatalog.java} (99%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index d0f56669b4..44925991ba 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -76,7 +76,7 @@ import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.DefaultConfigurationStore; import org.apache.polaris.service.config.RealmEntityManagerFactory; @@ -174,7 +174,7 @@ public Map getConfigOverrides() { @Inject protected Clock clock; @Inject protected FileIOFactory fileIOFactory; - protected PolarisIcebergCatalog baseCatalog; + protected IcebergCatalog baseCatalog; protected PolarisAdminService adminService; protected PolarisEntityManager entityManager; protected PolarisMetaStoreManager metaStoreManager; @@ -431,7 +431,7 @@ private void initBaseCatalog() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); this.baseCatalog = - new PolarisIcebergCatalog( + new IcebergCatalog( entityManager, metaStoreManager, callContext, diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/CatalogNoEntityCacheTest.java similarity index 90% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/CatalogNoEntityCacheTest.java index bb047379d2..7e92b97b5a 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogNoEntityCacheTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/CatalogNoEntityCacheTest.java @@ -25,8 +25,8 @@ import org.apache.polaris.core.persistence.cache.EntityCache; @QuarkusTest -@TestProfile(PolarisIcebergCatalogTest.Profile.class) -public class PolarisCatalogNoEntityCacheTest extends PolarisIcebergCatalogTest { +@TestProfile(IcebergCatalogTest.Profile.class) +public class CatalogNoEntityCacheTest extends IcebergCatalogTest { @Nullable @Override diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java similarity index 96% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index 1a664fb31a..f80ebadde4 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisGenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -68,8 +68,8 @@ import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.generic.PolarisGenericTableCatalog; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.generic.GenericTableCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.storage.PolarisStorageIntegrationProviderImpl; import org.apache.polaris.service.task.TaskExecutor; @@ -86,8 +86,8 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest -@TestProfile(PolarisGenericTableCatalogTest.Profile.class) -public class PolarisGenericTableCatalogTest { +@TestProfile(GenericTableCatalogTest.Profile.class) +public class GenericTableCatalogTest { public static class Profile implements QuarkusTestProfile { @Override @@ -108,8 +108,8 @@ public Map getConfigOverrides() { @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; - private PolarisGenericTableCatalog genericTableCatalog; - private PolarisIcebergCatalog icebergCatalog; + private GenericTableCatalog genericTableCatalog; + private IcebergCatalog icebergCatalog; private CallContext callContext; private AwsStorageConfigInfo storageConfigModel; private String realmName; @@ -220,7 +220,7 @@ public void before(TestInfo testInfo) { .thenReturn((PolarisStorageIntegration) storageIntegration); this.genericTableCatalog = - new PolarisGenericTableCatalog( + new GenericTableCatalog( entityManager, metaStoreManager, callContext, @@ -229,7 +229,7 @@ public void before(TestInfo testInfo) { taskExecutor, fileIOFactory); this.icebergCatalog = - new PolarisIcebergCatalog( + new IcebergCatalog( entityManager, metaStoreManager, callContext, diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java similarity index 97% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java index 426d95a470..06730214e2 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java @@ -109,7 +109,7 @@ import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.ExceptionMappingFileIO; import org.apache.polaris.service.catalog.io.FileIOFactory; @@ -142,9 +142,8 @@ import software.amazon.awssdk.services.sts.model.AssumeRoleResponse; import software.amazon.awssdk.services.sts.model.Credentials; -@QuarkusTest -@TestProfile(PolarisIcebergCatalogTest.Profile.class) -public abstract class PolarisIcebergCatalogTest extends CatalogTests { +@TestProfile(IcebergCatalogTest.Profile.class) +public abstract class IcebergCatalogTest extends CatalogTests { public static class Profile implements QuarkusTestProfile { @@ -176,7 +175,7 @@ public Map getConfigOverrides() { @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; - private PolarisIcebergCatalog catalog; + private IcebergCatalog catalog; private CallContext callContext; private AwsStorageConfigInfo storageConfigModel; private StsClient stsClient; @@ -295,7 +294,7 @@ public void before(TestInfo testInfo) { .thenReturn((PolarisStorageIntegration) storageIntegration); this.catalog = - new PolarisIcebergCatalog( + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -316,7 +315,7 @@ public void after() throws IOException { } @Override - protected PolarisIcebergCatalog catalog() { + protected IcebergCatalog catalog() { return catalog; } @@ -381,7 +380,7 @@ public void testRenameTableMissingDestinationNamespace() { requiresNamespaceCreate(), "Only applicable if namespaces must be created before adding children"); - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); catalog.createNamespace(NS); Assertions.assertThat(catalog.tableExists(TABLE)) @@ -425,7 +424,7 @@ public void testCreateNestedNamespaceUnderMissingParent() { Assumptions.assumeTrue( supportsNestedNamespaces(), "Only applicable if nested namespaces are supoprted"); - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace child1 = Namespace.of("parent", "child1"); @@ -446,7 +445,7 @@ public void testValidateNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/validate_table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -509,7 +508,7 @@ public void testValidateNotificationInDisallowedLocation() { // filename. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -553,8 +552,8 @@ public void testValidateNotificationFailToCreateFileIO() { new RealmEntityManagerFactory(createMockMetaStoreManagerFactory()), managerFactory, configurationStore)); - PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + IcebergCatalog catalog = + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -599,7 +598,7 @@ public void testUpdateNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -643,7 +642,7 @@ public void testUpdateNotificationCreateTableInDisallowedLocation() { // The location of the metadata JSON file specified in the create will be forbidden. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -694,7 +693,7 @@ public void testCreateNotificationCreateTableInExternalLocation() { .addProperty( FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); TableMetadata tableMetadata = TableMetadata.buildFromEmpty() .assignUUID() @@ -751,7 +750,7 @@ public void testCreateNotificationCreateTableOutsideOfMetadataLocation() { .addProperty( FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); TableMetadata tableMetadata = TableMetadata.buildFromEmpty() .assignUUID() @@ -805,7 +804,7 @@ public void testUpdateNotificationCreateTableInExternalLocation() { .addProperty( FeatureConfiguration.ALLOW_UNSTRUCTURED_TABLE_LOCATION.catalogConfig(), "true") .build()); - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); InMemoryFileIO fileIO = getInMemoryIo(catalog); fileIO.addFile( @@ -877,8 +876,8 @@ public void testUpdateNotificationCreateTableWithLocalFilePrefix() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, catalogWithoutStorage); TaskExecutor taskExecutor = Mockito.mock(); - PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + IcebergCatalog catalog = + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -941,8 +940,8 @@ public void testUpdateNotificationCreateTableWithHttpPrefix() { new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, catalogName); TaskExecutor taskExecutor = Mockito.mock(); - PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + IcebergCatalog catalog = + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1019,7 +1018,7 @@ public void testUpdateNotificationWhenNamespacesExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1065,7 +1064,7 @@ public void testUpdateNotificationWhenTableExists() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1118,7 +1117,7 @@ public void testUpdateNotificationWhenTableExistsInDisallowedLocation() { // The location of the metadata JSON file specified in the update will be forbidden. final String tableLocation = "s3://forbidden-table-location/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1164,7 +1163,7 @@ public void testUpdateNotificationRejectOutOfOrderTimestamp() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -1229,7 +1228,7 @@ public void testUpdateNotificationWhenTableExistsFileSpecifiesDisallowedLocation final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1278,7 +1277,7 @@ public void testDropNotificationWhenTableAndNamespacesDontExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); TableIdentifier table = TableIdentifier.of(namespace, "table"); @@ -1313,7 +1312,7 @@ public void testDropNotificationWhenNamespacesExist() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1359,7 +1358,7 @@ public void testDropNotificationWhenTableExists() { final String tableLocation = "s3://externally-owned-bucket/table/"; final String tableMetadataLocation = tableLocation + "metadata/v1.metadata.json"; - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Namespace namespace = Namespace.of("parent", "child1"); @@ -1484,8 +1483,8 @@ public void testDropTableWithPurgeDisabled() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, noPurgeCatalogName); - PolarisIcebergCatalog noPurgeCatalog = - new PolarisIcebergCatalog( + IcebergCatalog noPurgeCatalog = + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1542,7 +1541,7 @@ private void createNonExistingNamespaces(Namespace namespace) { @ParameterizedTest @MethodSource public void testRetriableException(Exception exception, boolean shouldRetry) { - Assertions.assertThat(PolarisIcebergCatalog.SHOULD_RETRY_REFRESH_PREDICATE.test(exception)) + Assertions.assertThat(IcebergCatalog.SHOULD_RETRY_REFRESH_PREDICATE.test(exception)) .isEqualTo(shouldRetry); } @@ -1592,8 +1591,8 @@ public void testFileIOWrapper() { new RealmEntityManagerFactory(createMockMetaStoreManagerFactory()), managerFactory, configurationStore); - PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + IcebergCatalog catalog = + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -1665,7 +1664,7 @@ public FileIO loadFileIO( @Test public void testRegisterTableWithSlashlessMetadataLocation() { - PolarisIcebergCatalog catalog = catalog(); + IcebergCatalog catalog = catalog(); Assertions.assertThatThrownBy( () -> catalog.registerTable(TABLE, "metadata_location_without_slashes")) .isInstanceOf(IllegalArgumentException.class) @@ -1689,8 +1688,8 @@ public void testConcurrencyConflictCreateTableUpdatedDuringFinalTransaction() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); - final PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + final IcebergCatalog catalog = + new IcebergCatalog( entityManager, spyMetaStore, callContext, @@ -1737,8 +1736,8 @@ public void testConcurrencyConflictUpdateTableDuringFinalTransaction() { PolarisPassthroughResolutionView passthroughView = new PolarisPassthroughResolutionView( callContext, entityManager, securityContext, CATALOG_NAME); - final PolarisIcebergCatalog catalog = - new PolarisIcebergCatalog( + final IcebergCatalog catalog = + new IcebergCatalog( entityManager, spyMetaStore, callContext, @@ -1770,7 +1769,7 @@ public void testConcurrencyConflictUpdateTableDuringFinalTransaction() { .hasMessageContaining("conflict_table"); } - private static InMemoryFileIO getInMemoryIo(PolarisIcebergCatalog catalog) { + private static InMemoryFileIO getInMemoryIo(IcebergCatalog catalog) { return (InMemoryFileIO) ((ExceptionMappingFileIO) catalog.getIo()).getInnerIo(); } } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogViewTest.java similarity index 96% rename from quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java rename to quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogViewTest.java index 626dcdd776..bea9aa3100 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisIcebergCatalogViewTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogViewTest.java @@ -60,7 +60,7 @@ import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.admin.PolarisAdminService; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.catalog.io.DefaultFileIOFactory; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; @@ -73,8 +73,8 @@ import org.mockito.Mockito; @QuarkusTest -@TestProfile(PolarisIcebergCatalogViewTest.Profile.class) -public class PolarisIcebergCatalogViewTest extends ViewCatalogTests { +@TestProfile(IcebergCatalogViewTest.Profile.class) +public class IcebergCatalogViewTest extends ViewCatalogTests { public static class Profile implements QuarkusTestProfile { @@ -100,7 +100,7 @@ public Map getConfigOverrides() { @Inject PolarisConfigurationStore configurationStore; @Inject PolarisDiagnostics diagServices; - private PolarisIcebergCatalog catalog; + private IcebergCatalog catalog; private String realmName; private PolarisMetaStoreManager metaStoreManager; @@ -188,7 +188,7 @@ public void before(TestInfo testInfo) { new DefaultFileIOFactory( new RealmEntityManagerFactory(managerFactory), managerFactory, configurationStore); this.catalog = - new PolarisIcebergCatalog( + new IcebergCatalog( entityManager, metaStoreManager, callContext, @@ -209,7 +209,7 @@ public void after() throws IOException { } @Override - protected PolarisIcebergCatalog catalog() { + protected IcebergCatalog catalog() { return catalog; } diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java index ab54402ad8..64c96bb5be 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/PolarisCatalogWithEntityCacheTest.java @@ -25,8 +25,8 @@ import org.apache.polaris.core.persistence.cache.EntityCache; @QuarkusTest -@TestProfile(PolarisIcebergCatalogTest.Profile.class) -public class PolarisCatalogWithEntityCacheTest extends PolarisIcebergCatalogTest { +@TestProfile(IcebergCatalogTest.Profile.class) +public class PolarisCatalogWithEntityCacheTest extends IcebergCatalogTest { @Nullable @Override diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java similarity index 97% rename from service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java index 247f1dd226..86c4f0bbfe 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/generic/PolarisGenericTableCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/generic/GenericTableCatalog.java @@ -41,8 +41,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class PolarisGenericTableCatalog { - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisGenericTableCatalog.class); +public class GenericTableCatalog { + private static final Logger LOGGER = LoggerFactory.getLogger(GenericTableCatalog.class); private final PolarisEntityManager entityManager; private final CallContext callContext; @@ -63,7 +63,7 @@ public class PolarisGenericTableCatalog { * this catalog instance only interacts with authorized resolved paths. * @param taskExecutor Executor we use to register cleanup task handlers */ - public PolarisGenericTableCatalog( + public GenericTableCatalog( PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, CallContext callContext, diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java similarity index 99% rename from service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 861812506b..13c6857b14 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/PolarisIcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -118,9 +118,9 @@ import org.slf4j.LoggerFactory; /** Defines the relationship between PolarisEntities and Iceberg's business logic. */ -public class PolarisIcebergCatalog extends BaseMetastoreViewCatalog +public class IcebergCatalog extends BaseMetastoreViewCatalog implements SupportsNamespaces, SupportsNotifications, Closeable, SupportsCredentialDelegation { - private static final Logger LOGGER = LoggerFactory.getLogger(PolarisIcebergCatalog.class); + private static final Logger LOGGER = LoggerFactory.getLogger(IcebergCatalog.class); private static final Joiner SLASH = Joiner.on("/"); @@ -178,7 +178,7 @@ public class PolarisIcebergCatalog extends BaseMetastoreViewCatalog * this catalog instance only interacts with authorized resolved paths. * @param taskExecutor Executor we use to register cleanup task handlers */ - public PolarisIcebergCatalog( + public IcebergCatalog( PolarisEntityManager entityManager, PolarisMetaStoreManager metaStoreManager, CallContext callContext, @@ -568,7 +568,7 @@ private String resolveNamespaceLocation(Namespace namespace, Map .reversed() .stream() .map(entity -> baseLocation(callContext, entity)) - .map(PolarisIcebergCatalog::stripLeadingTrailingSlash) + .map(IcebergCatalog::stripLeadingTrailingSlash) .collect(Collectors.joining("/")); } @@ -1169,7 +1169,7 @@ public PolarisIcebergCatalogViewBuilder(TableIdentifier identifier) { super(identifier); withProperties( PropertyUtil.propertiesWithPrefix( - PolarisIcebergCatalog.this.properties(), "table-default.")); + IcebergCatalog.this.properties(), "table-default.")); } @Override diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index 8ba5e3bdae..e97180f712 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -477,7 +477,7 @@ public CreateNamespaceResponse createNamespace(CreateNamespaceRequest request) { } authorizeCreateNamespaceUnderNamespaceOperationOrThrow(op, namespace); - if (namespaceCatalog instanceof PolarisIcebergCatalog) { + if (namespaceCatalog instanceof IcebergCatalog) { // Note: The CatalogHandlers' default implementation will non-atomically create the // namespace and then fetch its properties using loadNamespaceMetadata for the response. // However, the latest namespace metadata technically isn't the same authorized instance, @@ -680,9 +680,9 @@ private TableMetadata stageTableCreateHelper(Namespace namespace, CreateTableReq if (request.location() != null) { // Even if the request provides a location, run it through the catalog's TableBuilder // to inherit any override behaviors if applicable. - if (baseCatalog instanceof PolarisIcebergCatalog) { + if (baseCatalog instanceof IcebergCatalog) { location = - ((PolarisIcebergCatalog) baseCatalog).transformTableLikeLocation(request.location()); + ((IcebergCatalog) baseCatalog).transformTableLikeLocation(request.location()); } else { location = request.location(); } @@ -903,11 +903,11 @@ private UpdateTableRequest applyUpdateFilters(UpdateTableRequest request) { request.updates().stream() .map( update -> { - if (baseCatalog instanceof PolarisIcebergCatalog + if (baseCatalog instanceof IcebergCatalog && update instanceof MetadataUpdate.SetLocation) { String requestedLocation = ((MetadataUpdate.SetLocation) update).location(); String filteredLocation = - ((PolarisIcebergCatalog) baseCatalog) + ((IcebergCatalog) baseCatalog) .transformTableLikeLocation(requestedLocation); return new MetadataUpdate.SetLocation(filteredLocation); } else { @@ -1026,7 +1026,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) throw new BadRequestException("Cannot update table on external catalogs."); } - if (!(baseCatalog instanceof PolarisIcebergCatalog)) { + if (!(baseCatalog instanceof IcebergCatalog)) { throw new BadRequestException( "Unsupported operation: commitTransaction with baseCatalog type: %s", baseCatalog.getClass().getName()); @@ -1037,7 +1037,7 @@ public void commitTransaction(CommitTransactionRequest commitTransactionRequest) // validations. TransactionWorkspaceMetaStoreManager transactionMetaStoreManager = new TransactionWorkspaceMetaStoreManager(metaStoreManager); - ((PolarisIcebergCatalog) baseCatalog).setMetaStoreManager(transactionMetaStoreManager); + ((IcebergCatalog) baseCatalog).setMetaStoreManager(transactionMetaStoreManager); commitTransactionRequest.tableChanges().stream() .forEach( diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index 3042a330e4..9736a2ade1 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -31,7 +31,7 @@ import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.storage.PolarisCredentialVendor; import org.apache.polaris.core.storage.PolarisStorageActions; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -69,7 +69,7 @@ public static Optional findStorageInfoFromHierarchy( *

    Use cases: * *

      - *
    • In {@link PolarisIcebergCatalog}, subscoped credentials are generated or refreshed when + *
    • In {@link IcebergCatalog}, subscoped credentials are generated or refreshed when * the client sends a loadTable request to vend credentials. *
    • In {@link DefaultFileIOFactory}, subscoped credentials are obtained to access the storage * and read/write metadata JSON files. diff --git a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java index 1bd2259e9d..2332e9a00d 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/PolarisCallContextCatalogFactory.java @@ -34,7 +34,7 @@ import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.config.RealmEntityManagerFactory; import org.apache.polaris.service.task.TaskExecutor; @@ -83,8 +83,8 @@ public Catalog createCallContextCatalog( PolarisEntityManager entityManager = entityManagerFactory.getOrCreateEntityManager(context.getRealmContext()); - PolarisIcebergCatalog catalogInstance = - new PolarisIcebergCatalog( + IcebergCatalog catalogInstance = + new IcebergCatalog( entityManager, metaStoreManagerFactory.getOrCreateMetaStoreManager(context.getRealmContext()), context, diff --git a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java index b088768385..9a070273b8 100644 --- a/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java +++ b/service/common/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java @@ -48,7 +48,7 @@ import org.apache.polaris.core.entity.*; import org.apache.polaris.service.TestServices; import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView; -import org.apache.polaris.service.catalog.iceberg.PolarisIcebergCatalog; +import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; import org.apache.polaris.service.task.TaskFileIOSupplier; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.AfterEach; @@ -157,7 +157,7 @@ public void after() {} @Test public void testLoadFileIOForTableLike() { - PolarisIcebergCatalog catalog = createCatalog(testServices); + IcebergCatalog catalog = createCatalog(testServices); catalog.createNamespace(NS); catalog.createTable(TABLE, SCHEMA); @@ -175,7 +175,7 @@ public void testLoadFileIOForTableLike() { @Test public void testLoadFileIOForCleanupTask() { - PolarisIcebergCatalog catalog = createCatalog(testServices); + IcebergCatalog catalog = createCatalog(testServices); catalog.createNamespace(NS); catalog.createTable(TABLE, SCHEMA); catalog.dropTable(TABLE, true); @@ -208,7 +208,7 @@ public void testLoadFileIOForCleanupTask() { Mockito.any()); } - PolarisIcebergCatalog createCatalog(TestServices services) { + IcebergCatalog createCatalog(TestServices services) { String storageLocation = "s3://my-bucket/path/to/data"; AwsStorageConfigInfo awsStorageConfigInfo = AwsStorageConfigInfo.builder() @@ -236,8 +236,8 @@ PolarisIcebergCatalog createCatalog(TestServices services) { services.entityManagerFactory().getOrCreateEntityManager(realmContext), services.securityContext(), CATALOG_NAME); - PolarisIcebergCatalog polarisCatalog = - new PolarisIcebergCatalog( + IcebergCatalog polarisCatalog = + new IcebergCatalog( services.entityManagerFactory().getOrCreateEntityManager(realmContext), services.metaStoreManagerFactory().getOrCreateMetaStoreManager(realmContext), callContext, From cec652c38af5709858318db5a2948de6c3a9b3da Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Mon, 17 Mar 2025 22:07:43 -0700 Subject: [PATCH 15/18] autolint --- .../polaris/service/quarkus/catalog/IcebergCatalogTest.java | 1 - .../polaris/service/catalog/iceberg/IcebergCatalog.java | 3 +-- .../service/catalog/iceberg/IcebergCatalogHandlerWrapper.java | 3 +-- .../org/apache/polaris/service/catalog/io/FileIOUtil.java | 4 ++-- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java index 06730214e2..3dafaf109a 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogTest.java @@ -31,7 +31,6 @@ import com.google.cloud.storage.StorageException; import com.google.common.collect.ImmutableMap; import io.quarkus.test.junit.QuarkusMock; -import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.QuarkusTestProfile; import io.quarkus.test.junit.TestProfile; import jakarta.annotation.Nonnull; diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 13c6857b14..00469cc491 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -1168,8 +1168,7 @@ private class PolarisIcebergCatalogViewBuilder extends BaseMetastoreViewCatalog. public PolarisIcebergCatalogViewBuilder(TableIdentifier identifier) { super(identifier); withProperties( - PropertyUtil.propertiesWithPrefix( - IcebergCatalog.this.properties(), "table-default.")); + PropertyUtil.propertiesWithPrefix(IcebergCatalog.this.properties(), "table-default.")); } @Override diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java index e97180f712..c774525c84 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerWrapper.java @@ -681,8 +681,7 @@ private TableMetadata stageTableCreateHelper(Namespace namespace, CreateTableReq // Even if the request provides a location, run it through the catalog's TableBuilder // to inherit any override behaviors if applicable. if (baseCatalog instanceof IcebergCatalog) { - location = - ((IcebergCatalog) baseCatalog).transformTableLikeLocation(request.location()); + location = ((IcebergCatalog) baseCatalog).transformTableLikeLocation(request.location()); } else { location = request.location(); } diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java index 9736a2ade1..481033dad0 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/io/FileIOUtil.java @@ -69,8 +69,8 @@ public static Optional findStorageInfoFromHierarchy( *

      Use cases: * *

        - *
      • In {@link IcebergCatalog}, subscoped credentials are generated or refreshed when - * the client sends a loadTable request to vend credentials. + *
      • In {@link IcebergCatalog}, subscoped credentials are generated or refreshed when the + * client sends a loadTable request to vend credentials. *
      • In {@link DefaultFileIOFactory}, subscoped credentials are obtained to access the storage * and read/write metadata JSON files. *
      From 213bb9dec6481dbaf6b2fa400c095e646223daf5 Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 18 Mar 2025 15:29:11 -0700 Subject: [PATCH 16/18] rename --- .../service/quarkus/catalog/GenericTableCatalogTest.java | 1 - .../catalog/{iceberg => }/DefaultCatalogPrefixParser.java | 3 +-- .../java/org/apache/polaris/service/TestServices.java | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) rename service/common/src/main/java/org/apache/polaris/service/catalog/{iceberg => }/DefaultCatalogPrefixParser.java (91%) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index f80ebadde4..b39919887c 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -86,7 +86,6 @@ import software.amazon.awssdk.services.sts.model.Credentials; @QuarkusTest -@TestProfile(GenericTableCatalogTest.Profile.class) public class GenericTableCatalogTest { public static class Profile implements QuarkusTestProfile { diff --git a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java b/service/common/src/main/java/org/apache/polaris/service/catalog/DefaultCatalogPrefixParser.java similarity index 91% rename from service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java rename to service/common/src/main/java/org/apache/polaris/service/catalog/DefaultCatalogPrefixParser.java index cc9781a4bb..2573c9069f 100644 --- a/service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/DefaultCatalogPrefixParser.java +++ b/service/common/src/main/java/org/apache/polaris/service/catalog/DefaultCatalogPrefixParser.java @@ -16,11 +16,10 @@ * specific language governing permissions and limitations * under the License. */ -package org.apache.polaris.service.catalog.iceberg; +package org.apache.polaris.service.catalog; import jakarta.enterprise.context.ApplicationScoped; import org.apache.polaris.core.context.RealmContext; -import org.apache.polaris.service.catalog.CatalogPrefixParser; @ApplicationScoped public class DefaultCatalogPrefixParser implements CatalogPrefixParser { diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index 5131c461e2..f2ec27503c 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -46,7 +46,7 @@ import org.apache.polaris.service.admin.api.PolarisCatalogsApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; -import org.apache.polaris.service.catalog.iceberg.DefaultCatalogPrefixParser; +import org.apache.polaris.service.catalog.DefaultCatalogPrefixParser; import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; From 6c71751fa502313f8f13a13025ee630ce322039f Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 18 Mar 2025 15:30:04 -0700 Subject: [PATCH 17/18] autolint --- .../service/quarkus/catalog/GenericTableCatalogTest.java | 1 - .../java/org/apache/polaris/service/TestServices.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java index b39919887c..57d49226c4 100644 --- a/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java +++ b/quarkus/service/src/test/java/org/apache/polaris/service/quarkus/catalog/GenericTableCatalogTest.java @@ -24,7 +24,6 @@ import io.quarkus.test.junit.QuarkusMock; import io.quarkus.test.junit.QuarkusTest; import io.quarkus.test.junit.QuarkusTestProfile; -import io.quarkus.test.junit.TestProfile; import jakarta.inject.Inject; import jakarta.ws.rs.core.SecurityContext; import java.io.IOException; diff --git a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java index f2ec27503c..f14b27a391 100644 --- a/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/service/common/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -44,9 +44,9 @@ import org.apache.polaris.core.persistence.transactional.TransactionalPersistence; import org.apache.polaris.service.admin.PolarisServiceImpl; import org.apache.polaris.service.admin.api.PolarisCatalogsApi; +import org.apache.polaris.service.catalog.DefaultCatalogPrefixParser; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApi; import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; -import org.apache.polaris.service.catalog.DefaultCatalogPrefixParser; import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; From ffed2bd60ee3e7aff9a59012376937bba33751ef Mon Sep 17 00:00:00 2001 From: Eric Maynard Date: Tue, 18 Mar 2025 22:24:38 -0700 Subject: [PATCH 18/18] fix merge conflict --- .../java/org/apache/polaris/core/entity/PolarisEntityType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java index 37f3f11baf..90d9aa9e5f 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/entity/PolarisEntityType.java @@ -36,7 +36,7 @@ public enum PolarisEntityType { TASK(8, ROOT, false, false), FILE(9, ICEBERG_TABLE_LIKE, false, false), POLICY(10, NAMESPACE, false, false), - GENERIC_TABLE(10, NAMESPACE, false, false); + GENERIC_TABLE(11, NAMESPACE, false, false); // to efficiently map a code to its corresponding entity type, use a reverse array which // is initialized below