Search in sources :

Example 16 with SKIP

use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.

the class LensUtil method consolidateTripleToDelta.

/**
	 * Consolidate the mappings of a single item to a delta. It takes the convenient structure of ItemValueWithOrigin triple.
	 * It produces the delta considering the mapping exclusion, authoritativeness and strength.
     *
     * filterExistingValues: if true, then values that already exist in the item are not added (and those that don't exist are not removed)
	 */
@NotNull
public static <V extends PrismValue, D extends ItemDefinition, I extends ItemValueWithOrigin<V, D>> ItemDelta<V, D> consolidateTripleToDelta(ItemPath itemPath, DeltaSetTriple<I> triple, D itemDefinition, ItemDelta<V, D> aprioriItemDelta, PrismContainer<?> itemContainer, ValueMatcher<?> valueMatcher, Comparator<V> comparator, boolean addUnchangedValues, boolean filterExistingValues, boolean isExclusiveStrong, String contextDescription, boolean applyWeak) throws ExpressionEvaluationException, PolicyViolationException, SchemaException {
    ItemDelta<V, D> itemDelta = itemDefinition.createEmptyDelta(itemPath);
    Item<V, D> itemExisting = null;
    if (itemContainer != null) {
        itemExisting = itemContainer.findItem(itemPath);
    }
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Consolidating {} triple:\n{}\nApriori Delta:\n{}\nExisting item:\n{}", itemPath, triple.debugDump(1), DebugUtil.debugDump(aprioriItemDelta, 1), DebugUtil.debugDump(itemExisting, 1));
    }
    Collection<V> allValues = collectAllValues(triple, valueMatcher);
    final MutableBoolean itemHasStrongMutable = new MutableBoolean(false);
    SimpleVisitor<I> visitor = pvwo -> {
        if (pvwo.getMapping().getStrength() == MappingStrengthType.STRONG) {
            itemHasStrongMutable.setValue(true);
        }
    };
    triple.accept(visitor);
    boolean ignoreNormalMappings = itemHasStrongMutable.booleanValue() && isExclusiveStrong;
    // a single item (e.g. attribute). But this loop iterates over every potential value of that item.
    for (V value : allValues) {
        LOGGER.trace("  consolidating value: {}", value);
        // Check what to do with the value using the usual "triple routine". It means that if a value is
        // in zero set than we need no delta, plus set means add delta and minus set means delete delta.
        // The first set that the value is present determines the result.
        Collection<ItemValueWithOrigin<V, D>> zeroPvwos = collectPvwosFromSet(value, triple.getZeroSet(), valueMatcher);
        Collection<ItemValueWithOrigin<V, D>> plusPvwos = collectPvwosFromSet(value, triple.getPlusSet(), valueMatcher);
        Collection<ItemValueWithOrigin<V, D>> minusPvwos = collectPvwosFromSet(value, triple.getMinusSet(), valueMatcher);
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("PVWOs for value {}:\nzero = {}\nplus = {}\nminus = {}", value, zeroPvwos, plusPvwos, minusPvwos);
        }
        boolean zeroHasStrong = false;
        if (!zeroPvwos.isEmpty()) {
            for (ItemValueWithOrigin<V, D> pvwo : zeroPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    zeroHasStrong = true;
                }
            }
        }
        if (zeroHasStrong && aprioriItemDelta != null && aprioriItemDelta.isValueToDelete(value, true)) {
            throw new PolicyViolationException("Attempt to delete value " + value + " from item " + itemPath + " but that value is mandated by a strong mapping (in " + contextDescription + ")");
        }
        if (!zeroPvwos.isEmpty() && !addUnchangedValues) {
            // Value unchanged, nothing to do
            LOGGER.trace("Value {} unchanged, doing nothing", value);
            continue;
        }
        PrismValueDeltaSetTripleProducer<V, D> exclusiveMapping = null;
        Collection<ItemValueWithOrigin<V, D>> pvwosToAdd = null;
        if (addUnchangedValues) {
            pvwosToAdd = MiscUtil.union(zeroPvwos, plusPvwos);
        } else {
            pvwosToAdd = plusPvwos;
        }
        if (!pvwosToAdd.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwoToAdd : pvwosToAdd) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwoToAdd.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isExclusive()) {
                    if (exclusiveMapping == null) {
                        exclusiveMapping = mapping;
                    } else {
                        String message = "Exclusion conflict in " + contextDescription + ", item " + itemPath + ", conflicting constructions: " + exclusiveMapping + " and " + mapping;
                        LOGGER.error(message);
                        throw new ExpressionEvaluationException(message);
                    }
                }
            }
            if (weakOnly) {
                // Postpone processing of weak values until we process all other values
                LOGGER.trace("Value {} mapping is weak in item {}, postponing processing in {}", value, itemPath, contextDescription);
                continue;
            }
            if (!hasStrong && ignoreNormalMappings) {
                LOGGER.trace("Value {} mapping is normal in item {} and we have exclusiveStrong, skipping processing in {}", value, itemPath, contextDescription);
                continue;
            }
            if (hasStrong && aprioriItemDelta != null && aprioriItemDelta.isValueToDelete(value, true)) {
                throw new PolicyViolationException("Attempt to delete value " + value + " from item " + itemPath + " but that value is mandated by a strong mapping (in " + contextDescription + ")");
            }
            if (!hasStrong && (aprioriItemDelta != null && !aprioriItemDelta.isEmpty())) {
                // There is already a delta, skip this
                LOGGER.trace("Value {} mapping is not strong and the item {} already has a delta that is more concrete, " + "skipping adding in {}", value, itemPath, contextDescription);
                continue;
            }
            if (filterExistingValues && hasValue(itemExisting, value, valueMatcher, comparator)) {
                LOGGER.trace("Value {} NOT added to delta for item {} because the item already has that value in {}", value, itemPath, contextDescription);
                continue;
            }
            LOGGER.trace("Value {} added to delta as ADD for item {} in {}", value, itemPath, contextDescription);
            itemDelta.addValueToAdd((V) value.clone());
            continue;
        }
        // So check for that special case here to avoid removing them.
        if (!minusPvwos.isEmpty() && plusPvwos.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            boolean hasAuthoritative = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwo : minusPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isAuthoritative()) {
                    hasAuthoritative = true;
                }
            }
            if (!hasAuthoritative) {
                LOGGER.trace("Value {} has no authoritative mapping for item {}, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (!hasStrong && (aprioriItemDelta != null && !aprioriItemDelta.isEmpty())) {
                // There is already a delta, skip this
                LOGGER.trace("Value {} mapping is not strong and the item {} already has a delta that is more concrete, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (weakOnly && (itemExisting != null && !itemExisting.isEmpty())) {
                // There is already a value, skip this
                LOGGER.trace("Value {} mapping is weak and the item {} already has a value, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (weakOnly && !applyWeak && (itemExisting == null || itemExisting.isEmpty())) {
                // There is a weak mapping on a property, but we do not have full account available, so skipping deletion of the value is better way
                LOGGER.trace("Value {} mapping is weak and the full account could not be fetched, skipping deletion in {}", value, itemPath, contextDescription);
                continue;
            }
            if (filterExistingValues && !hasValue(itemExisting, value, valueMatcher, comparator)) {
                LOGGER.trace("Value {} NOT add to delta as DELETE because item {} the item does not have that value in {} (matcher: {})", value, itemPath, contextDescription, valueMatcher);
                continue;
            }
            LOGGER.trace("Value {} added to delta as DELETE for item {} in {}", value, itemPath, contextDescription);
            itemDelta.addValueToDelete((V) value.clone());
        }
        if (!zeroPvwos.isEmpty()) {
            boolean weakOnly = true;
            boolean hasStrong = false;
            boolean hasAuthoritative = false;
            // exclusions and strength
            for (ItemValueWithOrigin<V, D> pvwo : zeroPvwos) {
                PrismValueDeltaSetTripleProducer<V, D> mapping = pvwo.getMapping();
                if (mapping.getStrength() != MappingStrengthType.WEAK) {
                    weakOnly = false;
                }
                if (mapping.getStrength() == MappingStrengthType.STRONG) {
                    hasStrong = true;
                }
                if (mapping.isAuthoritative()) {
                    hasAuthoritative = true;
                }
            }
            if (aprioriItemDelta != null && aprioriItemDelta.isReplace()) {
                // Any strong mappings in the zero set needs to be re-applied as otherwise the replace will destroy it
                if (hasStrong) {
                    LOGGER.trace("Value {} added to delta for item {} in {} because there is strong mapping in the zero set", value, itemPath, contextDescription);
                    itemDelta.addValueToAdd((V) value.clone());
                    continue;
                }
            }
        }
    }
    Item<V, D> itemNew = null;
    if (itemContainer != null) {
        itemNew = itemContainer.findItem(itemPath);
    }
    if (!hasValue(itemNew, itemDelta)) {
        // The application of computed delta results in no value, apply weak mappings
        Collection<? extends ItemValueWithOrigin<V, D>> nonNegativePvwos = triple.getNonNegativeValues();
        Collection<V> valuesToAdd = addWeakValues(nonNegativePvwos, OriginType.ASSIGNMENTS, applyWeak);
        if (valuesToAdd.isEmpty()) {
            valuesToAdd = addWeakValues(nonNegativePvwos, OriginType.OUTBOUND, applyWeak);
        }
        if (valuesToAdd.isEmpty()) {
            valuesToAdd = addWeakValues(nonNegativePvwos, null, applyWeak);
        }
        LOGGER.trace("No value for item {} in {}, weak mapping processing yielded values: {}", itemPath, contextDescription, valuesToAdd);
        itemDelta.addValuesToAdd(valuesToAdd);
    } else {
        LOGGER.trace("Existing values for item {} in {}, weak mapping processing skipped", new Object[] { itemPath, contextDescription });
    }
    if (itemExisting != null) {
        List<V> existingValues = itemExisting.getValues();
        if (existingValues != null) {
            itemDelta.setEstimatedOldValues(PrismValue.cloneCollection(existingValues));
        }
    }
    return itemDelta;
}
Also used : ObjectResolver(com.evolveum.midpoint.schema.util.ObjectResolver) com.evolveum.midpoint.util.exception(com.evolveum.midpoint.util.exception) ExpressionConstants(com.evolveum.midpoint.schema.constants.ExpressionConstants) BooleanUtils(org.apache.commons.lang.BooleanUtils) DOMUtil(com.evolveum.midpoint.util.DOMUtil) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) EvaluatedPolicyRule(com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) com.evolveum.midpoint.prism(com.evolveum.midpoint.prism) PasswordCapabilityType(com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.PasswordCapabilityType) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) Utils(com.evolveum.midpoint.model.impl.util.Utils) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) Collection(java.util.Collection) ActivationComputer(com.evolveum.midpoint.common.ActivationComputer) ResourceTypeUtil(com.evolveum.midpoint.schema.util.ResourceTypeUtil) ModelExpressionThreadLocalHolder(com.evolveum.midpoint.model.impl.expr.ModelExpressionThreadLocalHolder) MiscUtil(com.evolveum.midpoint.util.MiscUtil) Task(com.evolveum.midpoint.task.api.Task) EvaluatedPolicyRuleTrigger(com.evolveum.midpoint.model.api.context.EvaluatedPolicyRuleTrigger) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) ExpressionVariables(com.evolveum.midpoint.repo.common.expression.ExpressionVariables) ExpressionFactory(com.evolveum.midpoint.repo.common.expression.ExpressionFactory) PolyStringType(com.evolveum.prism.xml.ns._public.types_3.PolyStringType) ProvisioningService(com.evolveum.midpoint.provisioning.api.ProvisioningService) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) QName(javax.xml.namespace.QName) NotNull(org.jetbrains.annotations.NotNull) com.evolveum.midpoint.xml.ns._public.common.common_3(com.evolveum.midpoint.xml.ns._public.common.common_3) SchemaConstants(com.evolveum.midpoint.schema.constants.SchemaConstants) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) Trace(com.evolveum.midpoint.util.logging.Trace) DebugUtil(com.evolveum.midpoint.util.DebugUtil) PrismDefaultPolyStringNormalizer(com.evolveum.midpoint.prism.polystring.PrismDefaultPolyStringNormalizer) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) CredentialsCapabilityType(com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) HashSet(java.util.HashSet) SchemaConstantsGenerated(com.evolveum.midpoint.schema.SchemaConstantsGenerated) RefinedResourceSchema(com.evolveum.midpoint.common.refinery.RefinedResourceSchema) RefinedResourceSchemaImpl(com.evolveum.midpoint.common.refinery.RefinedResourceSchemaImpl) ObjectTypeUtil(com.evolveum.midpoint.schema.util.ObjectTypeUtil) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) CapabilityUtil(com.evolveum.midpoint.schema.CapabilityUtil) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) ItemDeltaItem(com.evolveum.midpoint.repo.common.expression.ItemDeltaItem) Iterator(java.util.Iterator) Expression(com.evolveum.midpoint.repo.common.expression.Expression) ExpressionEvaluationContext(com.evolveum.midpoint.repo.common.expression.ExpressionEvaluationContext) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) LoggingUtils(com.evolveum.midpoint.util.logging.LoggingUtils) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) ShadowUtil(com.evolveum.midpoint.schema.util.ShadowUtil) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) Source(com.evolveum.midpoint.repo.common.expression.Source) Comparator(java.util.Comparator) Collections(java.util.Collections) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) ValueMatcher(com.evolveum.midpoint.model.impl.lens.projector.ValueMatcher) MutableBoolean(org.apache.commons.lang.mutable.MutableBoolean) PolyString(com.evolveum.midpoint.prism.polystring.PolyString) NotNull(org.jetbrains.annotations.NotNull)

Example 17 with SKIP

use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP 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);
            }
        }
    }
}
Also used : PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) EvaluatedAssignmentImpl(com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl) ItemDeltaItem(com.evolveum.midpoint.repo.common.expression.ItemDeltaItem) SystemException(com.evolveum.midpoint.util.exception.SystemException) AssignmentType(com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) PrismObject(com.evolveum.midpoint.prism.PrismObject)

Example 18 with SKIP

use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.

the class OrgStructFunctionsImpl method getParentOrgs.

@Override
public Collection<OrgType> getParentOrgs(ObjectType object, QName relation, String orgType, boolean preAuthorized) throws SchemaException, SecurityViolationException {
    List<ObjectReferenceType> parentOrgRefs = object.getParentOrgRef();
    List<OrgType> parentOrgs = new ArrayList<>(parentOrgRefs.size());
    for (ObjectReferenceType parentOrgRef : parentOrgRefs) {
        if (!ObjectTypeUtil.relationMatches(relation, parentOrgRef.getRelation())) {
            continue;
        }
        OrgType parentOrg;
        try {
            parentOrg = getObject(OrgType.class, parentOrgRef.getOid(), preAuthorized);
        } catch (ObjectNotFoundException e) {
            LOGGER.warn("Org " + parentOrgRef.getOid() + " specified in parentOrgRef in " + object + " was not found: " + e.getMessage(), e);
            // but do not rethrow, just skip this
            continue;
        } catch (CommunicationException | ConfigurationException | ExpressionEvaluationException e) {
            // This should not happen.
            throw new SystemException(e.getMessage(), e);
        }
        if (orgType == null || parentOrg.getOrgType().contains(orgType)) {
            parentOrgs.add(parentOrg);
        }
    }
    return parentOrgs;
}
Also used : ObjectReferenceType(com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType) OrgType(com.evolveum.midpoint.xml.ns._public.common.common_3.OrgType)

Example 19 with SKIP

use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.

the class WfHook method invoke.

@Override
public <O extends ObjectType> HookOperationMode invoke(@NotNull ModelContext<O> context, @NotNull Task taskFromModel, @NotNull OperationResult parentResult) {
    Validate.notNull(context);
    Validate.notNull(taskFromModel);
    Validate.notNull(parentResult);
    // Generally this cannot be minor as we need the "task switched to background" flag.
    // But if the hook does nothing (returns FOREGROUND flag), we mark the result
    // as minor afterwards.
    OperationResult result = parentResult.createSubresult(OPERATION_INVOKE);
    result.addParam("taskFromModel", taskFromModel.toString());
    result.addContext("model state", context.getState());
    try {
        WfConfigurationType wfConfigurationType = baseConfigurationHelper.getWorkflowConfiguration(context, result);
        // TODO consider this if it's secure enough
        if (wfConfigurationType != null && Boolean.FALSE.equals(wfConfigurationType.isModelHookEnabled())) {
            LOGGER.info("Workflow model hook is disabled. Proceeding with operation execution as if everything is approved.");
            result.recordSuccess();
            return HookOperationMode.FOREGROUND;
        }
        if (context.getPartialProcessingOptions().getApprovals() == PartialProcessingTypeType.SKIP) {
            LOGGER.debug("Skipping workflow processing because of the partial processing option set to SKIP");
            result.recordSuccess();
            return HookOperationMode.FOREGROUND;
        }
        // e.g. for tests, initialization is scattered through many places, so that would be too much work.
        if (SchemaConstants.CHANNEL_GUI_INIT_URI.equals(context.getChannel())) {
            LOGGER.debug("Skipping workflow processing because the channel is '" + SchemaConstants.CHANNEL_GUI_INIT_URI + "'.");
            result.recordSuccess();
            return HookOperationMode.FOREGROUND;
        }
        logOperationInformation(context);
        HookOperationMode retval = processModelInvocation(context, wfConfigurationType, taskFromModel, result);
        result.computeStatus();
        if (retval == HookOperationMode.FOREGROUND) {
            result.setMinor(true);
        }
        return retval;
    } catch (RuntimeException e) {
        result.recordFatalError("Couldn't process model invocation in workflow module: " + e.getMessage(), e);
        throw e;
    }
}
Also used : HookOperationMode(com.evolveum.midpoint.model.api.hooks.HookOperationMode) WfConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.WfConfigurationType) OperationResult(com.evolveum.midpoint.schema.result.OperationResult)

Example 20 with SKIP

use of com.evolveum.midpoint.xml.ns._public.common.common_3.PartialProcessingTypeType.SKIP in project midpoint by Evolveum.

the class LoggingConfigurationManager method prepareConfiguration.

private static String prepareConfiguration(LoggingConfigurationType config) throws SchemaException {
    if (null == config) {
        throw new IllegalArgumentException("Configuration can't be null");
    }
    StringBuilder sb = new StringBuilder();
    sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    sb.append("<configuration scan=\"false\" debug=\"true\">\n");
    //find and configure ALL logger and bring it to top of turbo stack
    for (SubSystemLoggerConfigurationType ss : config.getSubSystemLogger()) {
        if ("ALL".contentEquals(ss.getComponent().name())) {
            defineTurbo(sb, ss);
        }
    }
    //Generate subsystem logging quickstep
    for (SubSystemLoggerConfigurationType ss : config.getSubSystemLogger()) {
        if (null == ss.getComponent() || null == ss.getLevel()) {
            LOGGER.error("Subsystem ({}) or level ({})is null", ss.getComponent(), ss.getLevel());
            continue;
        }
        //skip disabled subsystem logger
        if ("OFF".equals(ss.getLevel().name())) {
            continue;
        }
        //All ready defined above
        if ("ALL".contentEquals(ss.getComponent().name())) {
            continue;
        }
        defineTurbo(sb, ss);
    }
    //Generate appenders configuration
    for (AppenderConfigurationType appender : config.getAppender()) {
        prepareAppenderConfiguration(sb, appender, config);
    }
    //define root appender if defined
    if (!StringUtils.isEmpty(config.getRootLoggerAppender())) {
        sb.append("\t<root level=\"");
        sb.append(config.getRootLoggerLevel());
        sb.append("\">\n");
        sb.append("\t\t<appender-ref ref=\"");
        sb.append(config.getRootLoggerAppender());
        sb.append("\" />\n");
        sb.append("\t</root>\n");
    }
    //Generate class based loggers
    for (ClassLoggerConfigurationType logger : config.getClassLogger()) {
        sb.append("\t<logger name=\"");
        sb.append(logger.getPackage());
        sb.append("\" level=\"");
        sb.append(logger.getLevel());
        sb.append("\"");
        //if logger specific appender is defined
        if (null != logger.getAppender() && !logger.getAppender().isEmpty()) {
            sb.append(" additivity=\"false\">\n");
            for (String appenderName : logger.getAppender()) {
                sb.append("\t\t<appender-ref ref=\"");
                sb.append(appenderName);
                sb.append("\"/>");
            }
            sb.append("\t</logger>\n");
        } else {
            sb.append("/>\n");
        }
    }
    generateAuditingLogConfig(config.getAuditing(), sb);
    if (null != config.getAdvanced()) {
        for (Object item : config.getAdvanced().getContent()) {
            sb.append(item.toString());
            sb.append("\n");
        }
    }
    // LevelChangePropagator to propagate log level changes to JUL
    // this keeps us from performance impact of disable JUL logging statements
    // WARNING: if deployed in Tomcat then this propagates only to the JUL loggers in current classloader.
    // It means that ICF connector loggers are not affected by this
    // MAGIC: moved to the end of the "file" as suggested in http://jira.qos.ch/browse/LOGBACK-740
    sb.append("\t<contextListener class=\"ch.qos.logback.classic.jul.LevelChangePropagator\">\n");
    sb.append("\t\t<resetJUL>true</resetJUL>\n");
    sb.append("\t</contextListener>\n");
    sb.append("</configuration>");
    return sb.toString();
}
Also used : SyslogAppenderConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.SyslogAppenderConfigurationType) FileAppenderConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.FileAppenderConfigurationType) AppenderConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.AppenderConfigurationType) ClassLoggerConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ClassLoggerConfigurationType) SubSystemLoggerConfigurationType(com.evolveum.midpoint.xml.ns._public.common.common_3.SubSystemLoggerConfigurationType)

Aggregations

OperationResult (com.evolveum.midpoint.schema.result.OperationResult)11 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)8 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)7 Task (com.evolveum.midpoint.task.api.Task)6 ObjectReferenceType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType)6 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)5 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)5 QName (javax.xml.namespace.QName)5 SystemException (com.evolveum.midpoint.util.exception.SystemException)4 com.evolveum.midpoint.prism (com.evolveum.midpoint.prism)3 ItemDefinition (com.evolveum.midpoint.prism.ItemDefinition)3 PrismObject (com.evolveum.midpoint.prism.PrismObject)3 SchemaConstants (com.evolveum.midpoint.schema.constants.SchemaConstants)3 Trace (com.evolveum.midpoint.util.logging.Trace)3 TraceManager (com.evolveum.midpoint.util.logging.TraceManager)3 com.evolveum.midpoint.xml.ns._public.common.common_3 (com.evolveum.midpoint.xml.ns._public.common.common_3)3 CredentialsCapabilityType (com.evolveum.midpoint.xml.ns._public.resource.capabilities_3.CredentialsCapabilityType)3 Collection (java.util.Collection)3 List (java.util.List)3 SynchronizationPolicyDecision (com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision)2