use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentProcessor method evaluateFocusMappings.
private <AH extends AssignmentHolderType> void evaluateFocusMappings(LensContext<AH> context, XMLGregorianCalendar now, LensFocusContext<AH> focusContext, DeltaSetTriple<EvaluatedAssignmentImpl<AH>> evaluatedAssignmentTriple, Task task, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, PolicyViolationException, ConfigurationException, SecurityViolationException, ObjectNotFoundException, CommunicationException {
OperationResult result = parentResult.subresult(OP_EVALUATE_FOCUS_MAPPINGS).setMinor().build();
try {
LOGGER.trace("Starting evaluation of assignment-held mappings");
ObjectDeltaObject<AH> focusOdoRelative = focusContext.getObjectDeltaObjectRelative();
List<AssignedFocusMappingEvaluationRequest> allRequests = new ArrayList<>();
for (EvaluatedAssignmentImpl<AH> evaluatedAssignment : evaluatedAssignmentTriple.getAllValues()) {
allRequests.addAll(evaluatedAssignment.getFocusMappingEvaluationRequests());
}
FocalMappingSetEvaluation.TripleCustomizer<?, ?> customizer = (triple, abstractRequest) -> {
if (triple == null) {
return null;
}
DeltaSetTriple<ItemValueWithOrigin<PrismValue, ItemDefinition<?>>> rv = prismContext.deltaFactory().createDeltaSetTriple();
AssignedFocusMappingEvaluationRequest request = (AssignedFocusMappingEvaluationRequest) abstractRequest;
// noinspection unchecked
EvaluatedAssignmentImpl<AH> evaluatedAssignment = (EvaluatedAssignmentImpl<AH>) request.getEvaluatedAssignment();
PlusMinusZero relativeMode = request.getRelativeMode();
Set<PlusMinusZero> presence = new HashSet<>();
PlusMinusZero resultingMode = null;
if (evaluatedAssignmentTriple.presentInPlusSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.PLUS, relativeMode);
presence.add(PlusMinusZero.PLUS);
}
if (evaluatedAssignmentTriple.presentInMinusSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.MINUS, relativeMode);
presence.add(PlusMinusZero.MINUS);
}
if (evaluatedAssignmentTriple.presentInZeroSet(evaluatedAssignment)) {
resultingMode = PlusMinusZero.compute(PlusMinusZero.ZERO, relativeMode);
presence.add(PlusMinusZero.ZERO);
}
LOGGER.trace("triple customizer: presence = {}, relativeMode = {}, resultingMode = {}", presence, relativeMode, resultingMode);
if (presence.isEmpty()) {
throw new IllegalStateException("Evaluated assignment is not present in any of plus/minus/zero sets " + "of the triple. Assignment = " + evaluatedAssignment + ", triple = " + triple);
} else if (presence.size() > 1) {
// TODO think about this
throw new IllegalStateException("Evaluated assignment is present in more than one plus/minus/zero sets " + "of the triple: " + presence + ". Assignment = " + evaluatedAssignment + ", triple = " + triple);
}
if (resultingMode != null) {
switch(resultingMode) {
case PLUS:
// MID-6403
rv.addAllToPlusSet(triple.getNonNegativeValues());
break;
case MINUS:
// MID-6403
rv.addAllToMinusSet(triple.getNonPositiveValues());
break;
case ZERO:
rv = triple;
break;
}
}
return rv;
};
FocalMappingSetEvaluation.EvaluatedMappingConsumer mappingConsumer = (mapping, abstractRequest) -> {
AssignedFocusMappingEvaluationRequest request = (AssignedFocusMappingEvaluationRequest) abstractRequest;
request.getEvaluatedAssignment().addFocusMapping(mapping);
};
TargetObjectSpecification<AH> targetSpecification = new FixedTargetSpecification<>(focusOdoRelative.getNewObject(), true);
MappingEvaluationEnvironment env = new MappingEvaluationEnvironment("focus mappings in assignments of " + focusContext.getHumanReadableName(), now, task);
FocalMappingSetEvaluation<AH, AH> mappingSetEvaluation = new FocalMappingSetEvaluationBuilder<AH, AH>().context(context).evaluationRequests(allRequests).phase(null).focusOdo(focusOdoRelative).targetSpecification(targetSpecification).tripleCustomizer(customizer).mappingConsumer(mappingConsumer).iteration(focusContext.getIteration()).iterationToken(focusContext.getIterationToken()).beans(beans).env(env).result(result).build();
mappingSetEvaluation.evaluateMappingsToTriples();
PathKeyedMap<DeltaSetTriple<ItemValueWithOrigin<?, ?>>> focusOutputTripleMap = mappingSetEvaluation.getOutputTripleMap();
logOutputTripleMap(focusOutputTripleMap);
DeltaSetTripleMapConsolidation<AH> consolidation = new DeltaSetTripleMapConsolidation<>(focusOutputTripleMap, focusOdoRelative.getNewObject(), focusOdoRelative.getObjectDelta(), context::primaryFocusItemDeltaExists, null, null, focusContext.getObjectDefinition(), env, beans, context, result);
consolidation.computeItemDeltas();
Collection<ItemDelta<?, ?>> focusDeltas = consolidation.getItemDeltas();
LOGGER.trace("Computed focus deltas: {}", focusDeltas);
focusContext.swallowToSecondaryDelta(focusDeltas);
focusContext.recompute();
} catch (Throwable t) {
result.recordFatalError(t.getMessage(), t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}
use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AbstractTestProjectorPersona method test100AssignRolePersonaAdminToJack.
@Test
public void test100AssignRolePersonaAdminToJack() throws Exception {
// GIVEN
Task task = getTestTask();
OperationResult result = task.getResult();
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.FULL);
LensContext<UserType> context = createUserLensContext();
fillContextWithUser(context, USER_JACK_OID, result);
ObjectDelta<UserType> focusDelta = createAssignmentAssignmentHolderDelta(UserType.class, USER_JACK_OID, getPersonaRoleOid(), RoleType.COMPLEX_TYPE, null, null, null, true);
addFocusDeltaToContext(context, focusDelta);
displayDumpable("Input context", context);
assertFocusModificationSanity(context);
rememberCounter(InternalCounters.SHADOW_FETCH_OPERATION_COUNT);
// WHEN
projector.project(context, "test", task, result);
// THEN
displayDumpable("Output context", context);
assertCounterIncrement(InternalCounters.SHADOW_FETCH_OPERATION_COUNT, 0);
assertSame(context.getFocusContext().getPrimaryDelta().getChangeType(), ChangeType.MODIFY);
assertSideEffectiveDeltasOnly(context.getFocusContext().getSecondaryDelta(), "user secondary delta", ActivationStatusType.ENABLED);
assertTrue("Unexpected projection changes", context.getProjectionContexts().isEmpty());
DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
assertNotNull("No evaluatedAssignmentTriple", evaluatedAssignmentTriple);
assertTrue("Unexpected evaluatedAssignmentTriple zero set", evaluatedAssignmentTriple.getZeroSet().isEmpty());
assertTrue("Unexpected evaluatedAssignmentTriple minus set", evaluatedAssignmentTriple.getMinusSet().isEmpty());
assertNotNull("No evaluatedAssignmentTriple plus set", evaluatedAssignmentTriple.getPlusSet());
assertEquals("Wrong size of evaluatedAssignmentTriple plus set", 1, evaluatedAssignmentTriple.getPlusSet().size());
EvaluatedAssignmentImpl<UserType> evaluatedAssignment = (EvaluatedAssignmentImpl<UserType>) evaluatedAssignmentTriple.getPlusSet().iterator().next();
displayDumpable("evaluatedAssignment", evaluatedAssignment);
assertNotNull("No evaluatedAssignment", evaluatedAssignment);
DeltaSetTriple<PersonaConstruction<UserType>> personaConstructionTriple = evaluatedAssignment.getPersonaConstructionTriple();
displayDumpable("personaConstructionTriple", personaConstructionTriple);
assertNotNull("No personaConstructionTriple", personaConstructionTriple);
assertFalse("Empty personaConstructionTriple", personaConstructionTriple.isEmpty());
assertTrue("Unexpected personaConstructionTriple plus set", personaConstructionTriple.getPlusSet().isEmpty());
assertTrue("Unexpected personaConstructionTriple minus set", personaConstructionTriple.getMinusSet().isEmpty());
assertNotNull("No personaConstructionTriple zero set", personaConstructionTriple.getZeroSet());
assertEquals("Wrong size of personaConstructionTriple zero set", 1, personaConstructionTriple.getZeroSet().size());
PersonaConstruction<UserType> personaConstruction = personaConstructionTriple.getZeroSet().iterator().next();
assertNotNull("No personaConstruction", personaConstruction);
PersonaConstructionType personaConstructionType = personaConstruction.getConstructionBean();
assertNotNull("No personaConstructionType", personaConstructionType);
assertTrue("Wrong type: " + personaConstructionType.getTargetType(), QNameUtil.match(UserType.COMPLEX_TYPE, personaConstructionType.getTargetType()));
assertPersonaSubtypeOrArchetype(personaConstructionType);
}
use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class TestAssignmentProcessor method test200AssignVisitor.
/**
* NOTE: These two tests are legacy. They should be placed in TestPolicyRules. Please do not add
* any similar tests here; use {@link TestPolicyRules} instead. It contains better 'assume' methods for policies.
*
* TODO move these ones as well
*
* ===============================================================================================
*
* Checking approval policy rules.
* Visitor has a generic metarole that has associated policy rule (approve-any-corp-role).
* Generic metarole also induces metarole-sod-notifications that has "notify-exclusion-violations" rule.
*/
@Test
public void test200AssignVisitor() throws Exception {
given();
Task task = getTestTask();
OperationResult result = task.getResult();
LensContext<UserType> context = createUserLensContext();
PrismObject<UserType> user = getUser(USER_JACK_OID);
AssignmentType assignment = new AssignmentType(prismContext);
assignment.setTargetRef(ObjectTypeUtil.createObjectRef(ROLE_CORP_VISITOR_OID, ObjectTypes.ROLE));
fillContextWithFocus(context, user);
addFocusDeltaToContext(context, prismContext.deltaFor(UserType.class).item(UserType.F_ASSIGNMENT).add(assignment).asObjectDelta(USER_JACK_OID));
recompute(context);
displayDumpable("Input context", context);
assertFocusModificationSanity(context);
when();
processAssignments(task, result, context);
then();
// DebugUtil.setDetailedDebugDump(true);
displayDumpable("Output context", context);
display("outbound processor result", result);
// assertSuccess("Outbound processor failed (result)", result);
assertSame(context.getFocusContext().getPrimaryDelta().getChangeType(), ChangeType.MODIFY);
assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta());
assertFalse("No account changes", context.getProjectionContexts().isEmpty());
DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
assertEquals("Wrong # of added assignments", 1, evaluatedAssignmentTriple.getPlusSet().size());
displayValue("Policy rules", context.dumpAssignmentPolicyRules(3));
EvaluatedAssignmentImpl<?> evaluatedAssignment = evaluatedAssignmentTriple.getPlusSet().iterator().next();
assertEquals("Wrong # of focus policy rules", 0, evaluatedAssignment.getFocusPolicyRules().size());
Collection<? extends EvaluatedPolicyRule> targetPolicyRules = evaluatedAssignment.getAllTargetsPolicyRules();
assertEquals("Wrong # of target policy rules", 2, targetPolicyRules.size());
assertSerializable(context);
}
use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentProcessor method processOrgAssignments.
@SuppressWarnings("unused")
@ProcessorMethod
<F extends ObjectType> void processOrgAssignments(LensContext<F> context, XMLGregorianCalendar now, Task task, OperationResult result) throws SchemaException, PolicyViolationException {
LensFocusContext<F> focusContext = context.getFocusContext();
Collection<PrismReferenceValue> shouldBeParentOrgRefs = new ArrayList<>();
DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
if (evaluatedAssignmentTriple == null) {
// could be if "assignments" step is skipped
return;
}
for (EvaluatedAssignmentImpl<?> evalAssignment : evaluatedAssignmentTriple.getNonNegativeValues()) {
// MID-6403
if (evalAssignment.isValid()) {
addReferences(shouldBeParentOrgRefs, evalAssignment.getOrgRefVals());
}
}
setReferences(focusContext, ObjectType.F_PARENT_ORG_REF, shouldBeParentOrgRefs);
ObjectDelta<F> focusPrimaryDelta = focusContext.getPrimaryDelta();
if (focusPrimaryDelta != null) {
ReferenceDelta parentOrgRefDelta = focusPrimaryDelta.findReferenceModification(ObjectType.F_PARENT_ORG_REF);
if (parentOrgRefDelta != null) {
List<PrismReferenceValue> parentOrgRefCurrentValues = null;
PrismObject<F> objectCurrent = focusContext.getObjectCurrent();
if (objectCurrent != null) {
PrismReference parentOrgRefCurrent = objectCurrent.findReference(ObjectType.F_PARENT_ORG_REF);
if (parentOrgRefCurrent != null) {
parentOrgRefCurrentValues = parentOrgRefCurrent.getValues();
}
}
try {
parentOrgRefDelta.validateValues((plusMinusZero, val) -> {
switch(plusMinusZero) {
case PLUS:
case ZERO:
if (!PrismValueCollectionsUtil.containsRealValue(shouldBeParentOrgRefs, val)) {
throw new TunnelException(new PolicyViolationException("Attempt to add parentOrgRef " + val.getOid() + ", but it is not allowed by assignments"));
}
break;
case MINUS:
if (PrismValueCollectionsUtil.containsRealValue(shouldBeParentOrgRefs, val)) {
throw new TunnelException(new PolicyViolationException("Attempt to delete parentOrgRef " + val.getOid() + ", but it is mandated by assignments"));
}
break;
}
}, parentOrgRefCurrentValues);
} catch (TunnelException e) {
throw (PolicyViolationException) e.getCause();
}
}
}
computeTenantRef(context);
}
use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentProcessor method distributeConstructions.
private <AH extends AssignmentHolderType> void distributeConstructions(LensContext<AH> context, DeltaSetTriple<EvaluatedAssignmentImpl<AH>> evaluatedAssignmentTriple, Task task, OperationResult parentResult) throws ObjectNotFoundException, SchemaException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
ComplexConstructionConsumer<ResourceShadowDiscriminator, EvaluatedAssignedResourceObjectConstructionImpl<AH>> consumer = new ComplexConstructionConsumer<>() {
private boolean processOnlyExistingProjContexts;
@Override
public boolean before(ResourceShadowDiscriminator rsd) {
if (rsd.getResourceOid() == null) {
throw new IllegalStateException("Resource OID null in ResourceShadowDiscriminator during assignment processing");
}
if (rsd.getIntent() == null) {
throw new IllegalStateException("Resource object intent is null in ResourceShadowDiscriminator during assignment processing");
}
processOnlyExistingProjContexts = false;
if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
if (context.getTriggeringResourceOid() != null && !rsd.getResourceOid().equals(context.getTriggeringResourceOid())) {
LOGGER.trace("Skipping processing construction for shadow identified by {} because of limitation to propagate changes only for resource {}", rsd, context.getTriggeringResourceOid());
return false;
}
if (context.getChannel() != null && SchemaConstants.CHANNEL_DISCOVERY.equals(QNameUtil.uriToQName(context.getChannel()))) {
LOGGER.trace("Processing of shadow identified by {} will be skipped because of limitation for discovery channel.", // TODO is this message OK? [med]
context.getChannel());
processOnlyExistingProjContexts = true;
}
}
return true;
}
@Override
public void onAssigned(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd).context;
projectionContext.setAssigned(true);
projectionContext.setAssignedOldIfUnknown(false);
projectionContext.setLegalOldIfUnknown(false);
if (projectionContext.getAssignmentPolicyEnforcementType() != AssignmentPolicyEnforcementType.NONE) {
LOGGER.trace("Projection {} legal: assigned (valid)", desc);
projectionContext.setLegal(true);
} else {
LOGGER.trace("Projection {} skip: assigned (valid), NONE enforcement", desc);
}
}
@Override
public void onUnchangedValid(ResourceShadowDiscriminator key, String desc) throws SchemaException {
LensProjectionContext projectionContext = context.findProjectionContext(key);
if (projectionContext == null) {
if (processOnlyExistingProjContexts) {
LOGGER.trace("Projection {} skip: unchanged (valid), processOnlyExistingProjCxts", desc);
return;
}
// The projection should exist before the change but it does not
// This happens during reconciliation if there is an inconsistency.
// Pretend that the assignment was just added. That should do.
projectionContext = LensUtil.getOrCreateProjectionContext(context, key).context;
}
LOGGER.trace("Projection {} legal: unchanged (valid)", desc);
projectionContext.setAssigned(true);
projectionContext.setAssignedOldIfUnknown(true);
if (projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.NONE) {
projectionContext.setLegalOld(null);
projectionContext.setLegal(null);
} else {
projectionContext.setLegalOldIfUnknown(true);
projectionContext.setLegal(true);
}
}
@Override
public void onUnchangedInvalid(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
LensProjectionContext projectionContext = context.findProjectionContext(rsd);
if (projectionContext == null) {
if (processOnlyExistingProjContexts) {
LOGGER.trace("Projection {} skip: unchanged (invalid), processOnlyExistingProjContexts", desc);
} else {
LOGGER.trace("Projection {} skip: unchanged (invalid) and does not exist in current lens context", desc);
}
return;
}
LOGGER.trace("Projection {} illegal: unchanged (invalid)", desc);
projectionContext.setLegal(false);
projectionContext.setLegalOldIfUnknown(false);
projectionContext.setAssigned(false);
projectionContext.setAssignedOldIfUnknown(false);
if (projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.NONE || projectionContext.getAssignmentPolicyEnforcementType() == AssignmentPolicyEnforcementType.POSITIVE) {
projectionContext.setLegalOld(null);
projectionContext.setLegal(null);
} else {
projectionContext.setLegalOldIfUnknown(false);
projectionContext.setLegal(false);
}
}
@Override
public void onUnassigned(ResourceShadowDiscriminator rsd, String desc) throws SchemaException {
if (accountExists(context, rsd)) {
LensProjectionContext projectionContext = context.findProjectionContext(rsd);
if (projectionContext == null) {
if (processOnlyExistingProjContexts) {
LOGGER.trace("Projection {} skip: unassigned, processOnlyExistingProjContexts", desc);
return;
}
projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd).context;
}
projectionContext.setAssigned(false);
projectionContext.setAssignedOldIfUnknown(true);
projectionContext.setLegalOldIfUnknown(true);
AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
// TODO: check for MARK and LEGALIZE enforcement policies ....add delete also for relative enforcement
if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.FULL || assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.RELATIVE) {
LOGGER.trace("Projection {} illegal: unassigned", desc);
projectionContext.setLegal(false);
} else if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.POSITIVE) {
LOGGER.trace("Projection {} legal: unassigned, but allowed by policy ({})", desc, assignmentPolicyEnforcement);
projectionContext.setLegal(true);
} else {
LOGGER.trace("Projection {} legal: unassigned, policy decision postponed ({})", desc, assignmentPolicyEnforcement);
projectionContext.setLegal(null);
}
} else {
LOGGER.trace("Projection {} nothing: unassigned (valid->invalid) but not there", desc);
// We have to delete something that is not there. Nothing to do.
}
}
@Override
public void after(ResourceShadowDiscriminator rsd, String desc, DeltaMapTriple<ResourceShadowDiscriminator, EvaluatedConstructionPack<EvaluatedAssignedResourceObjectConstructionImpl<AH>>> constructionMapTriple) {
DeltaSetTriple<EvaluatedAssignedResourceObjectConstructionImpl<AH>> projectionEvaluatedConstructionDeltaSetTriple = prismContext.deltaFactory().createDeltaSetTriple(getConstructions(constructionMapTriple.getZeroMap().get(rsd), true), getConstructions(constructionMapTriple.getPlusMap().get(rsd), true), getConstructions(constructionMapTriple.getMinusMap().get(rsd), false));
LensProjectionContext projectionContext = context.findProjectionContext(rsd);
if (projectionContext != null) {
// This can be null in a exotic case if we delete already deleted account
LOGGER.trace("Construction delta set triple for {}:\n{}", rsd, projectionEvaluatedConstructionDeltaSetTriple.debugDumpLazily(1));
projectionContext.setEvaluatedAssignedConstructionDeltaSetTriple(projectionEvaluatedConstructionDeltaSetTriple);
if (isForceRecon(constructionMapTriple.getZeroMap().get(rsd)) || isForceRecon(constructionMapTriple.getPlusMap().get(rsd)) || isForceRecon(constructionMapTriple.getMinusMap().get(rsd))) {
projectionContext.setDoReconciliation(true);
}
}
}
};
OperationResult result = parentResult.createMinorSubresult(OP_DISTRIBUTE_CONSTRUCTIONS);
try {
LOGGER.trace("Starting construction distribution");
constructionProcessor.distributeConstructions(evaluatedAssignmentTriple, EvaluatedAssignmentImpl::getConstructionTriple, construction -> getConstructionMapKey(context, construction, task, result), consumer);
LOGGER.trace("Finished construction distribution");
} catch (Throwable t) {
result.recordFatalError(t);
throw t;
} finally {
result.computeStatusIfUnknown();
}
}
Aggregations