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();
}
}
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();
}
}
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);
}
Aggregations