Search in sources :

Example 6 with SKIP

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

the class AccountActivationNotifier method checkApplicability.

@Override
protected boolean checkApplicability(Event event, GeneralNotifierType generalNotifierType, OperationResult result) {
    if (!event.isSuccess()) {
        LOGGER.trace("Operation was not successful, exiting.");
        return false;
    }
    ModelEvent modelEvent = (ModelEvent) event;
    if (modelEvent.getFocusDeltas().isEmpty()) {
        LOGGER.trace("No user deltas in event, exiting.");
        return false;
    }
    List<ShadowType> shadows = getShadowsToActivate(modelEvent);
    if (shadows.isEmpty()) {
        LOGGER.trace("No shadows to activate found in model context. Skip sending notifications.");
        return false;
    }
    LOGGER.trace("Found shadows to activate: {}. Skip sending notifications.", shadows);
    return true;
}
Also used : ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) ModelEvent(com.evolveum.midpoint.notifications.api.events.ModelEvent)

Example 7 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 task, @NotNull OperationResult 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(OP_INVOKE);
    result.addParam("task", task.toString());
    result.addArbitraryObjectAsContext("model state", context.getState());
    try {
        WfConfigurationType wfConfigurationType = configurationHelper.getWorkflowConfiguration(context, result);
        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_INIT_URI.equals(context.getChannel())) {
            LOGGER.debug("Skipping workflow processing because the channel is '" + SchemaConstants.CHANNEL_INIT_URI + "'.");
            result.recordSuccess();
            return HookOperationMode.FOREGROUND;
        }
        logOperationInformation(context);
        HookOperationMode retval = processModelInvocation(context, wfConfigurationType, task, result);
        result.computeStatus();
        if (retval == HookOperationMode.FOREGROUND) {
            result.setMinor();
        }
        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 8 with SKIP

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

the class ReconciliationProcessor method reconcileProjectionAttribute.

private <T> void reconcileProjectionAttribute(QName attrName, LensProjectionContext projCtx, Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> squeezedAttributes, PrismContainer attributesContainer) throws SchemaException {
    LOGGER.trace("Attribute reconciliation processing attribute {}", attrName);
    // noinspection unchecked
    ResourceAttributeDefinition<T> attributeDefinition = (ResourceAttributeDefinition<T>) projCtx.findAttributeDefinition(attrName);
    if (attributeDefinition == null) {
        throw new SchemaException("No definition for attribute " + attrName + " in " + projCtx.getResourceShadowDiscriminator());
    }
    DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<T>, PrismPropertyDefinition<T>>> pvwoTriple = squeezedAttributes != null ? (DeltaSetTriple) squeezedAttributes.get(attrName) : null;
    if (attributeDefinition.isIgnored(LayerType.MODEL)) {
        LOGGER.trace("Skipping reconciliation of attribute {} because it is ignored", attrName);
        return;
    }
    PropertyLimitations limitations = attributeDefinition.getLimitations(LayerType.MODEL);
    if (limitations != null) {
        PropertyAccessType access = limitations.getAccess();
        if (access != null) {
            if (projCtx.isAdd() && (access.isAdd() == null || !access.isAdd())) {
                LOGGER.trace("Skipping reconciliation of attribute {} because it is non-createable", attrName);
                return;
            }
            if (projCtx.isModify() && (access.isModify() == null || !access.isModify())) {
                LOGGER.trace("Skipping reconciliation of attribute {} because it is non-updateable", attrName);
                return;
            }
        }
    }
    Collection<ItemValueWithOrigin<PrismPropertyValue<T>, PrismPropertyDefinition<T>>> shouldBePValues;
    if (pvwoTriple == null) {
        shouldBePValues = new HashSet<>();
    } else {
        shouldBePValues = new HashSet<>(selectValidValues(pvwoTriple.getNonNegativeValues()));
    }
    // We consider values explicitly requested by user to be among "should be values".
    addPropValuesFromDelta(shouldBePValues, projCtx.getPrimaryDelta(), attrName);
    // But we DO NOT take values from sync delta (because they just reflect what's on the resource),
    // nor from secondary delta (because these got there from mappings).
    boolean hasStrongShouldBePValue = false;
    boolean hasOtherNonWeakValues = false;
    for (ItemValueWithOrigin<? extends PrismPropertyValue<T>, PrismPropertyDefinition<T>> shouldBePValue : shouldBePValues) {
        if (shouldBePValue.getMapping() != null) {
            if (shouldBePValue.getMapping().getStrength() == MappingStrengthType.STRONG) {
                hasStrongShouldBePValue = true;
                hasOtherNonWeakValues = true;
                break;
            }
            if (shouldBePValue.getMapping().getStrength() == null || shouldBePValue.getMapping().getStrength() == MappingStrengthType.NORMAL) {
                hasOtherNonWeakValues = true;
            }
        }
    }
    // noinspection unchecked
    PrismProperty<T> attribute = attributesContainer.findProperty(ItemName.fromQName(attrName));
    Collection<PrismPropertyValue<T>> arePValues;
    if (attribute != null) {
        arePValues = attribute.getValues();
    } else {
        arePValues = new HashSet<>();
    }
    // Too loud :-)
    // if (LOGGER.isTraceEnabled()) {
    // StringBuilder sb = new StringBuilder();
    // sb.append("Reconciliation\nATTR: ").append(PrettyPrinter.prettyPrint(attrName));
    // sb.append("\n  Should be:");
    // for (ItemValueWithOrigin<?,?> shouldBePValue : shouldBePValues) {
    // sb.append("\n    ");
    // sb.append(shouldBePValue.getItemValue());
    // PrismValueDeltaSetTripleProducer<?, ?> shouldBeMapping = shouldBePValue.getMapping();
    // if (shouldBeMapping.getStrength() == MappingStrengthType.STRONG) {
    // sb.append(" STRONG");
    // }
    // if (shouldBeMapping.getStrength() == MappingStrengthType.WEAK) {
    // sb.append(" WEAK");
    // }
    // if (!shouldBePValue.isValid()) {
    // sb.append(" INVALID");
    // }
    // }
    // sb.append("\n  Is:");
    // for (PrismPropertyValue<Object> isPVal : arePValues) {
    // sb.append("\n    ");
    // sb.append(isPVal);
    // }
    // LOGGER.trace("{}", sb.toString());
    // }
    ValueMatcher<T> valueMatcher = ValueMatcher.createMatcher(attributeDefinition, matchingRuleRegistry);
    T realValueToReplace = null;
    boolean hasRealValueToReplace = false;
    for (ItemValueWithOrigin<? extends PrismPropertyValue<T>, PrismPropertyDefinition<T>> shouldBePvwo : shouldBePValues) {
        PrismPropertyValue<T> shouldBePrismValue = shouldBePvwo.getItemValue();
        // probably too careful (the value should not be null, shouldn't it?)
        T shouldBeRealValue = shouldBePrismValue != null ? shouldBePrismValue.getValue() : null;
        PrismValueDeltaSetTripleProducer<?, ?> shouldBeMapping = shouldBePvwo.getMapping();
        if (shouldBeMapping == null) {
            LOGGER.trace("Skipping reconciliation of value {} of the attribute {}: no origin mapping", shouldBeRealValue, attributeDefinition.getItemName().getLocalPart());
            continue;
        }
        if (shouldBeMapping.getStrength() != MappingStrengthType.STRONG && (!arePValues.isEmpty() || hasStrongShouldBePValue)) {
            // Weak or normal value and the attribute already has a value. Skip it.
            // We cannot override it as it might have been legally changed directly on the projection resource object
            LOGGER.trace("Skipping reconciliation of value {} of the attribute {}: the mapping is not strong", shouldBeRealValue, attributeDefinition.getItemName().getLocalPart());
            continue;
        }
        if (!isInValues(valueMatcher, shouldBeRealValue, arePValues)) {
            if (attributeDefinition.isSingleValue()) {
                // TODO generalize this a bit (e.g. also for multivalued items)
                if (hasRealValueToReplace) {
                    if (matchValue(shouldBeRealValue, realValueToReplace, valueMatcher)) {
                        LOGGER.trace("Value to replace for {} is already set, skipping it: {}", attrName, realValueToReplace);
                        continue;
                    } else {
                        String message = "Attempt to set more than one value for single-valued attribute " + attrName + " in " + projCtx.getResourceShadowDiscriminator();
                        LOGGER.debug("{}: value to be added: {}, existing value to replace: {}", message, shouldBeMapping, realValueToReplace);
                        throw new SchemaException(message);
                    }
                }
                hasRealValueToReplace = true;
                realValueToReplace = shouldBeRealValue;
                recordDelta(valueMatcher, projCtx, SchemaConstants.PATH_ATTRIBUTES, attributeDefinition, ModificationType.REPLACE, shouldBeRealValue, shouldBePvwo.getSource(), "it is given by a mapping");
            } else {
                recordDelta(valueMatcher, projCtx, SchemaConstants.PATH_ATTRIBUTES, attributeDefinition, ModificationType.ADD, shouldBeRealValue, shouldBePvwo.getSource(), "it is given by a mapping");
            }
        } else {
            LOGGER.trace("Value is already present in {}, skipping it: {}", attrName, shouldBeRealValue);
        }
    }
    decideIfTolerate(projCtx, attributeDefinition, arePValues, shouldBePValues, valueMatcher, hasOtherNonWeakValues);
}
Also used : PropertyAccessType(com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyAccessType)

Example 9 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, @NotNull Predicate<OrgType> predicate, boolean preAuthorized) throws SchemaException, SecurityViolationException {
    List<ObjectReferenceType> parentOrgRefs = object.getParentOrgRef();
    List<OrgType> parentOrgs = new ArrayList<>(parentOrgRefs.size());
    for (ObjectReferenceType parentOrgRef : parentOrgRefs) {
        if (!prismContext.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 (predicate.test(parentOrg)) {
            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 10 with SKIP

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

the class SqaleAuditService method iterativeSearchCondition.

/**
 * Similar to {@link SqaleRepositoryService#lastOidCondition}.
 *
 * TODO, lots of possible improvements:
 *
 * * Just like in repo iterative search this is added to the original filter with `AND`.
 * However, if `timestamp` is used in the original filter, it could be replaced by stricter
 * `timestamp` condition based on the `lastProcessedObject` - this is not implemented yet.
 * ** TODO: If provided, do we want to add another timestamp condition?
 * Would it help with partitions?
 * Probably, with ID condition + ordering, it's not a big deal to leave it out.
 *
 * * Support for multiple order specifications from the client is not supported.
 * Perhaps some short-term stateful filter/order object would be better to construct this,
 * especially if it could be used in both repo and audit (with strict order attribute
 * provided in constructor for example).
 *
 * [NOTE]
 * ====
 * Both `timestamp` and `repoId` is used for iterative search condition, but *only `repoId`*
 * is used for additional ordering to assure strict reliable ordering.
 * This can be further complicated by the fact that both `repoId` and `timestamp`
 * can be part of custom ordering from client (this is different from repository, where `oid`
 * is not valid for filter and ordering on the model level, even when it's usable for repository).
 * If used on the top-level `AND` group, they can be be replaced by next iteration condition,
 * which is likely more selective.
 *
 * As for the ordering, if multiple ordering is used (*not supported yet*) if `repoId` is used,
 * anything after it can be omitted as irrelevant.
 * ====
 *
 * TODO: Currently, single path ordering is supported. Finish multi-path too.
 * TODO: What about nullable columns?
 */
@Nullable
private ObjectFilter iterativeSearchCondition(@Nullable AuditEventRecordType lastProcessedObject, List<? extends ObjectOrdering> providedOrdering) {
    if (lastProcessedObject == null) {
        return null;
    }
    // TODO inspect originalFilter to detect timestamp/repoId conditions.
    // Only top level AND filter should be checked, anything else is irrelevant
    // for the decision whether to skip additional timestamp condition.
    // BTW: We CANNOT skip repoId condition, that one is CRITICAL for proper iterating.
    Long lastProcessedId = lastProcessedObject.getRepoId();
    XMLGregorianCalendar lastProcessedTimestamp = lastProcessedObject.getTimestamp();
    if (providedOrdering == null || providedOrdering.isEmpty()) {
        return prismContext().queryFor(AuditEventRecordType.class).item(AuditEventRecordType.F_REPO_ID).gt(lastProcessedId).and().item(AuditEventRecordType.F_TIMESTAMP).ge(lastProcessedTimestamp).buildFilter();
    }
    if (providedOrdering.size() == 1) {
        ObjectOrdering objectOrdering = providedOrdering.get(0);
        ItemPath orderByPath = objectOrdering.getOrderBy();
        boolean asc = objectOrdering.getDirection() == OrderDirection.ASCENDING;
        S_ConditionEntry filter = prismContext().queryFor(AuditEventRecordType.class).item(orderByPath);
        @SuppressWarnings("unchecked") Item<PrismValue, ItemDefinition<?>> item = lastProcessedObject.asPrismContainerValue().findItem(orderByPath);
        if (item.size() > 1) {
            throw new IllegalArgumentException("Multi-value property for ordering is forbidden - item: " + item);
        } else if (item.isEmpty()) {
        // TODO what if it's nullable? is it null-first or last?
        // See: https://www.postgresql.org/docs/13/queries-order.html
        // "By default, null values sort as if larger than any non-null value; that is,
        // NULLS FIRST is the default for DESC order, and NULLS LAST otherwise."
        } else {
            S_MatchingRuleEntry matchingRuleEntry = asc ? filter.gt(item.getRealValue()) : filter.lt(item.getRealValue());
            filter = matchingRuleEntry.or().block().item(orderByPath).eq(item.getRealValue()).and().item(AuditEventRecordType.F_REPO_ID);
            return (asc ? filter.gt(lastProcessedId) : filter.lt(lastProcessedId)).endBlock().buildFilter();
        }
    }
    throw new IllegalArgumentException("Shouldn't get here with check in executeSearchObjectsIterative()");
}
Also used : S_ConditionEntry(com.evolveum.midpoint.prism.query.builder.S_ConditionEntry) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) S_MatchingRuleEntry(com.evolveum.midpoint.prism.query.builder.S_MatchingRuleEntry) PrismValue(com.evolveum.midpoint.prism.PrismValue) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) AuditEventRecordType(com.evolveum.midpoint.xml.ns._public.common.audit_3.AuditEventRecordType) CanonicalItemPath(com.evolveum.midpoint.prism.path.CanonicalItemPath) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) Nullable(org.jetbrains.annotations.Nullable)

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