Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract resolution mechanisms from service implementations #514

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
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.PolarisResolutionManifest;
import org.apache.polaris.core.persistence.resolution.ResolutionManifest;
import org.apache.polaris.core.storage.cache.StorageCredentialCache;
import org.apache.polaris.service.catalog.BasePolarisCatalog;
import org.apache.polaris.service.catalog.PolarisPassthroughResolutionView;
Expand Down Expand Up @@ -385,7 +385,7 @@ public PolarisEntityManager getOrCreateEntityManager(RealmContext realmContext)
public Catalog createCallContextCatalog(
CallContext context,
AuthenticatedPolarisPrincipal authenticatedPolarisPrincipal,
final PolarisResolutionManifest resolvedManifest) {
ResolutionManifest resolvedManifest) {
// This depends on the BasePolarisCatalog allowing calling initialize multiple times
// to override the previous config.
Catalog catalog =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
import org.apache.polaris.core.entity.PrincipalEntity;
import org.apache.polaris.core.persistence.PolarisEntityManager;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest;
import org.apache.polaris.core.persistence.resolution.ResolutionManifest;
import org.apache.polaris.service.admin.PolarisAuthzTestBase;
import org.apache.polaris.service.catalog.io.DefaultFileIOFactory;
import org.apache.polaris.service.config.RealmEntityManagerFactory;
Expand Down Expand Up @@ -1688,7 +1688,7 @@ public PolarisEntityManager getOrCreateEntityManager(RealmContext realmContext)
public Catalog createCallContextCatalog(
CallContext context,
AuthenticatedPolarisPrincipal authenticatedPolarisPrincipal,
PolarisResolutionManifest resolvedManifest) {
ResolutionManifest resolvedManifest) {
Catalog catalog =
super.createCallContextCatalog(
context, authenticatedPolarisPrincipal, resolvedManifest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
package org.apache.polaris.service.catalog;

import java.util.Arrays;
import java.util.Set;
import org.apache.iceberg.catalog.Namespace;
import org.apache.iceberg.catalog.TableIdentifier;
import org.apache.polaris.core.auth.AuthenticatedPolarisPrincipal;
import org.apache.polaris.core.catalog.PolarisCatalogHelpers;
import org.apache.polaris.core.context.CallContext;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.entity.PolarisEntitySubType;
import org.apache.polaris.core.entity.PolarisEntityType;
import org.apache.polaris.core.persistence.EntityNotFoundException;
import org.apache.polaris.core.persistence.PolarisEntityManager;
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifest;
import org.apache.polaris.core.persistence.resolver.PolarisResolutionManifestCatalogView;
import org.apache.polaris.core.persistence.resolution.PolarisResolvedPathWrapper;
import org.apache.polaris.core.persistence.resolution.ResolutionManifest;
import org.apache.polaris.core.persistence.resolver.ResolverPath;

/**
Expand All @@ -39,7 +41,7 @@
* new single-use PolarisResolutionManifests for each desired resolved path without defining a fixed
* set of resolved entities that need to be checked against authorizable operations.
*/
public class PolarisPassthroughResolutionView implements PolarisResolutionManifestCatalogView {
public class PolarisPassthroughResolutionView implements ResolutionManifest {
private final PolarisEntityManager entityManager;
private final CallContext callContext;
private final AuthenticatedPolarisPrincipal authenticatedPrincipal;
Expand All @@ -58,86 +60,125 @@ public PolarisPassthroughResolutionView(

@Override
public PolarisResolvedPathWrapper getResolvedReferenceCatalogEntity() {
PolarisResolutionManifest manifest =
entityManager.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName);
manifest.resolveAll();
return manifest.getResolvedReferenceCatalogEntity();
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.buildResolved()
.getResolvedReferenceCatalogEntity();
}

@Override
public PolarisResolvedPathWrapper getResolvedPath(Object key) {
PolarisResolutionManifest manifest =
entityManager.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName);

if (key instanceof Namespace namespace) {
manifest.addPath(
new ResolverPath(Arrays.asList(namespace.levels()), PolarisEntityType.NAMESPACE),
namespace);
manifest.resolveAll();
return manifest.getResolvedPath(namespace);
} else {
throw new IllegalStateException(
String.format(
"Trying to getResolvedPath(key) for %s with class %s", key, key.getClass()));
public PolarisResolvedPathWrapper getResolvedPath(
Namespace namespace, boolean prependRootContainer) {
try {
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.addPath(
new ResolverPath(Arrays.asList(namespace.levels()), PolarisEntityType.NAMESPACE),
namespace)
.buildResolved()
.getResolvedPath(namespace, prependRootContainer);
} catch (EntityNotFoundException nf) {
return null;
}
}

@Override
public PolarisResolvedPathWrapper getResolvedPath(Object key, PolarisEntitySubType subType) {
PolarisResolutionManifest manifest =
entityManager.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName);

if (key instanceof TableIdentifier identifier) {
manifest.addPath(
new ResolverPath(
PolarisCatalogHelpers.tableIdentifierToList(identifier),
PolarisEntityType.TABLE_LIKE),
identifier);
manifest.resolveAll();
return manifest.getResolvedPath(identifier, subType);
} else {
throw new IllegalStateException(
String.format(
"Trying to getResolvedPath(key, subType) for %s with class %s and subType %s",
key, key.getClass(), subType));
public PolarisResolvedPathWrapper getResolvedPath(
TableIdentifier tableIdentifier, boolean prependRootContainer) {
try {
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.addPath(
new ResolverPath(
PolarisCatalogHelpers.tableIdentifierToList(tableIdentifier),
PolarisEntityType.TABLE_LIKE),
tableIdentifier)
.buildResolved()
.getResolvedPath(tableIdentifier, prependRootContainer);
} catch (EntityNotFoundException nf) {
return null;
}
}

@Override
public PolarisResolvedPathWrapper getPassthroughResolvedPath(Object key) {
PolarisResolutionManifest manifest =
entityManager.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName);
public PolarisResolvedPathWrapper getResolvedPath(
TableIdentifier tableIdentifier, PolarisEntitySubType subType, boolean prependRootContainer) {
try {
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.addPath(
new ResolverPath(
PolarisCatalogHelpers.tableIdentifierToList(tableIdentifier),
PolarisEntityType.TABLE_LIKE),
tableIdentifier)
.buildResolved()
.getResolvedPath(tableIdentifier, subType, prependRootContainer);
} catch (EntityNotFoundException nf) {
return null;
}
}

if (key instanceof Namespace namespace) {
manifest.addPassthroughPath(
new ResolverPath(Arrays.asList(namespace.levels()), PolarisEntityType.NAMESPACE),
namespace);
return manifest.getPassthroughResolvedPath(namespace);
} else {
throw new IllegalStateException(
String.format(
"Trying to getResolvedPath(key) for %s with class %s", key, key.getClass()));
@Override
public PolarisResolvedPathWrapper getPassthroughResolvedPath(Namespace namespace) {
try {
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.addPassthroughPath(
new ResolverPath(Arrays.asList(namespace.levels()), PolarisEntityType.NAMESPACE),
namespace)
.buildResolved()
.getPassthroughResolvedPath(namespace);
} catch (EntityNotFoundException nf) {
return null;
}
}

@Override
public PolarisResolvedPathWrapper getPassthroughResolvedPath(
Object key, PolarisEntitySubType subType) {
PolarisResolutionManifest manifest =
entityManager.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName);

if (key instanceof TableIdentifier identifier) {
manifest.addPassthroughPath(
new ResolverPath(
PolarisCatalogHelpers.tableIdentifierToList(identifier),
PolarisEntityType.TABLE_LIKE),
identifier);
return manifest.getPassthroughResolvedPath(identifier, subType);
} else {
throw new IllegalStateException(
String.format(
"Trying to getResolvedPath(key, subType) for %s with class %s and subType %s",
key, key.getClass(), subType));
TableIdentifier tableIdentifier, PolarisEntitySubType subType) {
try {
return entityManager
.prepareResolutionManifest(callContext, authenticatedPrincipal, catalogName)
.addPassthroughPath(
new ResolverPath(
PolarisCatalogHelpers.tableIdentifierToList(tableIdentifier),
PolarisEntityType.TABLE_LIKE),
tableIdentifier)
.buildResolved(subType)
.getPassthroughResolvedPath(tableIdentifier, subType);
} catch (EntityNotFoundException nf) {
return null;
}
}

@Override
public PolarisResolvedPathWrapper getResolvedPath(String name, boolean prependRootContainer) {
throw new UnsupportedOperationException();
}

@Override
public PolarisResolvedPathWrapper getResolvedTopLevelEntity(
String name, PolarisEntityType polarisEntityType) {
throw new UnsupportedOperationException();
}

@Override
public PolarisResolvedPathWrapper getResolvedRootContainerEntityAsPath() {
throw new UnsupportedOperationException();
}

@Override
public PolarisEntitySubType getLeafSubType(TableIdentifier tableIdentifier) {
throw new UnsupportedOperationException();
}

@Override
public Set<PolarisBaseEntity> getAllActivatedPrincipalRoleEntities() {
throw new UnsupportedOperationException();
}

@Override
public Set<PolarisBaseEntity> getAllActivatedCatalogRoleAndPrincipalRoles() {
throw new UnsupportedOperationException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@
import jakarta.inject.Inject;
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.context.RealmContext;
import org.apache.polaris.core.persistence.LocalPolarisMetaStoreManagerFactory;
import org.apache.polaris.core.persistence.PolarisMetaStoreManager;
import org.apache.polaris.core.persistence.PolarisMetaStoreSession;
import org.apache.polaris.core.persistence.local.LocalPolarisMetaStoreManagerFactory;
import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@
import org.apache.polaris.core.entity.PolarisGrantRecord;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
import org.apache.polaris.core.exceptions.AlreadyExistsException;
import org.apache.polaris.core.persistence.PolarisMetaStoreManagerImpl;
import org.apache.polaris.core.persistence.PolarisMetaStoreSession;
import org.apache.polaris.core.persistence.PrincipalSecretsGenerator;
import org.apache.polaris.core.persistence.RetryOnConcurrencyException;
import org.apache.polaris.core.persistence.impl.PolarisMetaStoreManagerImpl;
import org.apache.polaris.core.storage.PolarisStorageConfigurationInfo;
import org.apache.polaris.core.storage.PolarisStorageIntegration;
import org.apache.polaris.core.storage.PolarisStorageIntegrationProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@
import org.apache.polaris.core.PolarisDiagnostics;
import org.apache.polaris.core.entity.PolarisPrincipalSecrets;
import org.apache.polaris.core.persistence.BasePolarisMetaStoreManagerTest;
import org.apache.polaris.core.persistence.PolarisMetaStoreManagerImpl;
import org.apache.polaris.core.persistence.PolarisTestMetaStoreManager;
import org.apache.polaris.core.persistence.impl.PolarisMetaStoreManagerImpl;
import org.apache.polaris.jpa.models.ModelPrincipalSecrets;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import java.util.List;
import java.util.Set;
import org.apache.polaris.core.entity.PolarisBaseEntity;
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
import org.apache.polaris.core.persistence.resolution.PolarisResolvedPathWrapper;

/** Interface for invoking authorization checks. */
public interface PolarisAuthorizer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@
import org.apache.polaris.core.entity.PolarisEntityCore;
import org.apache.polaris.core.entity.PolarisGrantRecord;
import org.apache.polaris.core.entity.PolarisPrivilege;
import org.apache.polaris.core.persistence.PolarisResolvedPathWrapper;
import org.apache.polaris.core.persistence.ResolvedPolarisEntity;
import org.apache.polaris.core.persistence.resolution.PolarisResolvedPathWrapper;
import org.apache.polaris.core.persistence.resolution.ResolvedPolarisEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public enum PolarisEntitySubType {
// ANY_SUBTYPE is not stored but is used to indicate that any subtype entities should be
// returned, for example when doing a list operation or checking if a table like object of
// name X exists
ANY_SUBTYPE(-1, null),
ANY_SUBTYPE(-1, null, "Table or view"),
// 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);
NULL_SUBTYPE(0, null, "(null)"),
TABLE(2, PolarisEntityType.TABLE_LIKE, "Table"),
VIEW(3, PolarisEntityType.TABLE_LIKE, "View");

// to efficiently map the code of a subtype to its corresponding subtype enum, use a reverse
// array which is initialized below
Expand Down Expand Up @@ -63,10 +63,13 @@ public enum PolarisEntitySubType {
// parent type for this entity
private final PolarisEntityType parentType;

PolarisEntitySubType(int code, PolarisEntityType parentType) {
private final String readableName;

PolarisEntitySubType(int code, PolarisEntityType parentType, String readableName) {
// remember the id of this entity
this.code = code;
this.parentType = parentType;
this.readableName = readableName;
}

/**
Expand Down Expand Up @@ -111,4 +114,8 @@ public PolarisEntityType getParentType() {

return null;
}

public String readableName() {
return readableName;
}
}
Loading
Loading