From c63687f40988227190a1f63991f0242e758cfb3c Mon Sep 17 00:00:00 2001 From: Radovan Semancik Date: Fri, 24 Apr 2020 17:55:42 +0200 Subject: [PATCH] Outbound multiaccounts WIP (MID-6242) --- .../schema/ResourceShadowDiscriminator.java | 24 ++++--- .../api/context/EvaluatedConstruction.java | 18 +++++- .../model/impl/lens/Construction.java | 38 +++++++++-- .../impl/lens/EvaluatedConstructionImpl.java | 63 ++++++++++--------- 4 files changed, 98 insertions(+), 45 deletions(-) diff --git a/infra/schema/src/main/java/com/evolveum/midpoint/schema/ResourceShadowDiscriminator.java b/infra/schema/src/main/java/com/evolveum/midpoint/schema/ResourceShadowDiscriminator.java index 2a68b48606a..eaf05bcbb15 100644 --- a/infra/schema/src/main/java/com/evolveum/midpoint/schema/ResourceShadowDiscriminator.java +++ b/infra/schema/src/main/java/com/evolveum/midpoint/schema/ResourceShadowDiscriminator.java @@ -12,10 +12,7 @@ import javax.xml.namespace.QName; import com.evolveum.midpoint.schema.constants.SchemaConstants; -import com.evolveum.midpoint.util.DebugDumpable; -import com.evolveum.midpoint.util.DebugUtil; -import com.evolveum.midpoint.util.HumanReadableDescribable; -import com.evolveum.midpoint.util.PrettyPrinter; +import com.evolveum.midpoint.util.*; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowDiscriminatorType; @@ -35,7 +32,7 @@ * * @author Radovan Semancik */ -public class ResourceShadowDiscriminator implements Serializable, DebugDumpable, HumanReadableDescribable { +public class ResourceShadowDiscriminator implements Serializable, DebugDumpable, ShortDumpable, HumanReadableDescribable { private static final long serialVersionUID = 346600684011645741L; private String resourceOid; @@ -286,12 +283,11 @@ public String toString() { } @Override - public String toHumanReadableDescription() { - return toHumanReadableDescription(true); + public void shortDump(StringBuilder sb) { + shortDump(sb, true); } - public String toHumanReadableDescription(boolean writeOid) { - StringBuilder sb = new StringBuilder("RSD("); + private void shortDump(StringBuilder sb, boolean writeOid) { sb.append(kind==null?"null":kind.value()); sb.append(" (").append(intent); if (tag != null) { @@ -312,6 +308,16 @@ public String toHumanReadableDescription(boolean writeOid) { if (tombstone) { sb.append(" TOMBSTONE"); } + } + + @Override + public String toHumanReadableDescription() { + return toHumanReadableDescription(true); + } + + public String toHumanReadableDescription(boolean writeOid) { + StringBuilder sb = new StringBuilder("RSD("); + shortDump(sb, writeOid); sb.append(")"); return sb.toString(); } diff --git a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedConstruction.java b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedConstruction.java index 24c3da52304..625e5fc69d8 100644 --- a/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedConstruction.java +++ b/model/model-api/src/main/java/com/evolveum/midpoint/model/api/context/EvaluatedConstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2015 Evolveum and contributors + * Copyright (c) 2010-2020 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. @@ -11,18 +11,32 @@ import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + /** - * @author mederly + * Facade interface that provides insight about construction that was evaluted by projector code. + * It is used for several purposes, e.g. to display all evaluated assignments, both direct and indirect. + * + * WARNING: Implementation of this interface are NOT required to be Serializable. + * They contain "live" data used by projector computation. + * Do NOT store this object in web session. * + * @author mederly + * @author Radovan Semancik */ public interface EvaluatedConstruction extends DebugDumpable { PrismObject getResource(); + @NotNull ShadowKindType getKind(); String getIntent(); + @Nullable + String getTag(); + boolean isDirectlyAssigned(); AssignmentPath getAssignmentPath(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java index 202c648aa8a..c4429423574 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/Construction.java @@ -12,6 +12,8 @@ import java.util.Objects; import javax.xml.namespace.QName; +import com.evolveum.midpoint.prism.delta.DeltaSetTriple; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -64,6 +66,7 @@ public class Construction extends AbstractConst private static final String OP_EVALUATE = Construction.class.getName() + ".evaluate"; private ObjectType orderOneObject; + private String resourceOid; private ResolvedResource resolvedResource; private ExpressionProfile expressionProfile; private MappingFactory mappingFactory; @@ -75,7 +78,11 @@ public class Construction extends AbstractConst private AssignmentPathVariables assignmentPathVariables = null; private PrismContainerDefinition associationContainerDefinition; private PrismObject systemConfiguration; // only to provide $configuration variable (MID-2372) - private LensProjectionContext projectionContext; + + private DeltaSetTriple> evaluatedConstructionTriple; + + // TODO: remove + public Construction(ConstructionType constructionType, ObjectType source) { super(constructionType, source); @@ -320,6 +327,7 @@ public void evaluate(Task task, OperationResult parentResult) ResourceType resource = resolveResource(task, result); if (resource != null) { evaluateKindIntentObjectClass(resource, task, result); + createEvaluatedConstructions(task, result); evaluateAttributes(task, result); evaluateAssociations(task, result); result.recordSuccess(); @@ -338,7 +346,6 @@ public void evaluate(Task task, OperationResult parentResult) } private void evaluateKindIntentObjectClass(ResourceType resource, Task task, OperationResult result) throws SchemaException, ConfigurationException, ObjectNotFoundException, CommunicationException, SecurityViolationException, ExpressionEvaluationException { - String resourceOid; if (getConstructionType().getResourceRef() != null) { resourceOid = getConstructionType().getResourceRef().getOid(); if (resourceOid != null && !resource.getOid().equals(resourceOid)) { @@ -385,14 +392,28 @@ private void evaluateKindIntentObjectClass(ResourceType resource, Task task, Ope auxiliaryObjectClassDefinitions.add(auxOcDef); } + } + + private void createEvaluatedConstructions(Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { PrismValueDeltaSetTriple> tagTriple = evaluateTagTripe(task, result); LOGGER.info("XXXX: tagTriple\n{}", DebugUtil.debugDump(tagTriple)); - ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, kind, getConstructionType().getIntent(), null, false); - projectionContext = getLensContext().findProjectionContext(rsd); - // projection context may not exist yet (existence might not be yet decided) + evaluatedConstructionTriple = getPrismContext().deltaFactory().createDeltaSetTriple(); + + if (tagTriple == null) { + // Singleaccount case (not multiaccount). We just create a simple EvaluatedConstruction + EvaluatedConstructionImpl evaluatedConstruction = createEvaluatedConstruction(null); + evaluatedConstructionTriple.addToZeroSet(evaluatedConstruction); + + } else { + + tagTriple.transform(evaluatedConstructionTriple, tag -> createEvaluatedConstruction(tag.getRealValue())); + } + + LOGGER.info("XXXX: evaluatedConstructionTriple\n{}", DebugUtil.debugDump(evaluatedConstructionTriple)); } + private PrismValueDeltaSetTriple> evaluateTagTripe(Task task, OperationResult result) throws CommunicationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, ExpressionEvaluationException { ResourceObjectMultiplicityType multiplicity = refinedObjectClassDefinition.getMultiplicity(); if (!RefinedDefinitionUtil.isMultiaccount(multiplicity)) { @@ -424,6 +445,13 @@ private PrismValueDeltaSetTriple> evaluateTagTripe(Ta return evaluatedMapping.getOutputTriple(); } + private EvaluatedConstructionImpl createEvaluatedConstruction(String tag) { + ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, refinedObjectClassDefinition.getKind(), refinedObjectClassDefinition.getIntent(), tag, false); + EvaluatedConstructionImpl evaluatedConstruction = new EvaluatedConstructionImpl<>(this, rsd); + evaluatedConstruction.initialize(); + return evaluatedConstruction; + } + private void evaluateAttributes(Task task, OperationResult result) throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException, SecurityViolationException, ConfigurationException, CommunicationException { attributeMappings = new ArrayList<>(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedConstructionImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedConstructionImpl.java index b0488df0fa7..5ffa7461fe6 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedConstructionImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedConstructionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2017 Evolveum and contributors + * Copyright (c) 2010-2020 Evolveum and contributors * * This work is dual-licensed under the Apache License 2.0 * and European Union Public License. See LICENSE file for details. @@ -10,83 +10,88 @@ import com.evolveum.midpoint.model.api.context.AssignmentPath; import com.evolveum.midpoint.model.api.context.EvaluatedConstruction; import com.evolveum.midpoint.prism.PrismObject; +import com.evolveum.midpoint.schema.ResourceShadowDiscriminator; import com.evolveum.midpoint.util.DebugUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentHolderType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowKindType; +import org.jetbrains.annotations.NotNull; + /** * @author mederly */ -public class EvaluatedConstructionImpl implements EvaluatedConstruction { +public class EvaluatedConstructionImpl implements EvaluatedConstruction { + + @NotNull final private Construction construction; + @NotNull final private ResourceShadowDiscriminator rsd; - final private PrismObject resource; - final private ShadowKindType kind; - final private String intent; - final private boolean directlyAssigned; - final private AssignmentPath assignmentPath; - final private boolean weak; + private LensProjectionContext projectionContext; /** * @pre construction is already evaluated and not ignored (has resource) */ - EvaluatedConstructionImpl(Construction construction) { - resource = construction.getResource().asPrismObject(); - kind = construction.getKind(); - intent = construction.getIntent(); - assignmentPath = construction.getAssignmentPath(); - directlyAssigned = assignmentPath == null || assignmentPath.size() == 1; - weak = construction.isWeak(); + EvaluatedConstructionImpl(@NotNull final Construction construction, @NotNull final ResourceShadowDiscriminator rsd) { + this.construction = construction; + this.rsd = rsd; + } + + public void initialize() { + projectionContext = construction.getLensContext().findProjectionContext(rsd); + // projection context may not exist yet (existence might not be yet decided) } @Override public PrismObject getResource() { - return resource; + return construction.getResource().asPrismObject(); } @Override public ShadowKindType getKind() { - return kind; + return rsd.getKind(); } @Override public String getIntent() { - return intent; + return rsd.getIntent(); + } + + @Override + public String getTag() { + return rsd.getTag(); } @Override public boolean isDirectlyAssigned() { - return directlyAssigned; + return construction.getAssignmentPath() == null || construction.getAssignmentPath().size() == 1; } @Override public AssignmentPath getAssignmentPath() { - return assignmentPath; + return construction.getAssignmentPath(); } @Override public boolean isWeak() { - return weak; + return construction.isWeak(); } @Override public String debugDump(int indent) { StringBuilder sb = new StringBuilder(); DebugUtil.debugDumpLabelLn(sb, "EvaluatedConstruction", indent); - DebugUtil.debugDumpWithLabelLn(sb, "resource", resource, indent + 1); - DebugUtil.debugDumpWithLabelLn(sb, "kind", kind.value(), indent + 1); - DebugUtil.debugDumpWithLabelLn(sb, "intent", intent, indent + 1); - DebugUtil.debugDumpWithLabelLn(sb, "directlyAssigned", directlyAssigned, indent + 1); - DebugUtil.debugDumpWithLabel(sb, "weak", weak, indent + 1); + DebugUtil.debugDumpWithLabelShortDumpLn(sb, "discriminator", rsd, indent + 1); + DebugUtil.debugDumpWithLabelLn(sb, "construction", construction, indent + 1); + DebugUtil.debugDumpWithLabelToString(sb, "projectionContext", projectionContext, indent + 1); return sb.toString(); } @Override public String toString() { return "EvaluatedConstruction(" + - "resource=" + resource + - ", kind=" + kind + - ", intent='" + intent + + "discriminator=" + rsd + + ", construction=" + construction + + ", projectionContext='" + projectionContext + ')'; } }