Skip to content

Commit

Permalink
Connect new correlators to synchronization service
Browse files Browse the repository at this point in the history
We now call new Correlator SPI in the main synchronization code path.
Work in progress: the old code is still used at some other places.

Unrelated change:
- Fixed task=null in ModelObjectResolver
  • Loading branch information
mederly committed Jan 13, 2022
1 parent adb2fc6 commit f64d90d
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

import com.evolveum.midpoint.util.DebugDumpable;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType;

import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand All @@ -27,17 +28,17 @@ public class CorrelationResult implements Serializable, DebugDumpable {
@NotNull private final Status status;

/**
* Reference to the correlated owner. Non-null if and only if {@link #status} is {@link Status#EXISTING_OWNER}.
* The correlated owner. Non-null if and only if {@link #status} is {@link Status#EXISTING_OWNER}.
*/
@Nullable private final ObjectReferenceType ownerRef;
@Nullable private final ObjectType owner;

private CorrelationResult(@NotNull Status status, @Nullable ObjectReferenceType ownerRef) {
private CorrelationResult(@NotNull Status status, @Nullable ObjectType owner) {
this.status = status;
this.ownerRef = ownerRef;
this.owner = owner;
}

public static CorrelationResult existingOwner(@NotNull ObjectReferenceType ownerRef) {
return new CorrelationResult(Status.EXISTING_OWNER, ownerRef);
public static CorrelationResult existingOwner(@NotNull ObjectType owner) {
return new CorrelationResult(Status.EXISTING_OWNER, owner);
}

public static CorrelationResult noOwner() {
Expand All @@ -52,17 +53,17 @@ public static CorrelationResult uncertain() {
return status;
}

public @Nullable ObjectReferenceType getOwnerRef() {
return ownerRef;
public @Nullable ObjectType getOwner() {
return owner;
}

@Override
public String debugDump(int indent) {
StringBuilder sb = DebugUtil.createTitleStringBuilderLn(getClass(), indent);
DebugUtil.debugDumpWithLabel(sb, "status", status, indent + 1);
if (ownerRef != null) {
if (owner != null) {
sb.append("\n");
DebugUtil.debugDumpWithLabel(sb, "ownerRef", String.valueOf(ownerRef), indent + 1);
DebugUtil.debugDumpWithLabel(sb, "owner", String.valueOf(owner), indent + 1);
}
return sb.toString();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ public <O extends ObjectType, R extends ObjectType> PrismObject<R> searchOrgTree
if (orgRefValue != null) {

try {
PrismObject<OrgType> org = resolve(orgRefValue, "resolving parent org ref", null, null, result);
PrismObject<OrgType> org = resolve(orgRefValue, "resolving parent org ref", null, task, result);
orgs.add(org);
ObjectReferenceType ref = function.apply(org);

Expand Down Expand Up @@ -315,7 +315,7 @@ public <R, O extends ObjectType> R searchOrgTreeWidthFirst(PrismObject<O> object
if (orgRefValue != null) {

try {
PrismObject<OrgType> org = resolve(orgRefValue, "resolving parent org ref", null, null, result);
PrismObject<OrgType> org = resolve(orgRefValue, "resolving parent org ref", null, task, result);
orgs.add(org);
R val = function.apply(org);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,11 @@
import org.jetbrains.annotations.NotNull;

import com.evolveum.midpoint.model.api.correlator.CorrelationResult;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;

public class CorrelatorUtil {

@NotNull
public static CorrelationResult getCorrelationResultFromObjects(List<? extends ObjectType> candidates) {
if (candidates.isEmpty()) {
return CorrelationResult.noOwner();
} else if (candidates.size() == 1) {
return CorrelationResult.existingOwner(
ObjectTypeUtil.createObjectRef(candidates.get(0)));
} else {
return CorrelationResult.uncertain();
}
}

@NotNull
public static CorrelationResult getCorrelationResultFromReferences(List<ObjectReferenceType> candidates) {
public static CorrelationResult createCorrelationResult(List<? extends ObjectType> candidates) {
if (candidates.isEmpty()) {
return CorrelationResult.noOwner();
} else if (candidates.size() == 1) {
Expand All @@ -66,7 +53,7 @@ public static <F extends ObjectType> void addCandidates(List<F> allCandidates, L
}
}

private static <F extends ObjectType> boolean containsOid(List<F> allCandidates, String oid) {
public static <F extends ObjectType> boolean containsOid(List<F> allCandidates, String oid) {
for (F existing : allCandidates) {
if (existing.getOid().equals(oid)) {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
import com.evolveum.midpoint.repo.common.expression.Expression;
import com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext;
import com.evolveum.midpoint.schema.constants.ExpressionConstants;
import com.evolveum.midpoint.schema.constants.ObjectTypes;
import com.evolveum.midpoint.schema.expression.ExpressionProfile;
import com.evolveum.midpoint.schema.expression.VariablesMap;
import com.evolveum.midpoint.schema.result.OperationResult;
import com.evolveum.midpoint.schema.util.MiscSchemaUtil;
import com.evolveum.midpoint.schema.util.ObjectTypeUtil;
import com.evolveum.midpoint.task.api.Task;
import com.evolveum.midpoint.util.DebugUtil;
import com.evolveum.midpoint.util.MiscUtil;
Expand Down Expand Up @@ -76,11 +76,11 @@ public CorrelationResult correlate(
resourceObject.debugDumpLazily(1),
correlationContext.debugDumpLazily(1));

return new Correlation(resourceObject, correlationContext, task)
return new Correlation<>(resourceObject, correlationContext, task)
.execute(result);
}

private class Correlation {
private class Correlation<F extends ObjectType> {

@NotNull private final ShadowType resourceObject;
@NotNull private final CorrelationContext correlationContext;
Expand All @@ -106,11 +106,11 @@ private class Correlation {
public CorrelationResult execute(OperationResult result)
throws SchemaException, ExpressionEvaluationException, CommunicationException, SecurityViolationException,
ConfigurationException, ObjectNotFoundException {
return CorrelatorUtil.getCorrelationResultFromReferences(
return CorrelatorUtil.createCorrelationResult(
findCandidatesUsingExpressions(result));
}

private @NotNull List<ObjectReferenceType> findCandidatesUsingExpressions(OperationResult result)
private @NotNull List<F> findCandidatesUsingExpressions(OperationResult result)
throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, CommunicationException,
ConfigurationException, SecurityViolationException {

Expand Down Expand Up @@ -147,10 +147,10 @@ public CorrelationResult execute(OperationResult result)
.evaluateAnyExpressionInContext(expression, params, task, result);
LOGGER.trace("Correlation expression returned:\n{}", DebugUtil.debugDumpLazily(outputTriple, 1));

List<ObjectReferenceType> allCandidates = new ArrayList<>();
List<F> allCandidates = new ArrayList<>();
if (outputTriple != null) {
for (PrismValue candidateValue : outputTriple.getNonNegativeValues()) {
addCandidateOwner(allCandidates, candidateValue);
addCandidateOwner(allCandidates, candidateValue, result);
}
}

Expand All @@ -161,42 +161,65 @@ public CorrelationResult execute(OperationResult result)
return allCandidates;
}

private void addCandidateOwner(List<ObjectReferenceType> allCandidates, PrismValue candidateValue)
throws SchemaException {
private void addCandidateOwner(List<F> allCandidates, PrismValue candidateValue, OperationResult result)
throws SchemaException, ObjectNotFoundException {
if (candidateValue == null) {
return;
}
ObjectReferenceType reference;
F candidateOwner;
if (candidateValue instanceof PrismObjectValue) {
reference = ObjectTypeUtil.createObjectRef(((PrismObjectValue<?>) candidateValue).asPrismObject());
//noinspection unchecked
candidateOwner = ((PrismObjectValue<F>) candidateValue).asObjectable();
if (containsOid(allCandidates, candidateValue, candidateOwner.getOid())) {
return;
}
} else if (candidateValue instanceof PrismReferenceValue) {
reference = ObjectTypeUtil.createObjectRef((PrismReferenceValue) candidateValue);
// We first check for duplicates to avoid needless resolution of the reference
PrismReferenceValue candidateOwnerRef = (PrismReferenceValue) candidateValue;
if (containsOid(allCandidates, candidateValue, candidateOwnerRef.getOid())) {
return;
}
candidateOwner = resolveReference(candidateOwnerRef, result);
} else {
throw new IllegalStateException("Unexpected return value " + MiscUtil.getValueWithClass(candidateValue)
+ " from correlation script in " + contextDescription);
}
allCandidates.add(candidateOwner);
}

String oid = reference.getOid();
/** Does some checking/logging besides OID presence checking. */
private boolean containsOid(List<F> allCandidates, PrismValue candidateValue, String oid) throws SchemaException {
if (oid == null) {
// Or other kind of exception?
throw new SchemaException("No OID found in value returned from correlation script. Value: "
+ candidateValue + " in: " + contextDescription);
}
if (containsReferenceWithOid(allCandidates, oid)) {
if (CorrelatorUtil.containsOid(allCandidates, oid)) {
LOGGER.trace("Candidate owner {} already processed", candidateValue);
return true;
} else {
LOGGER.trace("Adding {} to the list of candidate owners", candidateValue);
allCandidates.add(reference);
return false;
}
}

private boolean containsReferenceWithOid(List<ObjectReferenceType> allCandidates, String oid) {
for (ObjectReferenceType existing : allCandidates) {
if (existing.getOid().equals(oid)) {
return true;
}
private F resolveReference(PrismReferenceValue candidateOwnerRef, OperationResult result)
throws SchemaException, ObjectNotFoundException {
Class<? extends ObjectType> type;
if (candidateOwnerRef.getTargetType() != null) {
type = ObjectTypes.getObjectTypeClass(candidateOwnerRef.getTargetType());
} else {
type = correlationContext.getFocusType();
}
try {
//noinspection unchecked
return beans.cacheRepositoryService
.getObject((Class<F>) type, candidateOwnerRef.getOid(), null, result)
.asObjectable();
} catch (Exception e) {
MiscUtil.throwAsSame(e, "Couldn't resolve OID returned by correlation expression: " + e.getMessage());
throw e; // to make compiler happy
}
return false;
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public CorrelationResult execute(OperationResult result)
List<F> confirmedCandidates = confirmCandidates(candidates, result);
// TODO selection expression

return CorrelatorUtil.getCorrelationResultFromObjects(confirmedCandidates);
return CorrelatorUtil.createCorrelationResult(confirmedCandidates);
}

private @NotNull List<F> findCandidatesUsingConditionalFilters(OperationResult result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.util.List;
import javax.xml.namespace.QName;

import com.evolveum.midpoint.prism.util.CloneUtil;
import com.evolveum.midpoint.schema.processor.ResourceObjectTypeDefinition;
import com.evolveum.midpoint.model.impl.ModelBeans;
import com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription;
Expand Down Expand Up @@ -95,6 +96,9 @@ public class SynchronizationContext<F extends FocusType> implements DebugDumpabl
private String intent;
private String tag;

/** Definition of corresponding object type (currently found by kind+intent). Lazily evaluated. TODO reconsider. */
private ResourceObjectTypeDefinition objectTypeDefinition;

private boolean reactionEvaluated = false;
private SynchronizationReactionType reaction;

Expand Down Expand Up @@ -158,6 +162,15 @@ public String getIntent() throws SchemaException {
return intent;
}

// TODO reconsider
public @NotNull ResourceObjectTypeDefinition getObjectTypeDefinition() throws SchemaException, ConfigurationException {
if (objectTypeDefinition == null) {
objectTypeDefinition = ResourceSchemaFactory.getCompleteSchemaRequired(resource.asObjectable())
.findObjectTypeDefinitionRequired(getKind(), getIntent());
}
return objectTypeDefinition;
}

public String getTag() {
return tag;
}
Expand All @@ -174,6 +187,21 @@ public ExpressionType getConfirmation() {
return objectSynchronization.getConfirmation();
}

// TODO reconsider cloning here
public @NotNull CorrelatorsType getCorrelators() {
if (objectSynchronization.getCorrelationDefinition() != null) {
return objectSynchronization.getCorrelationDefinition().clone();
}
CorrelatorsType correlators =
new CorrelatorsType(PrismContext.get())
.beginFilter()
.confirmation(CloneUtil.clone(objectSynchronization.getConfirmation()))
.end();
correlators.getFilter().get(0).getFilter().addAll(
CloneUtil.cloneCollectionMembers(objectSynchronization.getCorrelation()));
return correlators;
}

public ObjectReferenceType getObjectTemplateRef() {
if (reaction.getObjectTemplateRef() != null) {
return reaction.getObjectTemplateRef();
Expand Down

0 comments on commit f64d90d

Please sign in to comment.