in service/common/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java [609:698]
public Optional<LoadTableResponse> loadTableWithAccessDelegationIfStale(
TableIdentifier tableIdentifier, IfNoneMatch ifNoneMatch, String snapshots) {
// Here we have a single method that falls through multiple candidate
// PolarisAuthorizableOperations because instead of identifying the desired operation up-front
// and
// failing the authz check if grants aren't found, we find the first most-privileged authz match
// and respond according to that.
PolarisAuthorizableOperation read =
PolarisAuthorizableOperation.LOAD_TABLE_WITH_READ_DELEGATION;
PolarisAuthorizableOperation write =
PolarisAuthorizableOperation.LOAD_TABLE_WITH_WRITE_DELEGATION;
Set<PolarisStorageActions> actionsRequested =
new HashSet<>(Set.of(PolarisStorageActions.READ, PolarisStorageActions.LIST));
try {
// TODO: Refactor to have a boolean-return version of the helpers so we can fallthrough
// easily.
authorizeBasicTableLikeOperationOrThrow(
write, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier);
actionsRequested.add(PolarisStorageActions.WRITE);
} catch (ForbiddenException e) {
authorizeBasicTableLikeOperationOrThrow(
read, PolarisEntitySubType.ICEBERG_TABLE, tableIdentifier);
}
PolarisResolvedPathWrapper catalogPath = resolutionManifest.getResolvedReferenceCatalogEntity();
callContext
.getPolarisCallContext()
.getDiagServices()
.checkNotNull(catalogPath, "No catalog available for loadTable request");
CatalogEntity catalogEntity = CatalogEntity.of(catalogPath.getRawLeafEntity());
PolarisConfigurationStore configurationStore =
callContext.getPolarisCallContext().getConfigurationStore();
LOGGER.info("Catalog type: {}", catalogEntity.getCatalogType());
LOGGER.info(
"allow external catalog credential vending: {}",
configurationStore.getConfiguration(
callContext.getPolarisCallContext(),
catalogEntity,
FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING));
if (catalogEntity
.getCatalogType()
.equals(org.apache.polaris.core.admin.model.Catalog.TypeEnum.EXTERNAL)
&& !configurationStore.getConfiguration(
callContext.getPolarisCallContext(),
catalogEntity,
FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING)) {
throw new ForbiddenException(
"Access Delegation is not enabled for this catalog. Please consult applicable "
+ "documentation for the catalog config property '%s' to enable this feature",
FeatureConfiguration.ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING.catalogConfig());
}
if (ifNoneMatch != null) {
// Perform freshness-aware table loading if caller specified ifNoneMatch.
IcebergTableLikeEntity tableEntity = getTableEntity(tableIdentifier);
if (tableEntity == null || tableEntity.getMetadataLocation() == null) {
LOGGER
.atWarn()
.addKeyValue("tableIdentifier", tableIdentifier)
.addKeyValue("tableEntity", tableEntity)
.log("Failed to getMetadataLocation to generate ETag when loading table");
} else {
// TODO: Refactor null-checking into the helper method once we create a more canonical
// interface for associate etags with entities.
String tableETag =
IcebergHttpUtil.generateETagForMetadataFileLocation(tableEntity.getMetadataLocation());
if (ifNoneMatch.anyMatch(tableETag)) {
return Optional.empty();
}
}
}
// TODO: Find a way for the configuration or caller to better express whether to fail or omit
// when data-access is specified but access delegation grants are not found.
Table table = baseCatalog.loadTable(tableIdentifier);
if (table instanceof BaseTable baseTable) {
TableMetadata tableMetadata = baseTable.operations().current();
return Optional.of(
buildLoadTableResponseWithDelegationCredentials(
tableIdentifier, tableMetadata, actionsRequested, snapshots)
.build());
} else if (table instanceof BaseMetadataTable) {
// metadata tables are loaded on the client side, return NoSuchTableException for now
throw new NoSuchTableException("Table does not exist: %s", tableIdentifier.toString());
}
throw new IllegalStateException("Cannot wrap catalog that does not produce BaseTable");
}