This is an automated email from the ASF dual-hosted git repository. snazy pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/polaris.git
The following commit(s) were added to refs/heads/main by this push: new 95358a992 Extract ResolverFactory from PolarisEntityManager (#2148) 95358a992 is described below commit 95358a99221778b85905e5ea51afe90474378ce7 Author: Christopher Lambert <xn...@gmx.de> AuthorDate: Wed Jul 23 17:18:01 2025 +0200 Extract ResolverFactory from PolarisEntityManager (#2148) `PolarisEntityManager.prepareResolver` was the only place that used the `EntityCache`. By introducing an application-scoped `ResolverFactory` the creation of an `EntityCache` is decided only once in `QuarkusProducers`, which will become the only place where `MetaStoreManagerFactory.getOrCreateEntityCache` gets called. Note that the little left-over functionality of `PolarisEntityManager` can be split out to more dedicated interfaces in a follow-up most likely. --- .../core/persistence/PolarisEntityManager.java | 26 +++++------------- .../resolver/PolarisResolutionManifest.java | 12 ++++---- .../core/persistence/resolver/ResolverFactory.java | 32 ++++++++++++++++++++++ .../service/quarkus/config/QuarkusProducers.java | 21 ++++++++++++++ .../quarkus/admin/PolarisAuthzTestBase.java | 8 ++++-- .../catalog/AbstractIcebergCatalogTest.java | 17 ++++++++++-- .../catalog/AbstractIcebergCatalogViewTest.java | 11 ++++---- .../AbstractPolarisGenericTableCatalogTest.java | 10 +++---- .../quarkus/catalog/AbstractPolicyCatalogTest.java | 10 +++---- .../catalog/IcebergCatalogHandlerAuthzTest.java | 2 +- .../service/catalog/iceberg/IcebergCatalog.java | 10 +++---- .../catalog/iceberg/IcebergCatalogAdapter.java | 6 +++- .../service/config/RealmEntityManagerFactory.java | 15 ++++------ .../catalog/PolarisCallContextCatalogFactory.java | 14 ++++------ .../service/catalog/io/FileIOFactoryTest.java | 2 +- .../org/apache/polaris/service/TestServices.java | 32 ++++++++++++++++++---- 16 files changed, 148 insertions(+), 80 deletions(-) diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisEntityManager.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisEntityManager.java index 01342be2e..5f4c88af9 100644 --- a/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisEntityManager.java +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/PolarisEntityManager.java @@ -29,9 +29,8 @@ import org.apache.polaris.core.entity.PolarisEntitySubType; import org.apache.polaris.core.entity.PolarisEntityType; import org.apache.polaris.core.entity.PolarisGrantRecord; import org.apache.polaris.core.entity.PolarisPrivilege; -import org.apache.polaris.core.persistence.cache.EntityCache; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; -import org.apache.polaris.core.persistence.resolver.Resolver; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; /** * Wraps logic of handling name-caching and entity-caching against a concrete underlying entity @@ -40,31 +39,19 @@ import org.apache.polaris.core.persistence.resolver.Resolver; */ public class PolarisEntityManager { private final PolarisMetaStoreManager metaStoreManager; - private final EntityCache entityCache; + private final ResolverFactory resolverFactory; // Lazily instantiated only a single time per entity manager. private ResolvedPolarisEntity implicitResolvedRootContainerEntity = null; /** * @param metaStoreManager the metastore manager for the current realm - * @param entityCache the entity cache to use (it may be {@code null}). + * @param resolverFactory the resolver factory to use */ public PolarisEntityManager( - @Nonnull PolarisMetaStoreManager metaStoreManager, @Nullable EntityCache entityCache) { + @Nonnull PolarisMetaStoreManager metaStoreManager, @Nonnull ResolverFactory resolverFactory) { this.metaStoreManager = metaStoreManager; - this.entityCache = entityCache; - } - - public Resolver prepareResolver( - @Nonnull CallContext callContext, - @Nonnull SecurityContext securityContext, - @Nullable String referenceCatalogName) { - return new Resolver( - callContext.getPolarisCallContext(), - metaStoreManager, - securityContext, - entityCache, - referenceCatalogName); + this.resolverFactory = resolverFactory; } public PolarisResolutionManifest prepareResolutionManifest( @@ -72,7 +59,8 @@ public class PolarisEntityManager { @Nonnull SecurityContext securityContext, @Nullable String referenceCatalogName) { PolarisResolutionManifest manifest = - new PolarisResolutionManifest(callContext, this, securityContext, referenceCatalogName); + new PolarisResolutionManifest( + callContext, resolverFactory, securityContext, referenceCatalogName); manifest.setSimulatedResolvedRootContainerEntity( getSimulatedResolvedRootContainerEntity(callContext)); return manifest; 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 4fe7c8261..f8e18341a 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 @@ -34,7 +34,6 @@ import org.apache.polaris.core.entity.PolarisBaseEntity; 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.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; import org.apache.polaris.core.persistence.ResolvedPolarisEntity; import org.slf4j.Logger; @@ -51,7 +50,7 @@ import org.slf4j.LoggerFactory; public class PolarisResolutionManifest implements PolarisResolutionManifestCatalogView { private static final Logger LOGGER = LoggerFactory.getLogger(PolarisResolutionManifest.class); - private final PolarisEntityManager entityManager; + private final ResolverFactory resolverFactory; private final CallContext callContext; private final SecurityContext securityContext; private final String catalogName; @@ -78,13 +77,14 @@ public class PolarisResolutionManifest implements PolarisResolutionManifestCatal public PolarisResolutionManifest( CallContext callContext, - PolarisEntityManager entityManager, + ResolverFactory resolverFactory, SecurityContext securityContext, String catalogName) { - this.entityManager = entityManager; this.callContext = callContext; + this.resolverFactory = resolverFactory; this.catalogName = catalogName; - this.primaryResolver = entityManager.prepareResolver(callContext, securityContext, catalogName); + this.primaryResolver = + resolverFactory.createResolver(callContext, securityContext, catalogName); this.diagnostics = callContext.getPolarisCallContext().getDiagServices(); this.diagnostics.checkNotNull(securityContext, "null_security_context_for_resolution_manifest"); this.securityContext = securityContext; @@ -193,7 +193,7 @@ public class PolarisResolutionManifest implements PolarisResolutionManifestCatal // Run a single-use Resolver for this path. Resolver passthroughResolver = - entityManager.prepareResolver(callContext, securityContext, catalogName); + resolverFactory.createResolver(callContext, securityContext, catalogName); passthroughResolver.addPath(requestedPath); ResolverStatus status = passthroughResolver.resolveAll(); diff --git a/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverFactory.java b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverFactory.java new file mode 100644 index 000000000..a3515a89c --- /dev/null +++ b/polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/ResolverFactory.java @@ -0,0 +1,32 @@ +/* + * 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.persistence.resolver; + +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import jakarta.ws.rs.core.SecurityContext; +import org.apache.polaris.core.context.CallContext; + +public interface ResolverFactory { + Resolver createResolver( + @Nonnull CallContext callContext, + @Nonnull SecurityContext securityContext, + @Nullable String referenceCatalogName); +} diff --git a/runtime/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java b/runtime/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java index f3eeb161f..06f4b66bb 100644 --- a/runtime/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java +++ b/runtime/service/src/main/java/org/apache/polaris/service/quarkus/config/QuarkusProducers.java @@ -49,6 +49,9 @@ 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.resolver.Resolver; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; import org.apache.polaris.core.storage.cache.StorageCredentialCache; @@ -106,6 +109,24 @@ public class QuarkusProducers { return new StorageCredentialCache(storageCredentialCacheConfig); } + @Produces + @ApplicationScoped + public ResolverFactory resolverFactory( + MetaStoreManagerFactory metaStoreManagerFactory, + PolarisMetaStoreManager polarisMetaStoreManager) { + return (callContext, securityContext, referenceCatalogName) -> { + EntityCache entityCache = + metaStoreManagerFactory.getOrCreateEntityCache( + callContext.getRealmContext(), callContext.getRealmConfig()); + return new Resolver( + callContext.getPolarisCallContext(), + polarisMetaStoreManager, + securityContext, + entityCache, + referenceCatalogName); + }; + } + @Produces @ApplicationScoped public PolarisAuthorizer polarisAuthorizer() { diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java index 53698728c..211c0ae45 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/admin/PolarisAuthzTestBase.java @@ -72,6 +72,7 @@ import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.dao.entity.EntityResult; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.policy.PredefinedPolicyTypes; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; @@ -193,6 +194,7 @@ public abstract class PolarisAuthzTestBase { @Inject protected CatalogHandlerUtils catalogHandlerUtils; @Inject protected PolarisConfigurationStore configurationStore; @Inject protected StorageCredentialCache storageCredentialCache; + @Inject protected ResolverFactory resolverFactory; protected IcebergCatalog baseCatalog; protected PolarisGenericTableCatalog genericTableCatalog; @@ -468,7 +470,7 @@ public abstract class PolarisAuthzTestBase { this.baseCatalog = new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManager, callContext, passthroughView, @@ -498,14 +500,14 @@ public abstract class PolarisAuthzTestBase { @Inject public TestPolarisCallContextCatalogFactory( StorageCredentialCache storageCredentialCache, - RealmEntityManagerFactory entityManagerFactory, + ResolverFactory resolverFactory, MetaStoreManagerFactory metaStoreManagerFactory, TaskExecutor taskExecutor, FileIOFactory fileIOFactory, PolarisEventListener polarisEventListener) { super( storageCredentialCache, - entityManagerFactory, + resolverFactory, metaStoreManagerFactory, taskExecutor, fileIOFactory, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogTest.java index 463ef4daf..3a991d755 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogTest.java @@ -116,6 +116,8 @@ import org.apache.polaris.core.persistence.dao.entity.BaseResult; import org.apache.polaris.core.persistence.dao.entity.EntityResult; import org.apache.polaris.core.persistence.pagination.Page; import org.apache.polaris.core.persistence.pagination.PageToken; +import org.apache.polaris.core.persistence.resolver.Resolver; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; import org.apache.polaris.core.storage.PolarisStorageActions; @@ -235,6 +237,7 @@ public abstract class AbstractIcebergCatalogTest extends CatalogTests<IcebergCat private UserSecretsManager userSecretsManager; private PolarisCallContext polarisContext; private PolarisAdminService adminService; + private ResolverFactory resolverFactory; private PolarisEntityManager entityManager; private FileIOFactory fileIOFactory; private InMemoryFileIO fileIO; @@ -280,7 +283,17 @@ public abstract class AbstractIcebergCatalogTest extends CatalogTests<IcebergCat Clock.systemDefaultZone()); EntityCache entityCache = createEntityCache(polarisContext.getRealmConfig(), metaStoreManager); - entityManager = new PolarisEntityManager(metaStoreManager, entityCache); + resolverFactory = + (callContext, securityContext, referenceCatalogName) -> + new Resolver( + callContext.getPolarisCallContext(), + metaStoreManager, + securityContext, + entityCache, + referenceCatalogName); + QuarkusMock.installMockForType(resolverFactory, ResolverFactory.class); + + entityManager = new PolarisEntityManager(metaStoreManager, resolverFactory); // LocalPolarisMetaStoreManagerFactory.bootstrapServiceAndCreatePolarisPrincipalForRealm sets // the CallContext.setCurrentContext() but never clears it, whereas the NoSQL one resets it. @@ -437,7 +450,7 @@ public abstract class AbstractIcebergCatalogTest extends CatalogTests<IcebergCat TaskExecutor taskExecutor = Mockito.mock(TaskExecutor.class); return new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManager, polarisContext, passthroughView, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogViewTest.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogViewTest.java index 2a0408e8b..08b426c77 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogViewTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractIcebergCatalogViewTest.java @@ -55,7 +55,7 @@ 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.cache.EntityCache; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; import org.apache.polaris.core.storage.cache.StorageCredentialCache; @@ -117,6 +117,7 @@ public abstract class AbstractIcebergCatalogViewTest extends ViewCatalogTests<Ic @Inject StorageCredentialCache storageCredentialCache; @Inject PolarisDiagnostics diagServices; @Inject PolarisEventListener polarisEventListener; + @Inject ResolverFactory resolverFactory; private IcebergCatalog catalog; @@ -166,10 +167,8 @@ public abstract class AbstractIcebergCatalogViewTest extends ViewCatalogTests<Ic configurationStore, Clock.systemDefaultZone()); - EntityCache entityCache = - metaStoreManagerFactory.getOrCreateEntityCache( - polarisContext.getRealmContext(), polarisContext.getRealmConfig()); - PolarisEntityManager entityManager = new PolarisEntityManager(metaStoreManager, entityCache); + PolarisEntityManager entityManager = + new PolarisEntityManager(metaStoreManager, resolverFactory); CallContext.setCurrentContext(polarisContext); @@ -230,7 +229,7 @@ public abstract class AbstractIcebergCatalogViewTest extends ViewCatalogTests<Ic this.catalog = new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManager, polarisContext, passthroughView, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java index 473fa2ed7..959a542ca 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolarisGenericTableCatalogTest.java @@ -56,7 +56,7 @@ import org.apache.polaris.core.entity.table.GenericTableEntity; 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.cache.EntityCache; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; import org.apache.polaris.core.storage.PolarisStorageIntegration; @@ -104,6 +104,7 @@ public abstract class AbstractPolarisGenericTableCatalogTest { @Inject StorageCredentialCache storageCredentialCache; @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; + @Inject ResolverFactory resolverFactory; private PolarisGenericTableCatalog genericTableCatalog; private IcebergCatalog icebergCatalog; @@ -157,10 +158,7 @@ public abstract class AbstractPolarisGenericTableCatalogTest { configurationStore, Clock.systemDefaultZone()); - EntityCache entityCache = - metaStoreManagerFactory.getOrCreateEntityCache( - realmContext, polarisContext.getRealmConfig()); - entityManager = new PolarisEntityManager(metaStoreManager, entityCache); + entityManager = new PolarisEntityManager(metaStoreManager, resolverFactory); PrincipalEntity rootEntity = new PrincipalEntity( @@ -249,7 +247,7 @@ public abstract class AbstractPolarisGenericTableCatalogTest { this.icebergCatalog = new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManager, polarisContext, passthroughView, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolicyCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolicyCatalogTest.java index 66c2b53d5..68dc6d3f9 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolicyCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/AbstractPolicyCatalogTest.java @@ -64,7 +64,7 @@ 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.PolicyMappingAlreadyExistsException; -import org.apache.polaris.core.persistence.cache.EntityCache; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.policy.PredefinedPolicyTypes; import org.apache.polaris.core.policy.exceptions.NoSuchPolicyException; import org.apache.polaris.core.policy.exceptions.PolicyInUseException; @@ -131,6 +131,7 @@ public abstract class AbstractPolicyCatalogTest { @Inject StorageCredentialCache storageCredentialCache; @Inject PolarisStorageIntegrationProvider storageIntegrationProvider; @Inject PolarisDiagnostics diagServices; + @Inject ResolverFactory resolverFactory; private PolicyCatalog policyCatalog; private IcebergCatalog icebergCatalog; @@ -180,10 +181,7 @@ public abstract class AbstractPolicyCatalogTest { configurationStore, Clock.systemDefaultZone()); - EntityCache entityCache = - metaStoreManagerFactory.getOrCreateEntityCache( - realmContext, polarisContext.getRealmConfig()); - entityManager = new PolarisEntityManager(metaStoreManager, entityCache); + entityManager = new PolarisEntityManager(metaStoreManager, resolverFactory); callContext = polarisContext; @@ -270,7 +268,7 @@ public abstract class AbstractPolicyCatalogTest { this.icebergCatalog = new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManager, callContext, passthroughView, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerAuthzTest.java b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerAuthzTest.java index e275a8f9b..90c985f71 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerAuthzTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/quarkus/catalog/IcebergCatalogHandlerAuthzTest.java @@ -1789,7 +1789,7 @@ public class IcebergCatalogHandlerAuthzTest extends PolarisAuthzTestBase { PolarisCallContextCatalogFactory factory = new PolarisCallContextCatalogFactory( storageCredentialCache, - realmEntityManagerFactory, + resolverFactory, managerFactory, Mockito.mock(), new DefaultFileIOFactory(storageCredentialCache, managerFactory), 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 5cc43e2be..e2f4d96bd 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 @@ -104,7 +104,6 @@ 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.table.IcebergTableLikeEntity; -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.ResolvedPolarisEntity; @@ -116,6 +115,7 @@ import org.apache.polaris.core.persistence.pagination.Page; import org.apache.polaris.core.persistence.pagination.PageToken; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest; import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifestCatalogView; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.persistence.resolver.ResolverPath; import org.apache.polaris.core.persistence.resolver.ResolverStatus; import org.apache.polaris.core.storage.AccessConfig; @@ -167,8 +167,8 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog || isStorageProviderRetryableException(ExceptionUtils.getRootCause(ex))); }; - private final PolarisEntityManager entityManager; private final StorageCredentialCache storageCredentialCache; + private final ResolverFactory resolverFactory; private final CallContext callContext; private final PolarisResolutionManifestCatalogView resolvedEntityView; private final CatalogEntity catalogEntity; @@ -197,7 +197,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog */ public IcebergCatalog( StorageCredentialCache storageCredentialCache, - PolarisEntityManager entityManager, + ResolverFactory resolverFactory, PolarisMetaStoreManager metaStoreManager, CallContext callContext, PolarisResolutionManifestCatalogView resolvedEntityView, @@ -205,8 +205,8 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog TaskExecutor taskExecutor, FileIOFactory fileIOFactory, PolarisEventListener polarisEventListener) { - this.entityManager = entityManager; this.storageCredentialCache = storageCredentialCache; + this.resolverFactory = resolverFactory; this.callContext = callContext; this.resolvedEntityView = resolvedEntityView; this.catalogEntity = @@ -1208,7 +1208,7 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog siblingTables.size() + siblingNamespaces.size()); PolarisResolutionManifest resolutionManifest = new PolarisResolutionManifest( - callContext, entityManager, securityContext, parentPath.getFirst().getName()); + callContext, resolverFactory, securityContext, parentPath.getFirst().getName()); siblingTables.forEach( tbl -> resolutionManifest.addPath( 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 7218da0f3..ea84ca11e 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 @@ -68,6 +68,7 @@ import org.apache.polaris.core.persistence.PolarisEntityManager; import org.apache.polaris.core.persistence.PolarisMetaStoreManager; import org.apache.polaris.core.persistence.ResolvedPolarisEntity; import org.apache.polaris.core.persistence.resolver.Resolver; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.persistence.resolver.ResolverStatus; import org.apache.polaris.core.rest.PolarisEndpoints; import org.apache.polaris.core.secrets.UserSecretsManager; @@ -136,6 +137,7 @@ public class IcebergCatalogAdapter private final CallContext callContext; private final CallContextCatalogFactory catalogFactory; private final PolarisEntityManager entityManager; + private final ResolverFactory resolverFactory; private final PolarisMetaStoreManager metaStoreManager; private final UserSecretsManager userSecretsManager; private final PolarisAuthorizer polarisAuthorizer; @@ -149,6 +151,7 @@ public class IcebergCatalogAdapter CallContext callContext, CallContextCatalogFactory catalogFactory, PolarisEntityManager entityManager, + ResolverFactory resolverFactory, PolarisMetaStoreManager metaStoreManager, UserSecretsManager userSecretsManager, PolarisAuthorizer polarisAuthorizer, @@ -159,6 +162,7 @@ public class IcebergCatalogAdapter this.callContext = callContext; this.catalogFactory = catalogFactory; this.entityManager = entityManager; + this.resolverFactory = resolverFactory; this.metaStoreManager = metaStoreManager; this.userSecretsManager = userSecretsManager; this.polarisAuthorizer = polarisAuthorizer; @@ -771,7 +775,7 @@ public class IcebergCatalogAdapter if (warehouse == null) { throw new BadRequestException("Please specify a warehouse"); } - Resolver resolver = entityManager.prepareResolver(callContext, securityContext, warehouse); + Resolver resolver = resolverFactory.createResolver(callContext, securityContext, warehouse); ResolverStatus resolverStatus = resolver.resolveAll(); if (!resolverStatus.getStatus().equals(ResolverStatus.StatusEnum.SUCCESS)) { throw new NotFoundException("Unable to find warehouse %s", warehouse); diff --git a/service/common/src/main/java/org/apache/polaris/service/config/RealmEntityManagerFactory.java b/service/common/src/main/java/org/apache/polaris/service/config/RealmEntityManagerFactory.java index c7af1fa10..7c72625df 100644 --- a/service/common/src/main/java/org/apache/polaris/service/config/RealmEntityManagerFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/config/RealmEntityManagerFactory.java @@ -22,12 +22,10 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import org.apache.polaris.core.config.PolarisConfigurationStore; -import org.apache.polaris.core.config.RealmConfig; -import org.apache.polaris.core.config.RealmConfigImpl; import org.apache.polaris.core.context.RealmContext; import org.apache.polaris.core.persistence.MetaStoreManagerFactory; import org.apache.polaris.core.persistence.PolarisEntityManager; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,17 +36,16 @@ public class RealmEntityManagerFactory { private static final Logger LOGGER = LoggerFactory.getLogger(RealmEntityManagerFactory.class); private final MetaStoreManagerFactory metaStoreManagerFactory; - private final PolarisConfigurationStore configurationStore; + private final ResolverFactory resolverFactory; // Key: realmIdentifier private final Map<String, PolarisEntityManager> cachedEntityManagers = new ConcurrentHashMap<>(); @Inject public RealmEntityManagerFactory( - MetaStoreManagerFactory metaStoreManagerFactory, - PolarisConfigurationStore configurationStore) { + MetaStoreManagerFactory metaStoreManagerFactory, ResolverFactory resolverFactory) { this.metaStoreManagerFactory = metaStoreManagerFactory; - this.configurationStore = configurationStore; + this.resolverFactory = resolverFactory; } public PolarisEntityManager getOrCreateEntityManager(RealmContext context) { @@ -60,10 +57,8 @@ public class RealmEntityManagerFactory { realm, r -> { LOGGER.info("Initializing new PolarisEntityManager for realm {}", r); - RealmConfig realmConfig = new RealmConfigImpl(configurationStore, context); return new PolarisEntityManager( - metaStoreManagerFactory.getOrCreateMetaStoreManager(context), - metaStoreManagerFactory.getOrCreateEntityCache(context, realmConfig)); + metaStoreManagerFactory.getOrCreateMetaStoreManager(context), resolverFactory); }); } } diff --git a/service/common/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java b/service/common/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java index dd3c04ea8..16eb2edd3 100644 --- a/service/common/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java +++ b/service/common/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java @@ -30,12 +30,11 @@ import org.apache.polaris.core.context.CallContext; import org.apache.polaris.core.entity.CatalogEntity; import org.apache.polaris.core.entity.PolarisBaseEntity; 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.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.storage.cache.StorageCredentialCache; 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.events.PolarisEventListener; import org.apache.polaris.service.task.TaskExecutor; import org.slf4j.Logger; @@ -46,23 +45,23 @@ public class PolarisCallContextCatalogFactory implements CallContextCatalogFacto private static final Logger LOGGER = LoggerFactory.getLogger(PolarisCallContextCatalogFactory.class); - private final RealmEntityManagerFactory entityManagerFactory; private final TaskExecutor taskExecutor; private final FileIOFactory fileIOFactory; private final StorageCredentialCache storageCredentialCache; + private final ResolverFactory resolverFactory; private final MetaStoreManagerFactory metaStoreManagerFactory; private final PolarisEventListener polarisEventListener; @Inject public PolarisCallContextCatalogFactory( StorageCredentialCache storageCredentialCache, - RealmEntityManagerFactory entityManagerFactory, + ResolverFactory resolverFactory, MetaStoreManagerFactory metaStoreManagerFactory, TaskExecutor taskExecutor, FileIOFactory fileIOFactory, PolarisEventListener polarisEventListener) { - this.entityManagerFactory = entityManagerFactory; this.storageCredentialCache = storageCredentialCache; + this.resolverFactory = resolverFactory; this.metaStoreManagerFactory = metaStoreManagerFactory; this.taskExecutor = taskExecutor; this.fileIOFactory = fileIOFactory; @@ -83,13 +82,10 @@ public class PolarisCallContextCatalogFactory implements CallContextCatalogFacto String catalogKey = realm + "/" + catalogName; LOGGER.debug("Initializing new BasePolarisCatalog for key: {}", catalogKey); - PolarisEntityManager entityManager = - entityManagerFactory.getOrCreateEntityManager(context.getRealmContext()); - IcebergCatalog catalogInstance = new IcebergCatalog( storageCredentialCache, - entityManager, + resolverFactory, metaStoreManagerFactory.getOrCreateMetaStoreManager(context.getRealmContext()), context, resolvedManifest, 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 e0570794b..24fff244b 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 @@ -234,7 +234,7 @@ public class FileIOFactoryTest { IcebergCatalog polarisCatalog = new IcebergCatalog( services.storageCredentialCache(), - services.entityManagerFactory().getOrCreateEntityManager(realmContext), + services.resolverFactory(), services.metaStoreManagerFactory().getOrCreateMetaStoreManager(realmContext), callContext, passthroughView, 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 8384f6ee5..081eac40e 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,7 +44,10 @@ 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.cache.EntityCache; import org.apache.polaris.core.persistence.dao.entity.CreatePrincipalResult; +import org.apache.polaris.core.persistence.resolver.Resolver; +import org.apache.polaris.core.persistence.resolver.ResolverFactory; import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.secrets.UserSecretsManagerFactory; import org.apache.polaris.core.storage.cache.StorageCredentialCache; @@ -79,6 +82,7 @@ public record TestServices( PolarisConfigurationStore configurationStore, PolarisDiagnostics polarisDiagnostics, StorageCredentialCache storageCredentialCache, + ResolverFactory resolverFactory, RealmEntityManagerFactory entityManagerFactory, MetaStoreManagerFactory metaStoreManagerFactory, RealmContext realmContext, @@ -155,11 +159,11 @@ public record TestServices( InMemoryPolarisMetaStoreManagerFactory metaStoreManagerFactory = new InMemoryPolarisMetaStoreManagerFactory( storageIntegrationProvider, polarisDiagnostics); + StorageCredentialCacheConfig storageCredentialCacheConfig = () -> 10_000; StorageCredentialCache storageCredentialCache = new StorageCredentialCache(storageCredentialCacheConfig); - RealmEntityManagerFactory realmEntityManagerFactory = - new RealmEntityManagerFactory(metaStoreManagerFactory, configurationStore); + UserSecretsManagerFactory userSecretsManagerFactory = new UnsafeInMemorySecretsManagerFactory(); @@ -172,10 +176,26 @@ public record TestServices( polarisDiagnostics, configurationStore, Clock.systemUTC()); - PolarisEntityManager entityManager = - realmEntityManagerFactory.getOrCreateEntityManager(realmContext); + PolarisMetaStoreManager metaStoreManager = metaStoreManagerFactory.getOrCreateMetaStoreManager(realmContext); + + EntityCache entityCache = + metaStoreManagerFactory.getOrCreateEntityCache( + realmContext, callContext.getRealmConfig()); + ResolverFactory resolverFactory = + (_callContext, securityContext, referenceCatalogName) -> + new Resolver( + _callContext.getPolarisCallContext(), + metaStoreManager, + securityContext, + entityCache, + referenceCatalogName); + + RealmEntityManagerFactory realmEntityManagerFactory = + new RealmEntityManagerFactory(metaStoreManagerFactory, resolverFactory); + PolarisEntityManager entityManager = + realmEntityManagerFactory.getOrCreateEntityManager(realmContext); UserSecretsManager userSecretsManager = userSecretsManagerFactory.getOrCreateUserSecretsManager(realmContext); @@ -188,7 +208,7 @@ public record TestServices( CallContextCatalogFactory callContextFactory = new PolarisCallContextCatalogFactory( storageCredentialCache, - realmEntityManagerFactory, + resolverFactory, metaStoreManagerFactory, taskExecutor, fileIOFactory, @@ -205,6 +225,7 @@ public record TestServices( callContext, callContextFactory, entityManager, + resolverFactory, metaStoreManager, userSecretsManager, authorizer, @@ -269,6 +290,7 @@ public record TestServices( configurationStore, polarisDiagnostics, storageCredentialCache, + resolverFactory, realmEntityManagerFactory, metaStoreManagerFactory, realmContext,