diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogUtils.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogUtils.java new file mode 100644 index 0000000000..6c0d8d82ac --- /dev/null +++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/common/CatalogUtils.java @@ -0,0 +1,48 @@ +/* + * 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.common; + +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.polaris.core.entity.PolarisEntitySubType; +import org.apache.polaris.core.entity.PolarisEntityType; +import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; +import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifestCatalogView; + +/** Utility methods for working with Polaris catalog entities. */ +public class CatalogUtils { + + /** + * Find the resolved entity path that may contain storage information + * + * @param resolvedEntityView The resolved entity view containing catalog entities. + * @param tableIdentifier The table identifier for which to find storage information. + * @return The resolved path wrapper that may contain storage information. + */ + public static PolarisResolvedPathWrapper findResolvedStorageEntity( + PolarisResolutionManifestCatalogView resolvedEntityView, TableIdentifier tableIdentifier) { + PolarisResolvedPathWrapper resolvedTableEntities = + resolvedEntityView.getResolvedPath( + tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); + if (resolvedTableEntities != null) { + return resolvedTableEntities; + } + return resolvedEntityView.getResolvedPath(tableIdentifier.namespace()); + } +} diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java index 0399b0d375..10ac47b438 100644 --- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java +++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalog.java @@ -121,14 +121,12 @@ 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; -import org.apache.polaris.core.storage.PolarisCredentialVendor; import org.apache.polaris.core.storage.PolarisStorageActions; import org.apache.polaris.core.storage.PolarisStorageConfigurationInfo; import org.apache.polaris.core.storage.StorageLocation; import org.apache.polaris.core.storage.StorageUtil; -import org.apache.polaris.core.storage.cache.StorageCredentialCache; import org.apache.polaris.service.catalog.SupportsNotifications; +import org.apache.polaris.service.catalog.common.CatalogUtils; import org.apache.polaris.service.catalog.common.LocationUtils; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.FileIOUtil; @@ -143,7 +141,7 @@ /** Defines the relationship between PolarisEntities and Iceberg's business logic. */ public class IcebergCatalog extends BaseMetastoreViewCatalog - implements SupportsNamespaces, SupportsNotifications, Closeable, SupportsCredentialDelegation { + implements SupportsNamespaces, SupportsNotifications, Closeable { private static final Logger LOGGER = LoggerFactory.getLogger(IcebergCatalog.class); private static final Joiner SLASH = Joiner.on("/"); @@ -163,7 +161,6 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog }; private final PolarisDiagnostics diagnostics; - private final StorageCredentialCache storageCredentialCache; private final ResolverFactory resolverFactory; private final CallContext callContext; private final RealmConfig realmConfig; @@ -194,7 +191,6 @@ public class IcebergCatalog extends BaseMetastoreViewCatalog */ public IcebergCatalog( PolarisDiagnostics diagnostics, - StorageCredentialCache storageCredentialCache, ResolverFactory resolverFactory, PolarisMetaStoreManager metaStoreManager, CallContext callContext, @@ -204,7 +200,6 @@ public IcebergCatalog( FileIOFactory fileIOFactory, PolarisEventListener polarisEventListener) { this.diagnostics = diagnostics; - this.storageCredentialCache = storageCredentialCache; this.resolverFactory = resolverFactory; this.callContext = callContext; this.realmConfig = callContext.getRealmConfig(); @@ -385,7 +380,9 @@ public boolean dropTable(TableIdentifier tableIdentifier, boolean purge) { lastMetadata = null; } - Optional storageInfoEntity = findStorageInfo(tableIdentifier); + Optional storageInfoEntity = + FileIOUtil.findStorageInfoFromHierarchy( + CatalogUtils.findResolvedStorageEntity(resolvedEntityView, tableIdentifier)); // The storageProperties we stash away in the Task should be the superset of the // internalProperties of the StorageInfoEntity to be able to use its StorageIntegration @@ -831,31 +828,6 @@ public boolean sendNotification( PolarisEntitySubType.ICEBERG_TABLE, identifier, notificationRequest); } - @Override - public AccessConfig getAccessConfig( - TableIdentifier tableIdentifier, - TableMetadata tableMetadata, - Set storageActions, - Optional refreshCredentialsEndpoint) { - Optional storageInfo = findStorageInfo(tableIdentifier); - if (storageInfo.isEmpty()) { - LOGGER - .atWarn() - .addKeyValue("tableIdentifier", tableIdentifier) - .log("Table entity has no storage configuration in its hierarchy"); - return AccessConfig.builder().supportsCredentialVending(false).build(); - } - return FileIOUtil.refreshAccessConfig( - callContext, - storageCredentialCache, - getCredentialVendor(), - tableIdentifier, - StorageUtil.getLocationsUsedByTable(tableMetadata), - storageActions, - storageInfo.get(), - refreshCredentialsEndpoint); - } - private String buildPrefixedLocation(TableIdentifier tableIdentifier) { StringBuilder locationBuilder = new StringBuilder(); locationBuilder.append(defaultBaseLocation); @@ -961,19 +933,6 @@ public String transformTableLikeLocation(TableIdentifier tableIdentifier, String tableIdentifier, applyReplaceNewLocationWithCatalogDefault(location)); } - private @Nonnull Optional findStorageInfo(TableIdentifier tableIdentifier) { - PolarisResolvedPathWrapper resolvedTableEntities = - resolvedEntityView.getResolvedPath( - tableIdentifier, PolarisEntityType.TABLE_LIKE, PolarisEntitySubType.ICEBERG_TABLE); - - PolarisResolvedPathWrapper resolvedStorageEntity = - resolvedTableEntities == null - ? resolvedEntityView.getResolvedPath(tableIdentifier.namespace()) - : resolvedTableEntities; - - return FileIOUtil.findStorageInfoFromHierarchy(resolvedStorageEntity); - } - /** * Validates that the specified {@code location} is valid for whatever storage config is found for * this TableLike's parent hierarchy. @@ -2130,10 +2089,6 @@ private PolarisMetaStoreManager getMetaStoreManager() { return metaStoreManager; } - private PolarisCredentialVendor getCredentialVendor() { - return metaStoreManager; - } - @VisibleForTesting public void setFileIOFactory(FileIOFactory newFactory) { this.fileIOFactory = newFactory; diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java index 38f1fbb4b6..a54c4f3cf9 100644 --- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java +++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java @@ -82,6 +82,7 @@ import org.apache.polaris.service.catalog.api.IcebergRestCatalogApiService; import org.apache.polaris.service.catalog.api.IcebergRestConfigurationApiService; import org.apache.polaris.service.catalog.common.CatalogAdapter; +import org.apache.polaris.service.catalog.io.AccessConfigProvider; import org.apache.polaris.service.config.ReservedProperties; import org.apache.polaris.service.context.catalog.CallContextCatalogFactory; import org.apache.polaris.service.events.listeners.PolarisEventListener; @@ -154,6 +155,7 @@ public class IcebergCatalogAdapter private final CatalogHandlerUtils catalogHandlerUtils; private final Instance externalCatalogFactories; private final PolarisEventListener polarisEventListener; + private final AccessConfigProvider accessConfigProvider; @Inject public IcebergCatalogAdapter( @@ -170,7 +172,8 @@ public IcebergCatalogAdapter( ReservedProperties reservedProperties, CatalogHandlerUtils catalogHandlerUtils, @Any Instance externalCatalogFactories, - PolarisEventListener polarisEventListener) { + PolarisEventListener polarisEventListener, + AccessConfigProvider accessConfigProvider) { this.diagnostics = diagnostics; this.realmContext = realmContext; this.callContext = callContext; @@ -186,6 +189,7 @@ public IcebergCatalogAdapter( this.catalogHandlerUtils = catalogHandlerUtils; this.externalCatalogFactories = externalCatalogFactories; this.polarisEventListener = polarisEventListener; + this.accessConfigProvider = accessConfigProvider; } /** @@ -225,7 +229,8 @@ IcebergCatalogHandler newHandlerWrapper(SecurityContext securityContext, String reservedProperties, catalogHandlerUtils, externalCatalogFactories, - polarisEventListener); + polarisEventListener, + accessConfigProvider); } @Override diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java index 03a5881c8d..7d94538143 100644 --- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java +++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java @@ -100,9 +100,12 @@ import org.apache.polaris.core.secrets.UserSecretsManager; import org.apache.polaris.core.storage.AccessConfig; import org.apache.polaris.core.storage.PolarisStorageActions; +import org.apache.polaris.core.storage.StorageUtil; import org.apache.polaris.service.catalog.AccessDelegationMode; import org.apache.polaris.service.catalog.SupportsNotifications; import org.apache.polaris.service.catalog.common.CatalogHandler; +import org.apache.polaris.service.catalog.common.CatalogUtils; +import org.apache.polaris.service.catalog.io.AccessConfigProvider; import org.apache.polaris.service.config.ReservedProperties; import org.apache.polaris.service.context.catalog.CallContextCatalogFactory; import org.apache.polaris.service.events.listeners.PolarisEventListener; @@ -135,6 +138,7 @@ public class IcebergCatalogHandler extends CatalogHandler implements AutoCloseab private final ReservedProperties reservedProperties; private final CatalogHandlerUtils catalogHandlerUtils; private final PolarisEventListener polarisEventListener; + private final AccessConfigProvider accessConfigProvider; // Catalog instance will be initialized after authorizing resolver successfully resolves // the catalog entity. @@ -158,7 +162,8 @@ public IcebergCatalogHandler( ReservedProperties reservedProperties, CatalogHandlerUtils catalogHandlerUtils, Instance externalCatalogFactories, - PolarisEventListener polarisEventListener) { + PolarisEventListener polarisEventListener, + AccessConfigProvider accessConfigProvider) { super( diagnostics, callContext, @@ -173,6 +178,7 @@ public IcebergCatalogHandler( this.reservedProperties = reservedProperties; this.catalogHandlerUtils = catalogHandlerUtils; this.polarisEventListener = polarisEventListener; + this.accessConfigProvider = accessConfigProvider; } private CatalogEntity getResolvedCatalogEntity() { @@ -793,16 +799,19 @@ private LoadTableResponse.Builder buildLoadTableResponseWithDelegationCredential Optional refreshCredentialsEndpoint) { LoadTableResponse.Builder responseBuilder = LoadTableResponse.builder().withTableMetadata(tableMetadata); + PolarisResolvedPathWrapper resolvedStoragePath = + CatalogUtils.findResolvedStorageEntity(resolutionManifest, tableIdentifier); + + if (baseCatalog instanceof IcebergCatalog && resolvedStoragePath != null) { - if (baseCatalog instanceof SupportsCredentialDelegation credentialDelegation) { - LOGGER - .atDebug() - .addKeyValue("tableIdentifier", tableIdentifier) - .addKeyValue("tableLocation", tableMetadata.location()) - .log("Fetching client credentials for table"); AccessConfig accessConfig = - credentialDelegation.getAccessConfig( - tableIdentifier, tableMetadata, actions, refreshCredentialsEndpoint); + accessConfigProvider.getAccessConfig( + callContext, + tableIdentifier, + StorageUtil.getLocationsUsedByTable(tableMetadata), + actions, + refreshCredentialsEndpoint, + resolvedStoragePath); Map credentialConfig = accessConfig.credentials(); if (delegationModes.contains(VENDED_CREDENTIALS)) { if (!credentialConfig.isEmpty()) { diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java deleted file mode 100644 index b85973ed8e..0000000000 --- a/runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/SupportsCredentialDelegation.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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.iceberg; - -import java.util.Optional; -import java.util.Set; -import org.apache.iceberg.TableMetadata; -import org.apache.iceberg.catalog.TableIdentifier; -import org.apache.polaris.core.storage.AccessConfig; -import org.apache.polaris.core.storage.PolarisStorageActions; - -/** - * Adds support for credential vending for (typically) {@link org.apache.iceberg.TableOperations} to - * fetch access credentials that are inserted into the {@link - * org.apache.iceberg.rest.responses.LoadTableResponse#config()} property. See the - * rest-catalog-open-api.yaml spec for details on the expected format of vended credential - * configuration. - */ -public interface SupportsCredentialDelegation { - AccessConfig getAccessConfig( - TableIdentifier tableIdentifier, - TableMetadata tableMetadata, - Set storageActions, - Optional refreshCredentialsEndpoint); -} diff --git a/runtime/service/src/main/java/org/apache/polaris/service/catalog/io/AccessConfigProvider.java b/runtime/service/src/main/java/org/apache/polaris/service/catalog/io/AccessConfigProvider.java new file mode 100644 index 0000000000..d336040273 --- /dev/null +++ b/runtime/service/src/main/java/org/apache/polaris/service/catalog/io/AccessConfigProvider.java @@ -0,0 +1,104 @@ +/* + * 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.io; + +import jakarta.annotation.Nonnull; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.Optional; +import java.util.Set; +import org.apache.iceberg.catalog.TableIdentifier; +import org.apache.polaris.core.context.CallContext; +import org.apache.polaris.core.entity.PolarisEntity; +import org.apache.polaris.core.persistence.MetaStoreManagerFactory; +import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper; +import org.apache.polaris.core.storage.AccessConfig; +import org.apache.polaris.core.storage.PolarisStorageActions; +import org.apache.polaris.core.storage.cache.StorageCredentialCache; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Provides temporary, scoped credentials for accessing table data in object storage (S3, GCS, Azure + * Blob Storage). + * + *

This provider decouples credential vending from catalog implementations, and should be the + * primary entrypoint to get sub-scoped credentials for accessing table data. + */ +@ApplicationScoped +public class AccessConfigProvider { + + private static final Logger LOGGER = LoggerFactory.getLogger(AccessConfigProvider.class); + + private final StorageCredentialCache storageCredentialCache; + private final MetaStoreManagerFactory metaStoreManagerFactory; + + @Inject + public AccessConfigProvider( + StorageCredentialCache storageCredentialCache, + MetaStoreManagerFactory metaStoreManagerFactory) { + this.storageCredentialCache = storageCredentialCache; + this.metaStoreManagerFactory = metaStoreManagerFactory; + } + + /** + * Vends credentials for accessing table storage at explicit locations. + * + * @param callContext the call context containing realm, principal, and security context + * @param tableIdentifier the table identifier, used for logging and refresh endpoint construction + * @param tableLocations set of storage location URIs to scope credentials to + * @param storageActions the storage operations (READ, WRITE, LIST, DELETE) to scope credentials + * to + * @param refreshCredentialsEndpoint optional endpoint URL for clients to refresh credentials + * @param resolvedPath the entity hierarchy to search for storage configuration + * @return {@link AccessConfig} with scoped credentials and metadata; empty if no storage config + * found + */ + public AccessConfig getAccessConfig( + @Nonnull CallContext callContext, + @Nonnull TableIdentifier tableIdentifier, + @Nonnull Set tableLocations, + @Nonnull Set storageActions, + @Nonnull Optional refreshCredentialsEndpoint, + @Nonnull PolarisResolvedPathWrapper resolvedPath) { + LOGGER + .atDebug() + .addKeyValue("tableIdentifier", tableIdentifier) + .addKeyValue("tableLocation", tableLocations) + .log("Fetching client credentials for table"); + Optional storageInfo = FileIOUtil.findStorageInfoFromHierarchy(resolvedPath); + if (storageInfo.isEmpty()) { + LOGGER + .atWarn() + .addKeyValue("tableIdentifier", tableIdentifier) + .log("Table entity has no storage configuration in its hierarchy"); + return AccessConfig.builder().supportsCredentialVending(false).build(); + } + return FileIOUtil.refreshAccessConfig( + callContext, + storageCredentialCache, + metaStoreManagerFactory.getOrCreateMetaStoreManager(callContext.getRealmContext()), + tableIdentifier, + tableLocations, + storageActions, + storageInfo.get(), + refreshCredentialsEndpoint); + } +} diff --git a/runtime/service/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java b/runtime/service/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java index 342d7d7744..c9dcbefaee 100644 --- a/runtime/service/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java +++ b/runtime/service/src/main/java/org/apache/polaris/service/context/catalog/PolarisCallContextCatalogFactory.java @@ -32,7 +32,6 @@ import org.apache.polaris.core.persistence.MetaStoreManagerFactory; 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.events.listeners.PolarisEventListener; @@ -48,7 +47,6 @@ public class PolarisCallContextCatalogFactory implements CallContextCatalogFacto private final PolarisDiagnostics diagnostics; private final TaskExecutor taskExecutor; private final FileIOFactory fileIOFactory; - private final StorageCredentialCache storageCredentialCache; private final ResolverFactory resolverFactory; private final MetaStoreManagerFactory metaStoreManagerFactory; private final PolarisEventListener polarisEventListener; @@ -56,14 +54,12 @@ public class PolarisCallContextCatalogFactory implements CallContextCatalogFacto @Inject public PolarisCallContextCatalogFactory( PolarisDiagnostics diagnostics, - StorageCredentialCache storageCredentialCache, ResolverFactory resolverFactory, MetaStoreManagerFactory metaStoreManagerFactory, TaskExecutor taskExecutor, FileIOFactory fileIOFactory, PolarisEventListener polarisEventListener) { this.diagnostics = diagnostics; - this.storageCredentialCache = storageCredentialCache; this.resolverFactory = resolverFactory; this.metaStoreManagerFactory = metaStoreManagerFactory; this.taskExecutor = taskExecutor; @@ -87,7 +83,6 @@ public Catalog createCallContextCatalog( IcebergCatalog catalogInstance = new IcebergCatalog( diagnostics, - storageCredentialCache, resolverFactory, metaStoreManagerFactory.getOrCreateMetaStoreManager(context.getRealmContext()), context, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java index 4eb9b0f46e..245e65d123 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/admin/PolarisAuthzTestBase.java @@ -90,6 +90,7 @@ import org.apache.polaris.service.catalog.generic.PolarisGenericTableCatalog; import org.apache.polaris.service.catalog.iceberg.CatalogHandlerUtils; import org.apache.polaris.service.catalog.iceberg.IcebergCatalog; +import org.apache.polaris.service.catalog.io.AccessConfigProvider; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.policy.PolicyCatalog; import org.apache.polaris.service.config.ReservedProperties; @@ -204,6 +205,7 @@ public Map getConfigOverrides() { @Inject protected PolarisConfigurationStore configurationStore; @Inject protected StorageCredentialCache storageCredentialCache; @Inject protected ResolverFactory resolverFactory; + @Inject protected AccessConfigProvider accessConfigProvider; protected IcebergCatalog baseCatalog; protected PolarisGenericTableCatalog genericTableCatalog; @@ -527,7 +529,6 @@ private void initBaseCatalog() { this.baseCatalog = new IcebergCatalog( diagServices, - storageCredentialCache, resolverFactory, metaStoreManager, callContext, @@ -567,7 +568,6 @@ public TestPolarisCallContextCatalogFactory( PolarisEventListener polarisEventListener) { super( diagnostics, - storageCredentialCache, resolverFactory, metaStoreManagerFactory, taskExecutor, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/generic/AbstractPolarisGenericTableCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/generic/AbstractPolarisGenericTableCatalogTest.java index 1d1071dfed..af2efded58 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/generic/AbstractPolarisGenericTableCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/generic/AbstractPolarisGenericTableCatalogTest.java @@ -239,7 +239,6 @@ public void before(TestInfo testInfo) { this.icebergCatalog = new IcebergCatalog( diagServices, - storageCredentialCache, resolverFactory, metaStoreManager, polarisContext, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogTest.java index 2418bcfcce..369a672520 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogTest.java @@ -448,7 +448,6 @@ protected IcebergCatalog newIcebergCatalog( TaskExecutor taskExecutor = Mockito.mock(TaskExecutor.class); return new IcebergCatalog( diagServices, - storageCredentialCache, resolverFactory, metaStoreManager, polarisContext, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogViewTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogViewTest.java index c4b68658a5..97c31cdb51 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogViewTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/AbstractIcebergCatalogViewTest.java @@ -215,7 +215,6 @@ public void before(TestInfo testInfo) { this.catalog = new IcebergCatalog( diagServices, - storageCredentialCache, resolverFactory, metaStoreManager, polarisContext, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerAuthzTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerAuthzTest.java index 0a5f063e2c..b187e148e4 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerAuthzTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerAuthzTest.java @@ -134,7 +134,8 @@ private IcebergCatalogHandler newWrapper( reservedProperties, catalogHandlerUtils, emptyExternalCatalogFactory(), - polarisEventListener); + polarisEventListener, + accessConfigProvider); } protected void doTestInsufficientPrivileges( @@ -273,7 +274,8 @@ public void testInsufficientPermissionsPriorToSecretRotation() { reservedProperties, catalogHandlerUtils, emptyExternalCatalogFactory(), - polarisEventListener); + polarisEventListener, + accessConfigProvider); // a variety of actions are all disallowed because the principal's credentials must be rotated doTestInsufficientPrivileges( @@ -310,7 +312,8 @@ public void testInsufficientPermissionsPriorToSecretRotation() { reservedProperties, catalogHandlerUtils, emptyExternalCatalogFactory(), - polarisEventListener); + polarisEventListener, + accessConfigProvider); doTestSufficientPrivilegeSets( List.of(Set.of(PolarisPrivilege.NAMESPACE_LIST)), @@ -1189,7 +1192,8 @@ public T getConfig(PolarisConfiguration config, CatalogEntity catalogEnti reservedProperties, catalogHandlerUtils, emptyExternalCatalogFactory(), - polarisEventListener); + polarisEventListener, + accessConfigProvider); } @Test @@ -1892,7 +1896,6 @@ public void testSendNotificationSufficientPrivileges() { PolarisCallContextCatalogFactory factory = new PolarisCallContextCatalogFactory( diagServices, - storageCredentialCache, resolverFactory, managerFactory, Mockito.mock(), diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java index 0e97197949..2378d19580 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandlerFineGrainedDisabledTest.java @@ -70,7 +70,8 @@ private IcebergCatalogHandler newWrapper() { reservedProperties, catalogHandlerUtils, emptyExternalCatalogFactory(), - polarisEventListener); + polarisEventListener, + accessConfigProvider); } public static class Profile extends PolarisAuthzTestBase.Profile { diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java index d966aeae6e..d36e9a74fe 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/io/FileIOFactoryTest.java @@ -222,7 +222,6 @@ IcebergCatalog createCatalog(TestServices services, String scheme) { IcebergCatalog polarisCatalog = new IcebergCatalog( services.polarisDiagnostics(), - services.storageCredentialCache(), services.resolverFactory(), services.metaStoreManager(), callContext, diff --git a/runtime/service/src/test/java/org/apache/polaris/service/catalog/policy/AbstractPolicyCatalogTest.java b/runtime/service/src/test/java/org/apache/polaris/service/catalog/policy/AbstractPolicyCatalogTest.java index 9da8260eb3..f430e2bffd 100644 --- a/runtime/service/src/test/java/org/apache/polaris/service/catalog/policy/AbstractPolicyCatalogTest.java +++ b/runtime/service/src/test/java/org/apache/polaris/service/catalog/policy/AbstractPolicyCatalogTest.java @@ -256,7 +256,6 @@ public void before(TestInfo testInfo) { this.icebergCatalog = new IcebergCatalog( diagServices, - storageCredentialCache, resolverFactory, metaStoreManager, polarisContext, diff --git a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java index d118e52e9d..ffc71c0c56 100644 --- a/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java +++ b/runtime/service/src/testFixtures/java/org/apache/polaris/service/TestServices.java @@ -68,6 +68,7 @@ import org.apache.polaris.service.catalog.api.IcebergRestConfigurationApi; import org.apache.polaris.service.catalog.iceberg.CatalogHandlerUtils; import org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter; +import org.apache.polaris.service.catalog.io.AccessConfigProvider; import org.apache.polaris.service.catalog.io.FileIOFactory; import org.apache.polaris.service.catalog.io.MeasuredFileIOFactory; import org.apache.polaris.service.config.ReservedProperties; @@ -104,7 +105,8 @@ public record TestServices( PolarisMetaStoreManager metaStoreManager, FileIOFactory fileIOFactory, TaskExecutor taskExecutor, - PolarisEventListener polarisEventListener) { + PolarisEventListener polarisEventListener, + AccessConfigProvider accessConfigProvider) { private static final RealmContext TEST_REALM = () -> "test-realm"; private static final String GCP_ACCESS_TOKEN = "abc"; @@ -230,13 +232,15 @@ public TestServices build() { CallContextCatalogFactory callContextFactory = new PolarisCallContextCatalogFactory( diagnostics, - storageCredentialCache, resolverFactory, metaStoreManagerFactory, taskExecutor, fileIOFactory, polarisEventListener); + AccessConfigProvider accessConfigProvider = + new AccessConfigProvider(storageCredentialCache, metaStoreManagerFactory); + ReservedProperties reservedProperties = ReservedProperties.NONE; CatalogHandlerUtils catalogHandlerUtils = new CatalogHandlerUtils(realmConfig); @@ -261,7 +265,8 @@ public TestServices build() { reservedProperties, catalogHandlerUtils, externalCatalogFactory, - polarisEventListener); + polarisEventListener, + accessConfigProvider); IcebergRestCatalogApi restApi = new IcebergRestCatalogApi(catalogService); IcebergRestConfigurationApi restConfigurationApi = @@ -334,7 +339,8 @@ public String getAuthenticationScheme() { metaStoreManager, fileIOFactory, taskExecutor, - polarisEventListener); + polarisEventListener, + accessConfigProvider); } }