Search in sources :

Example 1 with EvaluatedAssignmentTargetImpl

use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl in project midpoint by Evolveum.

the class HasAssignmentConstraintEvaluator method evaluate.

@Override
public <AH extends AssignmentHolderType> EvaluatedHasAssignmentTrigger evaluate(@NotNull JAXBElement<HasAssignmentPolicyConstraintType> constraintElement, @NotNull PolicyRuleEvaluationContext<AH> ctx, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
    OperationResult result = parentResult.subresult(OP_EVALUATE).setMinor().build();
    try {
        boolean shouldExist = QNameUtil.match(constraintElement.getName(), PolicyConstraintsType.F_HAS_ASSIGNMENT);
        HasAssignmentPolicyConstraintType constraint = constraintElement.getValue();
        ObjectReferenceType constraintTargetRef = constraint.getTargetRef();
        if (constraintTargetRef == null) {
            throw new SchemaException("No targetRef in hasAssignment constraint");
        }
        DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = ctx.lensContext.getEvaluatedAssignmentTriple();
        if (evaluatedAssignmentTriple == null) {
            return createTriggerIfShouldNotExist(shouldExist, constraintElement, ctx, result);
        }
        boolean allowMinus = ctx.state == ObjectState.BEFORE;
        boolean allowZero = true;
        boolean allowPlus = ctx.state == ObjectState.AFTER;
        boolean allowDirect = !Boolean.FALSE.equals(constraint.isDirect());
        boolean allowIndirect = !Boolean.TRUE.equals(constraint.isDirect());
        boolean allowEnabled = !Boolean.FALSE.equals(constraint.isEnabled());
        boolean allowDisabled = !Boolean.TRUE.equals(constraint.isEnabled());
        ConstraintReferenceMatcher<AH> refMatcher = new ConstraintReferenceMatcher<>(ctx, constraintTargetRef, expressionFactory, result, LOGGER);
        List<PrismObject<?>> matchingTargets = new ArrayList<>();
        for (EvaluatedAssignmentImpl<?> evaluatedAssignment : evaluatedAssignmentTriple.getNonNegativeValues()) {
            // MID-6403
            AssignmentOrigin origin = evaluatedAssignment.getOrigin();
            boolean assignmentIsAdded = origin.isBeingAdded();
            boolean assignmentIsDeleted = origin.isBeingDeleted();
            boolean assignmentIsKept = origin.isBeingKept();
            DeltaSetTriple<EvaluatedAssignmentTargetImpl> targetsTriple = evaluatedAssignment.getRoles();
            for (EvaluatedAssignmentTargetImpl target : targetsTriple.getNonNegativeValues()) {
                // MID-6403
                if (!target.appliesToFocus()) {
                    continue;
                }
                if (!(allowDirect && target.isDirectlyAssigned() || allowIndirect && !target.isDirectlyAssigned())) {
                    continue;
                }
                if (!(allowEnabled && target.isValid() || allowDisabled && !target.isValid())) {
                    continue;
                }
                if (!relationMatches(constraintTargetRef.getRelation(), constraint.getRelation(), target.getAssignment())) {
                    continue;
                }
                boolean targetIsInPlusSet = targetsTriple.presentInPlusSet(target);
                boolean targetIsInZeroSet = targetsTriple.presentInZeroSet(target);
                boolean targetIsInMinusSet = targetsTriple.presentInMinusSet(target);
                // TODO check these computations
                boolean isPlus = assignmentIsAdded || assignmentIsKept && targetIsInPlusSet;
                boolean isZero = assignmentIsKept && targetIsInZeroSet;
                boolean isMinus = assignmentIsDeleted || assignmentIsKept && targetIsInMinusSet;
                // noinspection ConstantConditions
                if (!(allowPlus && isPlus || allowZero && isZero || allowMinus && isMinus)) {
                    continue;
                }
                if (refMatcher.refMatchesTarget(target.getTarget(), "hasAssignment constraint")) {
                    // TODO more specific trigger, containing information on matching assignment; see ExclusionConstraintEvaluator
                    matchingTargets.add(target.getTarget());
                }
            }
        }
        if (!matchingTargets.isEmpty()) {
            if (shouldExist) {
                PrismObject<?> anyTargetObject = matchingTargets.get(0);
                return new EvaluatedHasAssignmentTrigger(PolicyConstraintKindType.HAS_ASSIGNMENT, constraint, matchingTargets, createPositiveMessage(constraintElement, ctx, anyTargetObject, result), createPositiveShortMessage(constraintElement, ctx, anyTargetObject, result));
            } else {
                // we matched something but the constraint was "has no assignment"
                return null;
            }
        } else {
            return createTriggerIfShouldNotExist(shouldExist, constraintElement, ctx, result);
        }
    } catch (Throwable t) {
        result.recordFatalError(t.getMessage(), t);
        throw t;
    } finally {
        result.computeStatusIfUnknown();
    }
}
Also used : EvaluatedHasAssignmentTrigger(com.evolveum.midpoint.model.api.context.EvaluatedHasAssignmentTrigger) AssignmentOrigin(com.evolveum.midpoint.model.impl.lens.projector.AssignmentOrigin) ArrayList(java.util.ArrayList) EvaluatedAssignmentTargetImpl(com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) EvaluatedAssignmentImpl(com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl) PrismObject(com.evolveum.midpoint.prism.PrismObject)

Example 2 with EvaluatedAssignmentTargetImpl

use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl in project midpoint by Evolveum.

the class ExclusionConstraintEvaluator method evaluate.

@Override
public <AH extends AssignmentHolderType> EvaluatedExclusionTrigger evaluate(@NotNull JAXBElement<ExclusionPolicyConstraintType> constraint, @NotNull PolicyRuleEvaluationContext<AH> rctx, OperationResult parentResult) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException {
    OperationResult result = parentResult.subresult(OP_EVALUATE).setMinor().build();
    try {
        LOGGER.trace("Evaluating exclusion constraint {} on {}", lazy(() -> PolicyRuleTypeUtil.toShortString(constraint)), rctx);
        if (!(rctx instanceof AssignmentPolicyRuleEvaluationContext)) {
            return null;
        }
        AssignmentPolicyRuleEvaluationContext<AH> ctx = (AssignmentPolicyRuleEvaluationContext<AH>) rctx;
        if (!ctx.isAdded && !ctx.isKept) {
            LOGGER.trace("Assignment not being added nor kept, skipping evaluation.");
            return null;
        }
        if (sourceOrderConstraintsDoNotMatch(constraint, ctx)) {
            // logged in the called method body
            return null;
        }
        /*
             * Now let us check the exclusions.
             *
             * Assignment A is the current evaluated assignment. It has directly or indirectly attached the exclusion policy rule.
             * We now go through all other assignments B and check the exclusions.
             */
        List<OrderConstraintsType> targetOrderConstraints = defaultIfEmpty(constraint.getValue().getTargetOrderConstraint());
        List<EvaluatedAssignmentTargetImpl> nonNegativeTargetsA = ctx.evaluatedAssignment.getNonNegativeTargets();
        ConstraintReferenceMatcher<AH> refMatcher = new ConstraintReferenceMatcher<>(ctx, constraint.getValue().getTargetRef(), expressionFactory, result, LOGGER);
        for (EvaluatedAssignmentImpl<AH> assignmentB : ctx.evaluatedAssignmentTriple.getNonNegativeValues()) {
            // MID-6403
            if (assignmentB == ctx.evaluatedAssignment) {
                // currently there is no other way of comparing the evaluated assignments
                continue;
            }
            targetB: for (EvaluatedAssignmentTargetImpl targetB : assignmentB.getNonNegativeTargets()) {
                if (!pathMatches(targetB.getAssignmentPath(), targetOrderConstraints)) {
                    LOGGER.trace("Skipping considering exclusion target {} because it does not match target path constraints." + " Path={}, constraints={}", targetB, targetB.getAssignmentPath(), targetOrderConstraints);
                    continue;
                }
                if (!refMatcher.refMatchesTarget(targetB.getTarget(), "exclusion constraint")) {
                    LOGGER.trace("Target {} OID does not match exclusion filter", targetB);
                    continue;
                }
                // To avoid false positives let us check if this target is not already covered by assignment being evaluated
                for (EvaluatedAssignmentTargetImpl targetA : nonNegativeTargetsA) {
                    if (targetIsAlreadyCovered(targetB, targetA)) {
                        continue targetB;
                    }
                }
                EvaluatedExclusionTrigger rv = createTrigger(ctx.evaluatedAssignment, assignmentB, targetB, constraint, ctx.policyRule, ctx, result);
                result.addReturn("trigger", rv.toDiagShortcut());
                return rv;
            }
        }
        return null;
    } catch (Throwable t) {
        result.recordFatalError(t.getMessage(), t);
        throw t;
    } finally {
        result.computeStatusIfUnknown();
    }
}
Also used : AssignmentPolicyRuleEvaluationContext(com.evolveum.midpoint.model.impl.lens.projector.policy.AssignmentPolicyRuleEvaluationContext) EvaluatedAssignmentTargetImpl(com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) OrderConstraintsType(com.evolveum.midpoint.xml.ns._public.common.common_3.OrderConstraintsType) EvaluatedExclusionTrigger(com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger)

Example 3 with EvaluatedAssignmentTargetImpl

use of com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl in project midpoint by Evolveum.

the class PolicyRuleProcessor method addGlobalPolicyRulesToAssignments.

// endregion
// region ------------------------------------------------------------------ Global policy rules
public <F extends AssignmentHolderType> void addGlobalPolicyRulesToAssignments(LensContext<F> context, DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, SecurityViolationException, ConfigurationException, CommunicationException {
    PrismObject<SystemConfigurationType> systemConfiguration = context.getSystemConfiguration();
    if (systemConfiguration == null) {
        return;
    }
    // We need to consider object before modification here.
    LensFocusContext<F> focusContext = context.getFocusContext();
    if (focusContext.isDelete()) {
        // TODO ok?
        LOGGER.trace("Focus is being deleted => assignments-related global policy rules are ignored");
        return;
    }
    PrismObject<F> focus = Objects.requireNonNull(focusContext.getObjectCurrentOrNew(), "no current nor new focus while operation is not DELETE");
    List<GlobalPolicyRuleType> globalPolicyRuleList = systemConfiguration.asObjectable().getGlobalPolicyRule();
    LOGGER.trace("Checking {} global policy rules for selection to assignments", globalPolicyRuleList.size());
    int globalRulesInstantiated = 0;
    for (GlobalPolicyRuleType globalPolicyRule : globalPolicyRuleList) {
        ObjectSelectorType focusSelector = globalPolicyRule.getFocusSelector();
        if (!repositoryService.selectorMatches(focusSelector, focus, null, LOGGER, "Global policy rule " + globalPolicyRule.getName() + " focus selector: ")) {
            LOGGER.trace("Skipping global policy rule {} because focus selector did not match: {}", globalPolicyRule.getName(), globalPolicyRule);
            continue;
        }
        for (EvaluatedAssignmentImpl<F> evaluatedAssignment : evaluatedAssignmentTriple.getAllValues()) {
            for (EvaluatedAssignmentTargetImpl target : evaluatedAssignment.getRoles().getNonNegativeValues()) {
                // MID-6403
                if (!target.getAssignmentPath().last().isMatchingOrder() && !target.isDirectlyAssigned()) {
                    // well as all indirectly assigned roles but of the matching order (because of exclusion violation).
                    continue;
                }
                if (!repositoryService.selectorMatches(globalPolicyRule.getTargetSelector(), target.getTarget(), null, LOGGER, "Global policy rule " + globalPolicyRule.getName() + " target selector: ")) {
                    LOGGER.trace("Skipping global policy rule {} because target selector did not match: {}", globalPolicyRule.getName(), globalPolicyRule);
                    continue;
                }
                if (!isRuleConditionTrue(globalPolicyRule, focus, evaluatedAssignment, context, task, result)) {
                    LOGGER.trace("Skipping global policy rule {} because the condition evaluated to false: {}", globalPolicyRule.getName(), globalPolicyRule);
                    continue;
                }
                String ruleId = PolicyRuleTypeUtil.createId(systemConfiguration.getOid(), globalPolicyRule.getId());
                EvaluatedPolicyRuleImpl evaluatedRule = new EvaluatedPolicyRuleImpl(globalPolicyRule.clone(), ruleId, target.getAssignmentPath().clone(), evaluatedAssignment);
                boolean direct = target.isDirectlyAssigned();
                if (direct) {
                    evaluatedAssignment.addThisTargetPolicyRule(evaluatedRule);
                } else {
                    evaluatedAssignment.addOtherTargetPolicyRule(evaluatedRule);
                }
                globalRulesInstantiated++;
            }
        }
    }
    LOGGER.trace("Global policy rules instantiated {} times for further evaluation", globalRulesInstantiated);
}
Also used : EvaluatedAssignmentTargetImpl(com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl)

Aggregations

EvaluatedAssignmentTargetImpl (com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentTargetImpl)3 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)2 EvaluatedExclusionTrigger (com.evolveum.midpoint.model.api.context.EvaluatedExclusionTrigger)1 EvaluatedHasAssignmentTrigger (com.evolveum.midpoint.model.api.context.EvaluatedHasAssignmentTrigger)1 EvaluatedAssignmentImpl (com.evolveum.midpoint.model.impl.lens.assignments.EvaluatedAssignmentImpl)1 AssignmentOrigin (com.evolveum.midpoint.model.impl.lens.projector.AssignmentOrigin)1 AssignmentPolicyRuleEvaluationContext (com.evolveum.midpoint.model.impl.lens.projector.policy.AssignmentPolicyRuleEvaluationContext)1 PrismObject (com.evolveum.midpoint.prism.PrismObject)1 OrderConstraintsType (com.evolveum.midpoint.xml.ns._public.common.common_3.OrderConstraintsType)1 ArrayList (java.util.ArrayList)1