in polaris-core/src/main/java/org/apache/polaris/core/persistence/resolver/Resolver.java [528:648]
private boolean bulkValidate(List<ResolvedPolarisEntity> toValidate) {
if (!polarisMetaStoreManager.requiresEntityReload()) {
return true;
}
// assume everything is good
boolean validationStatus = true;
// bulk validate
if (!toValidate.isEmpty()) {
// TODO: Provide configurable option to enforce bulk validation of *all* entities in a
// resolution pass, instead of only validating ones on "cache hit"; this would allow the same
// semantics as the transactional validation performed for methods like readEntityByName
// when PolarisMetaStoreManagerImpl uses PolarisEntityResolver in a read transaction.
List<PolarisEntityId> entityIds =
toValidate.stream()
.map(
resolvedEntity ->
new PolarisEntityId(
resolvedEntity.getEntity().getCatalogId(),
resolvedEntity.getEntity().getId()))
.collect(Collectors.toList());
// now get the current backend versions of all these entities
ChangeTrackingResult changeTrackingResult =
this.polarisMetaStoreManager.loadEntitiesChangeTracking(
this.polarisCallContext, entityIds);
// refresh any entity which is not fresh. If an entity is missing, reload it
Iterator<ResolvedPolarisEntity> entityIterator = toValidate.iterator();
Iterator<PolarisChangeTrackingVersions> versionIterator =
changeTrackingResult.getChangeTrackingVersions().iterator();
// determine the ones we need to reload or refresh and the ones which are up-to-date
while (entityIterator.hasNext()) {
// get resolved entity and associated versions
ResolvedPolarisEntity resolvedEntity = entityIterator.next();
PolarisChangeTrackingVersions versions = versionIterator.next();
PolarisBaseEntity entity = resolvedEntity.getEntity();
// refresh the resolved entity if the entity or grant records version is different
final ResolvedPolarisEntity refreshedResolvedEntity;
if (versions == null
|| entity.getEntityVersion() != versions.getEntityVersion()
|| entity.getGrantRecordsVersion() != versions.getGrantRecordsVersion()) {
// if null version we need to invalidate the cached entry since it has probably been
// dropped
if (versions == null) {
if (this.cache != null) {
this.cache.removeCacheEntry(resolvedEntity);
}
refreshedResolvedEntity = null;
} else {
// refresh that entity. If versions is null, it has been dropped
if (this.cache != null) {
refreshedResolvedEntity =
this.cache.getAndRefreshIfNeeded(
this.polarisCallContext,
entity,
versions.getEntityVersion(),
versions.getGrantRecordsVersion());
} else {
ResolvedEntityResult result =
this.polarisMetaStoreManager.refreshResolvedEntity(
this.polarisCallContext,
entity.getEntityVersion(),
entity.getGrantRecordsVersion(),
entity.getType(),
entity.getCatalogId(),
entity.getId());
refreshedResolvedEntity =
result.isSuccess()
? new ResolvedPolarisEntity(
this.polarisCallContext.getDiagServices(),
result.getEntity() != null ? result.getEntity() : entity,
result.getEntityGrantRecords() != null
? result.getEntityGrantRecords()
: resolvedEntity.getAllGrantRecords(),
result.getEntityGrantRecords() != null
? result.getGrantRecordsVersion()
: entity.getGrantRecordsVersion())
: null;
}
}
// get the refreshed entity
PolarisBaseEntity refreshedEntity =
(refreshedResolvedEntity == null) ? null : refreshedResolvedEntity.getEntity();
// if the entity has been removed, or its name has changed, or it was re-parented, or it
// was dropped, we will have to perform another pass
if (refreshedEntity == null
|| refreshedEntity.getParentId() != entity.getParentId()
|| refreshedEntity.isDropped() != entity.isDropped()
|| !refreshedEntity.getName().equals(entity.getName())) {
validationStatus = false;
}
// special cases: the set of principal roles or catalog roles which have been
// activated might change if usage grants to a principal or a principal role have
// changed. Hence, force another pass if we are in that scenario
if (entity.getTypeCode() == PolarisEntityType.PRINCIPAL.getCode()
|| entity.getTypeCode() == PolarisEntityType.PRINCIPAL_ROLE.getCode()) {
validationStatus = false;
}
} else {
// no need to refresh, it is up-to-date
refreshedResolvedEntity = resolvedEntity;
}
// if it was found, it has been resolved, so if there is another pass, we will not have to
// resolve it again
if (refreshedResolvedEntity != null) {
this.addToResolved(refreshedResolvedEntity);
}
}
}
// done, return final validation status
return validationStatus;
}