use of com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentProcessor method evaluateConstructions.
private <F extends FocusType> void evaluateConstructions(LensContext<F> context, Collection<EvaluatedAssignmentImpl<F>> evaluatedAssignments, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
if (evaluatedAssignments == null) {
return;
}
ObjectDeltaObject<F> focusOdo = null;
LensFocusContext<F> focusContext = context.getFocusContext();
if (focusContext != null) {
focusOdo = focusContext.getObjectDeltaObject();
}
Iterator<EvaluatedAssignmentImpl<F>> iterator = evaluatedAssignments.iterator();
while (iterator.hasNext()) {
EvaluatedAssignmentImpl<F> evaluatedAssignment = iterator.next();
try {
evaluatedAssignment.evaluateConstructions(focusOdo, context.getSystemConfiguration(), task, result);
} catch (ObjectNotFoundException ex) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing of assignment resulted in error {}: {}", ex, SchemaDebugUtil.prettyPrint(evaluatedAssignment.getAssignmentType()));
}
iterator.remove();
if (!ModelExecuteOptions.isForce(context.getOptions())) {
ModelUtils.recordFatalError(result, ex);
}
} catch (SchemaException ex) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing of assignment resulted in error {}: {}", ex, SchemaDebugUtil.prettyPrint(evaluatedAssignment.getAssignmentType()));
}
ModelUtils.recordFatalError(result, ex);
String resourceOid = FocusTypeUtil.determineConstructionResource(evaluatedAssignment.getAssignmentType());
if (resourceOid == null) {
// This is a role assignment or something like that. Just throw the original exception for now.
throw ex;
}
ResourceShadowDiscriminator rad = new ResourceShadowDiscriminator(resourceOid, FocusTypeUtil.determineConstructionKind(evaluatedAssignment.getAssignmentType()), FocusTypeUtil.determineConstructionIntent(evaluatedAssignment.getAssignmentType()));
LensProjectionContext accCtx = context.findProjectionContext(rad);
if (accCtx != null) {
accCtx.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.BROKEN);
}
iterator.remove();
}
}
}
use of com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentProcessor method processAssignmentsProjectionsWithFocus.
/**
* Processing focus-projection assignments (including roles).
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private <F extends FocusType> void processAssignmentsProjectionsWithFocus(LensContext<F> context, XMLGregorianCalendar now, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, CommunicationException, ConfigurationException, SecurityViolationException {
// PREPARE ASSIGNMENT DELTA
LensFocusContext<F> focusContext = context.getFocusContext();
ObjectDelta<F> focusDelta = focusContext.getDelta();
if (focusDelta != null && focusDelta.isDelete()) {
processFocusDelete(context, result);
return;
}
checkAssignmentDeltaSanity(context);
// ASSIGNMENT EVALUATION
// Initializing assignment evaluator. This will be used later to process all the assignments including the nested
// assignments (roles).
AssignmentEvaluator<F> assignmentEvaluator = createAssignmentEvaluator(context, now);
ObjectType source = determineSource(focusContext);
AssignmentTripleEvaluator<F> assignmentTripleEvaluator = new AssignmentTripleEvaluator<>();
assignmentTripleEvaluator.setActivationComputer(activationComputer);
assignmentTripleEvaluator.setAssignmentEvaluator(assignmentEvaluator);
assignmentTripleEvaluator.setContext(context);
assignmentTripleEvaluator.setNow(now);
assignmentTripleEvaluator.setPrismContext(prismContext);
assignmentTripleEvaluator.setResult(result);
assignmentTripleEvaluator.setSource(source);
assignmentTripleEvaluator.setTask(task);
// Normal processing. The enforcement policy requires that assigned accounts should be added, so we need to figure out
// which assignments were added. Do a complete recompute for all the enforcement modes. We can do that because this does
// not create deltas, it just creates the triples. So we can decide what to do later when we convert triples to deltas.
// Evaluates all assignments and sorts them to triple: added, removed and untouched assignments.
// This is where most of the assignment-level action happens.
DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
}
// PROCESSING POLICIES
policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
boolean needToReevaluateAssignments = policyRuleProcessor.processPruning(context, evaluatedAssignmentTriple, result);
if (needToReevaluateAssignments) {
LOGGER.debug("Re-evaluating assignments because exclusion pruning rule was triggered");
evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("re-evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
}
policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
}
//policyRuleProcessor.storeAssignmentPolicySituation(context, evaluatedAssignmentTriple, result);
// PROCESSING FOCUS
Map<ItemPath, DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>>> focusOutputTripleMap = new HashMap<>();
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getPlusSet(), focusOutputTripleMap, PlusMinusZero.PLUS);
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getMinusSet(), focusOutputTripleMap, PlusMinusZero.MINUS);
collectFocusTripleFromMappings(evaluatedAssignmentTriple.getZeroSet(), focusOutputTripleMap, PlusMinusZero.ZERO);
ObjectDeltaObject<F> focusOdo = focusContext.getObjectDeltaObject();
Collection<ItemDelta<?, ?>> focusDeltas = objectTemplateProcessor.computeItemDeltas(focusOutputTripleMap, null, focusOdo.getObjectDelta(), focusOdo.getNewObject(), focusContext.getObjectDefinition(), "focus mappings in assignments of " + focusContext.getHumanReadableName());
LOGGER.trace("Computed focus deltas: {}", focusDeltas);
focusContext.applyProjectionWaveSecondaryDeltas(focusDeltas);
focusContext.recompute();
// PROCESSING PROJECTIONS
// Evaluate the constructions in assignements now. These were not evaluated in the first pass of AssignmentEvaluator
// because there may be interaction from focusMappings of some roles to outbound mappings of other roles.
// Now we have complete focus with all the focusMappings so we can evaluate the constructions
evaluateConstructions(context, evaluatedAssignmentTriple, task, result);
ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>> consumer = new ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>>() {
private boolean processOnlyExistingProjCxts;
@Override
public boolean before(ResourceShadowDiscriminator rat) {
if (rat.getResourceOid() == null) {
throw new IllegalStateException("Resource OID null in ResourceAccountType during assignment processing");
}
if (rat.getIntent() == null) {
throw new IllegalStateException("Account type is null in ResourceAccountType during assignment processing");
}
processOnlyExistingProjCxts = false;
if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
if (context.getTriggeredResourceOid() != null && !rat.getResourceOid().equals(context.getTriggeredResourceOid())) {
LOGGER.trace("Skipping processing construction for shadow identified by {} because of limitation to propagate changes only for resource {}", rat, context.getTriggeredResourceOid());
return false;
}
if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY.equals(QNameUtil.uriToQName(context.getChannel()))) {
// TODO is this message OK? [med]
LOGGER.trace("Processing of shadow identified by {} will be skipped because of limitation for discovery channel.");
processOnlyExistingProjCxts = true;
}
}
return true;
}
@Override
public void onAssigned(ResourceShadowDiscriminator rat, String desc) {
LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
projectionContext.setAssigned(true);
projectionContext.setAssignedOld(false);
projectionContext.setLegalOld(false);
AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
if (assignmentPolicyEnforcement != AssignmentPolicyEnforcementType.NONE) {
LOGGER.trace("Projection {} legal: assigned (valid)", desc);
projectionContext.setLegal(true);
}
}
@Override
public void onUnchangedValid(ResourceShadowDiscriminator key, String desc) {
LensProjectionContext projectionContext = context.findProjectionContext(key);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
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);
}
LOGGER.trace("Projection {} legal: unchanged (valid)", desc);
projectionContext.setLegal(true);
projectionContext.setLegalOld(true);
projectionContext.setAssigned(true);
projectionContext.setAssignedOld(true);
}
@Override
public void onUnchangedInvalid(ResourceShadowDiscriminator rat, String desc) {
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
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, rat);
}
LOGGER.trace("Projection {} illegal: unchanged (invalid)", desc);
projectionContext.setLegal(false);
projectionContext.setLegalOld(false);
projectionContext.setAssigned(false);
projectionContext.setAssignedOld(false);
}
@Override
public void onUnassigned(ResourceShadowDiscriminator rat, String desc) {
if (accountExists(context, rat)) {
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext == null) {
if (processOnlyExistingProjCxts) {
return;
}
projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
}
projectionContext.setAssigned(false);
projectionContext.setAssignedOld(true);
projectionContext.setLegalOld(true);
AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
// TODO: check for MARK and LEGALIZE enforcement policies ....add delete laso for relative enforcemenet
if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.FULL || assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.RELATIVE) {
LOGGER.trace("Projection {} illegal: unassigned", desc);
projectionContext.setLegal(false);
} else {
LOGGER.trace("Projection {} legal: unassigned, but allowed by policy ({})", desc, assignmentPolicyEnforcement);
projectionContext.setLegal(true);
}
} 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 rat, String desc, DeltaMapTriple<ResourceShadowDiscriminator, ConstructionPack<Construction<F>>> constructionMapTriple) {
PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> projectionConstructionDeltaSetTriple = new PrismValueDeltaSetTriple<>(getConstructions(constructionMapTriple.getZeroMap().get(rat), true), getConstructions(constructionMapTriple.getPlusMap().get(rat), true), getConstructions(constructionMapTriple.getMinusMap().get(rat), false));
LensProjectionContext projectionContext = context.findProjectionContext(rat);
if (projectionContext != null) {
// This can be null in a exotic case if we delete already deleted account
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Construction delta set triple for {}:\n{}", rat, projectionConstructionDeltaSetTriple.debugDump(1));
}
projectionContext.setConstructionDeltaSetTriple(projectionConstructionDeltaSetTriple);
if (isForceRecon(constructionMapTriple.getZeroMap().get(rat)) || isForceRecon(constructionMapTriple.getPlusMap().get(rat)) || isForceRecon(constructionMapTriple.getMinusMap().get(rat))) {
projectionContext.setDoReconciliation(true);
}
}
}
};
constructionProcessor.processConstructions(context, evaluatedAssignmentTriple, evaluatedAssignment -> evaluatedAssignment.getConstructionTriple(), construction -> getConstructionMapKey(context, construction, task, result), consumer, task, result);
removeIgnoredContexts(context);
finishLegalDecisions(context);
}
use of com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class NotificationChangeHook method emitPolicyRulesEvents.
private void emitPolicyRulesEvents(ModelContext<?> context, Task task, OperationResult result) {
LensFocusContext<?> focusContext = (LensFocusContext<?>) context.getFocusContext();
for (EvaluatedPolicyRule rule : focusContext.getPolicyRules()) {
emitPolicyEventIfPresent(rule, context, task, result);
}
DeltaSetTriple<EvaluatedAssignmentImpl<?>> triple = ((LensContext<?>) context).getEvaluatedAssignmentTriple();
if (triple != null) {
for (EvaluatedAssignment<?> assignment : triple.getNonNegativeValues()) {
for (EvaluatedPolicyRule rule : assignment.getAllTargetsPolicyRules()) {
emitPolicyEventIfPresent(rule, context, task, result);
}
}
}
}
use of com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class FocusProcessor method triggerAssignmentFocusPolicyRules.
// TODO: should we really do this? Focus policy rules (e.g. forbidden modifications) are irrelevant in this situation,
// TODO: i.e. if we are assigning the object into some other object [med]
private <F extends FocusType> void triggerAssignmentFocusPolicyRules(LensContext<F> context, String activityDescription, XMLGregorianCalendar now, Task task, OperationResult result) throws PolicyViolationException, SchemaException {
LensFocusContext<F> focusContext = context.getFocusContext();
DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple();
if (evaluatedAssignmentTriple == null) {
return;
}
for (EvaluatedAssignmentImpl<?> evaluatedAssignment : evaluatedAssignmentTriple.getNonNegativeValues()) {
Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getFocusPolicyRules();
for (EvaluatedPolicyRule policyRule : policyRules) {
triggerRule(focusContext, policyRule);
}
}
}
use of com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl in project midpoint by Evolveum.
the class AssignmentTripleEvaluator method processAssignment.
private void processAssignment(DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple, ObjectDelta<F> focusDelta, ContainerDelta<AssignmentType> assignmentDelta, SmartAssignmentElement assignmentElement) throws SchemaException, ExpressionEvaluationException, PolicyViolationException {
LensFocusContext<F> focusContext = context.getFocusContext();
PrismContainerValue<AssignmentType> assignmentCVal = assignmentElement.getAssignmentCVal();
AssignmentType assignmentType = assignmentCVal.asContainerable();
PrismContainerValue<AssignmentType> assignmentCValOld = assignmentCVal;
PrismContainerValue<AssignmentType> assignmentCValNew = assignmentCVal;
ItemDeltaItem<PrismContainerValue<AssignmentType>, PrismContainerDefinition<AssignmentType>> assignmentIdi = new ItemDeltaItem<>();
assignmentIdi.setItemOld(LensUtil.createAssignmentSingleValueContainerClone(assignmentType));
boolean presentInCurrent = assignmentElement.isCurrent();
boolean presentInOld = assignmentElement.isOld();
// This really means whether the WHOLE assignment was changed (e.g. added/delted/replaced). It tells nothing
// about "micro-changes" inside assignment, these will be processed later.
boolean isAssignmentChanged = assignmentElement.isChanged();
boolean forceRecon = false;
String assignmentPlacementDesc;
if (isAssignmentChanged) {
// Whole assignment added or deleted
assignmentPlacementDesc = "delta for " + source;
} else {
assignmentPlacementDesc = source.toString();
Collection<? extends ItemDelta<?, ?>> assignmentItemDeltas = getExecutionWaveAssignmentItemDeltas(focusContext, assignmentCVal.getId());
if (assignmentItemDeltas != null && !assignmentItemDeltas.isEmpty()) {
// Small changes inside assignment, but otherwise the assignment stays as it is (not added or deleted)
assignmentIdi.setSubItemDeltas(assignmentItemDeltas);
// The subItemDeltas above will handle some changes. But not other.
// E.g. a replace of the whole construction will not be handled properly.
// Therefore we force recon to sort it out.
forceRecon = true;
isAssignmentChanged = true;
PrismContainer<AssignmentType> assContNew = focusContext.getObjectNew().findContainer(FocusType.F_ASSIGNMENT);
assignmentCValNew = assContNew.getValue(assignmentCVal.getId());
}
}
assignmentIdi.recompute();
if (focusDelta != null && focusDelta.isDelete()) {
// were not changed explicitly.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing focus delete for: {}", SchemaDebugUtil.prettyPrint(assignmentCVal));
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.MINUS, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToMinus(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else {
if (assignmentDelta.isReplace()) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing replace of all assignments for: {}", SchemaDebugUtil.prettyPrint(assignmentCVal));
}
// ASSIGNMENT REPLACE
// Handling assignment replace delta. This needs to be handled specially as all the "old"
// assignments should be considered deleted - except those that are part of the new value set
// (remain after replace). As account delete and add are costly operations (and potentially dangerous)
// we optimize here are consider the assignments that were there before replace and still are there
// after it as unchanged.
boolean hadValue = presentInCurrent;
boolean willHaveValue = assignmentDelta.isValueToReplace(assignmentCVal, true);
if (hadValue && willHaveValue) {
// No change
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.ZERO, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToZero(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else if (willHaveValue) {
// add
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.PLUS, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToPlus(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else if (hadValue) {
// delete
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.MINUS, true, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToMinus(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else if (assignmentElement.isOld()) {
// This is OK, safe to skip. This is just an relic of earlier processing.
return;
} else {
LOGGER.error("Whoops. Unexpected things happen. Assignment is neither current, old nor new (replace delta)\n{}", assignmentElement.debugDump(1));
throw new SystemException("Whoops. Unexpected things happen. Assignment is neither current, old nor new (replace delta).");
}
} else {
// Just sort assignments to sets: unchanged (zero), added (plus), removed (minus)
if (isAssignmentChanged) {
// There was some change
boolean isAdd = assignmentDelta.isValueToAdd(assignmentCVal, true);
boolean isDelete = assignmentDelta.isValueToDelete(assignmentCVal, true);
if (isAdd & !isDelete) {
// Entirely new assignment is added
if (presentInCurrent && presentInOld) {
// Phantom add: adding assignment that is already there
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, phantom add: {}", SchemaDebugUtil.prettyPrint(assignmentCVal));
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.ZERO, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToZero(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, add: {}", SchemaDebugUtil.prettyPrint(assignmentCVal));
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.PLUS, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToPlus(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
}
} else if (isDelete && !isAdd) {
// Existing assignment is removed
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, delete: {}", SchemaDebugUtil.prettyPrint(assignmentCVal));
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.MINUS, true, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToMinus(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
} else {
// Small change inside an assignment
// The only thing that we need to worry about is assignment validity change. That is a cause
// of provisioning/deprovisioning of the projections. So check that explicitly. Other changes are
// not significant, i.e. reconciliation can handle them.
boolean isValidOld = LensUtil.isAssignmentValid(focusContext.getObjectOld().asObjectable(), assignmentCValOld.asContainerable(), now, activationComputer);
boolean isValid = LensUtil.isAssignmentValid(focusContext.getObjectNew().asObjectable(), assignmentCValNew.asContainerable(), now, activationComputer);
if (isValid == isValidOld) {
// The change is not significant for assignment applicability. Recon will sort out the details.
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, minor change (add={}, delete={}, valid={}): {}", new Object[] { isAdd, isDelete, isValid, SchemaDebugUtil.prettyPrint(assignmentCVal) });
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.ZERO, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToZero(evaluatedAssignmentTriple, evaluatedAssignment, true);
} else if (isValid) {
// Assignment became valid. We need to place it in plus set to initiate provisioning
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, assignment becomes valid (add={}, delete={}): {}", new Object[] { isAdd, isDelete, SchemaDebugUtil.prettyPrint(assignmentCVal) });
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.PLUS, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToPlus(evaluatedAssignmentTriple, evaluatedAssignment, true);
} else {
// Assignment became invalid. We need to place is in minus set to initiate deprovisioning
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing changed assignment, assignment becomes invalid (add={}, delete={}): {}", new Object[] { isAdd, isDelete, SchemaDebugUtil.prettyPrint(assignmentCVal) });
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.MINUS, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToMinus(evaluatedAssignmentTriple, evaluatedAssignment, true);
}
}
} else {
// No change in assignment
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Processing unchanged assignment {}", new Object[] { SchemaDebugUtil.prettyPrint(assignmentCVal) });
}
EvaluatedAssignmentImpl<F> evaluatedAssignment = evaluateAssignment(assignmentIdi, PlusMinusZero.ZERO, false, context, source, assignmentEvaluator, assignmentPlacementDesc, task, result);
if (evaluatedAssignment == null) {
return;
}
evaluatedAssignment.setPresentInCurrentObject(presentInCurrent);
evaluatedAssignment.setPresentInOldObject(presentInOld);
collectToZero(evaluatedAssignmentTriple, evaluatedAssignment, forceRecon);
}
}
}
}
Aggregations