private SynchronizationPlan sortOnIdentifier()

in polaris-synchronizer/api/src/main/java/org/apache/polaris/tools/sync/polaris/planning/BaseStrategyPlanner.java [84:151]


  private <T> SynchronizationPlan<T> sortOnIdentifier(
          Collection<T> entitiesOnSource,
          Collection<T> entitiesOnTarget,
          boolean requiresOverwrites,
          Function<T, Object> entityIdentifierSupplier
  ) {
    Set<Object> sourceEntityIdentifiers = entitiesOnSource.stream().map(entityIdentifierSupplier).collect(Collectors.toSet());
    Set<Object> targetEntityIdentifiers = entitiesOnTarget.stream().map(entityIdentifierSupplier).collect(Collectors.toSet());

    SynchronizationPlan<T> plan = new SynchronizationPlan<>();

    for (T entityOnSource : entitiesOnSource) {
      Object sourceEntityId = entityIdentifierSupplier.apply(entityOnSource);

      if (targetEntityIdentifiers.contains(sourceEntityId)) {
        // If an entity with this identifier exists on both the source and the target

        if (strategy == Strategy.CREATE_ONLY) {
          // if the same entity identifier is on the source and target,
          // but we only permit creates, skip it
          plan.skipEntity(entityOnSource);
        } else {
          // if the same entity identifier is on the source and the target,
          // overwrite the one on the target with the one on the source

          if (requiresOverwrites) {
            // If the entity requires a drop-and-recreate to perform an overwrite.
            // some grant records can be "created" indefinitely even if they already exists, for example,
            // catalog roles can be assigned the same principal role many times
            plan.overwriteEntity(entityOnSource);
          } else {
            // if the entity is not a type that requires "overwriting" in the sense of
            // dropping and recreating, then just create it again
            plan.createEntity(entityOnSource);
          }
        }
      } else {
        // if the entity identifier only exists on the source, that means
        // we need to create it for the first time on the target
        plan.createEntity(entityOnSource);
      }
    }

    for (T entityOnTarget : entitiesOnTarget) {
      Object targetEntityId = entityIdentifierSupplier.apply(entityOnTarget);
      if (!sourceEntityIdentifiers.contains(targetEntityId)) {
        // if the entity exists on the target but doesn't exist on the source,
        // clean it up from the target

        // this is especially important for access control entities, as, for example,
        // we could have a scenario where a grant was revoked from a catalog role,
        // or a catalog role was revoked from a principal role, in which case the target
        // should reflect this change when the tool is run multiple times, because we don't
        // want to take chances with over-extending privileges

        if (strategy == Strategy.REPLICATE) {
          plan.removeEntity(entityOnTarget);
        } else {
          // skip children here because if we want to remove the entity
          // and then that means it does not exist on the source, so there are no child
          // entities to sync
          plan.skipEntityAndSkipChildren(entityOnTarget);
        }
      }
    }

    return plan;
  }