in polaris-core/src/testFixtures/java/org/apache/polaris/core/persistence/PolarisTestMetaStoreManager.java [727:940]
void dropEntity(List<PolarisEntityCore> catalogPath, PolarisBaseEntity entityToDrop) {
// see if the entity exists
final boolean exists;
boolean hasChildren = false;
// check if it exists
PolarisBaseEntity entity =
polarisMetaStoreManager
.loadEntity(
this.polarisCallContext,
entityToDrop.getCatalogId(),
entityToDrop.getId(),
entityToDrop.getType())
.getEntity();
if (entity != null) {
EntityResult entityFound =
polarisMetaStoreManager.readEntityByName(
this.polarisCallContext,
catalogPath,
entity.getType(),
entity.getSubType(),
entity.getName());
exists = entityFound.isSuccess();
// if exists, see if empty
if (exists
&& (entity.getType() == PolarisEntityType.CATALOG
|| entity.getType() == PolarisEntityType.NAMESPACE)) {
// build path
List<PolarisEntityCore> path = new ArrayList<>();
if (catalogPath != null) {
path.addAll(catalogPath);
}
path.add(entityToDrop);
// get all children, cannot be null
List<EntityNameLookupRecord> children =
polarisMetaStoreManager
.listEntities(
this.polarisCallContext,
path,
PolarisEntityType.NAMESPACE,
PolarisEntitySubType.NULL_SUBTYPE)
.getEntities();
Assertions.assertThat(children).isNotNull();
if (children.isEmpty() && entity.getType() == PolarisEntityType.NAMESPACE) {
children =
polarisMetaStoreManager
.listEntities(
this.polarisCallContext,
path,
PolarisEntityType.TABLE_LIKE,
PolarisEntitySubType.ANY_SUBTYPE)
.getEntities();
Assertions.assertThat(children).isNotNull();
} else if (children.isEmpty()) {
children =
polarisMetaStoreManager
.listEntities(
this.polarisCallContext,
path,
PolarisEntityType.CATALOG_ROLE,
PolarisEntitySubType.ANY_SUBTYPE)
.getEntities();
Assertions.assertThat(children).isNotNull();
// if only one left, it can be dropped.
if (children.size() == 1) {
children.clear();
}
}
hasChildren = !children.isEmpty();
}
} else {
exists = false;
}
// load all the grants to ensure they are properly cleaned
final List<PolarisBaseEntity> granteeEntities;
final List<PolarisBaseEntity> securableEntities;
if (exists) {
granteeEntities =
new ArrayList<>(
polarisMetaStoreManager
.loadGrantsOnSecurable(this.polarisCallContext, entity)
.getEntities());
securableEntities =
new ArrayList<>(
polarisMetaStoreManager
.loadGrantsToGrantee(this.polarisCallContext, entity)
.getEntities());
} else {
granteeEntities = List.of();
securableEntities = List.of();
}
// now drop it
Map<String, String> cleanupProperties =
Map.of("taskId", String.valueOf(entity.getId()), "cleanupProperty", "cleanupValue");
DropEntityResult dropResult =
polarisMetaStoreManager.dropEntityIfExists(
this.polarisCallContext, catalogPath, entityToDrop, cleanupProperties, true);
// should have been dropped if exists
if (entityToDrop.cannotBeDroppedOrRenamed()) {
Assertions.assertThat(dropResult.isSuccess()).isFalse();
Assertions.assertThat(dropResult.failedBecauseNotEmpty()).isFalse();
Assertions.assertThat(dropResult.isEntityUnDroppable()).isTrue();
} else if (exists && hasChildren) {
Assertions.assertThat(dropResult.isSuccess()).isFalse();
Assertions.assertThat(dropResult.failedBecauseNotEmpty()).isTrue();
Assertions.assertThat(dropResult.isEntityUnDroppable()).isFalse();
} else if (entityToDrop.getType() == PolarisEntityType.POLICY) {
// When dropping policy with cleanup = true, we do not need cleanup task
Assertions.assertThat(dropResult.isSuccess()).isEqualTo(exists);
Assertions.assertThat(dropResult.failedBecauseNotEmpty()).isFalse();
Assertions.assertThat(dropResult.isEntityUnDroppable()).isFalse();
Assertions.assertThat(dropResult.getCleanupTaskId()).isNull();
} else {
Assertions.assertThat(dropResult.isSuccess()).isEqualTo(exists);
Assertions.assertThat(dropResult.failedBecauseNotEmpty()).isFalse();
Assertions.assertThat(dropResult.isEntityUnDroppable()).isFalse();
Assertions.assertThat(dropResult.getCleanupTaskId()).isNotNull();
PolarisBaseEntity cleanupTask =
polarisMetaStoreManager
.loadEntity(
this.polarisCallContext,
0L,
dropResult.getCleanupTaskId(),
PolarisEntityType.TASK)
.getEntity();
Assertions.assertThat(cleanupTask).isNotNull();
Assertions.assertThat(cleanupTask.getType()).isEqualTo(PolarisEntityType.TASK);
Assertions.assertThat(cleanupTask.getInternalProperties()).isNotNull();
Map<String, String> internalProperties =
PolarisObjectMapperUtil.deserializeProperties(
polarisCallContext, cleanupTask.getInternalProperties());
Assertions.assertThat(internalProperties).isEqualTo(cleanupProperties);
Map<String, String> properties =
PolarisObjectMapperUtil.deserializeProperties(
polarisCallContext, cleanupTask.getProperties());
Assertions.assertThat(properties).isNotNull();
Assertions.assertThat(properties.get(PolarisTaskConstants.TASK_DATA)).isNotNull();
PolarisBaseEntity droppedEntity =
PolarisObjectMapperUtil.deserialize(
polarisCallContext,
properties.get(PolarisTaskConstants.TASK_DATA),
PolarisBaseEntity.class);
Assertions.assertThat(droppedEntity).isNotNull();
Assertions.assertThat(droppedEntity.getId()).isEqualTo(entity.getId());
}
// verify gone if it was dropped
if (dropResult.isSuccess()) {
// should be found but deleted
PolarisBaseEntity entityAfterDrop =
polarisMetaStoreManager
.loadEntity(
this.polarisCallContext,
entityToDrop.getCatalogId(),
entityToDrop.getId(),
entityToDrop.getType())
.getEntity();
// ensure dropped
Assertions.assertThat(entityAfterDrop).isNull();
// should no longer exists
Assertions.assertThat(entity).isNotNull();
EntityResult entityFound =
polarisMetaStoreManager.readEntityByName(
this.polarisCallContext,
catalogPath,
entity.getType(),
entity.getSubType(),
entity.getName());
// should not be found
Assertions.assertThat(entityFound.getReturnStatus())
.isEqualTo(BaseResult.ReturnStatus.ENTITY_NOT_FOUND);
// make sure that the entity which was dropped is no longer referenced by a grant with any
// of the entity it was connected with before being dropped
for (PolarisBaseEntity connectedEntity : granteeEntities) {
LoadGrantsResult grantResult =
polarisMetaStoreManager.loadGrantsToGrantee(this.polarisCallContext, connectedEntity);
if (grantResult.isSuccess()) {
long cnt =
grantResult.getGrantRecords().stream()
.filter(gr -> gr.getSecurableId() == entityToDrop.getId())
.count();
Assertions.assertThat(cnt).isZero();
} else {
// special case when a catalog is dropped, the catalog_admin role is also dropped with it
Assertions.assertThat(
grantResult.getReturnStatus() == BaseResult.ReturnStatus.ENTITY_NOT_FOUND
&& entityToDrop.getType() == PolarisEntityType.CATALOG
&& connectedEntity.getType() == PolarisEntityType.CATALOG_ROLE
&& connectedEntity
.getName()
.equals(PolarisEntityConstants.getNameOfCatalogAdminRole()))
.isTrue();
}
}
for (PolarisBaseEntity connectedEntity : securableEntities) {
LoadGrantsResult grantResult =
polarisMetaStoreManager.loadGrantsOnSecurable(this.polarisCallContext, connectedEntity);
long cnt =
grantResult.getGrantRecords().stream()
.filter(gr -> gr.getGranteeId() == entityToDrop.getId())
.count();
Assertions.assertThat(cnt).isZero();
}
}
}