Search in sources :

Example 1 with RefinedAttributeDefinition

use of com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition in project midpoint by Evolveum.

the class OutboundProcessor method processOutbound.

public <F extends FocusType> void processOutbound(LensContext<F> context, LensProjectionContext projCtx, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException {
    ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
    ObjectDelta<ShadowType> projectionDelta = projCtx.getDelta();
    if (projectionDelta != null && projectionDelta.getChangeType() == ChangeType.DELETE) {
        LOGGER.trace("Processing outbound expressions for {} skipped, DELETE account delta", discr);
        // No point in evaluating outbound
        return;
    }
    LOGGER.trace("Processing outbound expressions for {} starting", discr);
    RefinedObjectClassDefinition rOcDef = projCtx.getStructuralObjectClassDefinition();
    if (rOcDef == null) {
        LOGGER.error("Definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
        throw new IllegalStateException("Definition for " + discr + " not found in the context, but it should be there");
    }
    ObjectDeltaObject<F> focusOdo = context.getFocusContext().getObjectDeltaObject();
    ObjectDeltaObject<ShadowType> projectionOdo = projCtx.getObjectDeltaObject();
    Construction<F> outboundConstruction = new Construction<>(null, projCtx.getResource());
    outboundConstruction.setRefinedObjectClassDefinition(rOcDef);
    Collection<RefinedObjectClassDefinition> auxiliaryObjectClassDefinitions = rOcDef.getAuxiliaryObjectClassDefinitions();
    if (auxiliaryObjectClassDefinitions != null) {
        for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : auxiliaryObjectClassDefinitions) {
            outboundConstruction.addAuxiliaryObjectClassDefinition(auxiliaryObjectClassDefinition);
        }
    }
    String operation = projCtx.getOperation().getValue();
    for (QName attributeName : rOcDef.getNamesOfAttributesWithOutboundExpressions()) {
        RefinedAttributeDefinition<?> refinedAttributeDefinition = rOcDef.findAttributeDefinition(attributeName);
        final MappingType outboundMappingType = refinedAttributeDefinition.getOutboundMappingType();
        if (outboundMappingType == null) {
            continue;
        }
        if (refinedAttributeDefinition.isIgnored(LayerType.MODEL)) {
            LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", attributeName);
            continue;
        }
        Mapping.Builder<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> builder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(refinedAttributeDefinition.getName()) + " in " + rOcDef.getResourceType());
        builder = builder.originObject(rOcDef.getResourceType()).originType(OriginType.OUTBOUND);
        Mapping<PrismPropertyValue<?>, RefinedAttributeDefinition<?>> evaluatedMapping = evaluateMapping(builder, attributeName, refinedAttributeDefinition, focusOdo, projectionOdo, operation, rOcDef, null, context, projCtx, task, result);
        if (evaluatedMapping != null) {
            outboundConstruction.addAttributeMapping(evaluatedMapping);
        }
    }
    for (QName assocName : rOcDef.getNamesOfAssociationsWithOutboundExpressions()) {
        RefinedAssociationDefinition associationDefinition = rOcDef.findAssociationDefinition(assocName);
        final MappingType outboundMappingType = associationDefinition.getOutboundMappingType();
        if (outboundMappingType == null) {
            continue;
        }
        //			if (associationDefinition.isIgnored(LayerType.MODEL)) {
        //				LOGGER.trace("Skipping processing outbound mapping for attribute {} because it is ignored", assocName);
        //				continue;
        //			}
        Mapping.Builder<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> mappingBuilder = mappingFactory.createMappingBuilder(outboundMappingType, "outbound mapping for " + PrettyPrinter.prettyPrint(associationDefinition.getName()) + " in " + rOcDef.getResourceType());
        PrismContainerDefinition<ShadowAssociationType> outputDefinition = getAssociationContainerDefinition();
        Mapping<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>> evaluatedMapping = (Mapping) evaluateMapping(mappingBuilder, assocName, outputDefinition, focusOdo, projectionOdo, operation, rOcDef, associationDefinition.getAssociationTarget(), context, projCtx, task, result);
        if (evaluatedMapping != null) {
            outboundConstruction.addAssociationMapping(evaluatedMapping);
        }
    }
    projCtx.setOutboundConstruction(outboundConstruction);
}
Also used : MappingType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingType) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) RefinedAssociationDefinition(com.evolveum.midpoint.common.refinery.RefinedAssociationDefinition) RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) Construction(com.evolveum.midpoint.model.impl.lens.Construction) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) QName(javax.xml.namespace.QName) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 2 with RefinedAttributeDefinition

use of com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition in project midpoint by Evolveum.

the class InboundProcessor method processInboundExpressionsForProjection.

private <F extends FocusType> void processInboundExpressionsForProjection(LensContext<F> context, LensProjectionContext projContext, RefinedObjectClassDefinition accountDefinition, ObjectDelta<ShadowType> aPrioriDelta, Task task, XMLGregorianCalendar now, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, ConfigurationException, CommunicationException, SecurityViolationException {
    if (aPrioriDelta == null && projContext.getObjectCurrent() == null) {
        LOGGER.trace("Nothing to process in inbound, both a priori delta and current account were null.");
        return;
    }
    PrismObject<ShadowType> accountCurrent = projContext.getObjectCurrent();
    PrismObject<ShadowType> accountNew = projContext.getObjectNew();
    if (hasAnyStrongMapping(accountDefinition) && !projContext.isFullShadow() && !projContext.isThombstone()) {
        LOGGER.trace("There are strong inbound mapping, but the shadow hasn't be fully loaded yet. Trying to load full shadow now.");
        accountCurrent = loadProjection(context, projContext, task, result, accountCurrent);
        if (projContext.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
            return;
        }
    }
    for (QName accountAttributeName : accountDefinition.getNamesOfAttributesWithInboundExpressions()) {
        final PropertyDelta<?> attributeAPrioriDelta;
        if (aPrioriDelta != null) {
            attributeAPrioriDelta = aPrioriDelta.findPropertyDelta(new ItemPath(SchemaConstants.C_ATTRIBUTES), accountAttributeName);
            if (attributeAPrioriDelta == null && !projContext.isFullShadow() && !LensUtil.hasDependentContext(context, projContext)) {
                LOGGER.trace("Skipping inbound for {} in {}: Not a full shadow and account a priori delta exists, but doesn't have change for processed property.", accountAttributeName, projContext.getResourceShadowDiscriminator());
                continue;
            }
        } else {
            attributeAPrioriDelta = null;
        }
        RefinedAttributeDefinition attrDef = accountDefinition.findAttributeDefinition(accountAttributeName);
        if (attrDef.isIgnored(LayerType.MODEL)) {
            LOGGER.trace("Skipping inbound for attribute {} in {} because the attribute is ignored", PrettyPrinter.prettyPrint(accountAttributeName), projContext.getResourceShadowDiscriminator());
            continue;
        }
        List<MappingType> inboundMappingTypes = attrDef.getInboundMappingTypes();
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Processing inbound for {} in {}; ({} mappings)", PrettyPrinter.prettyPrint(accountAttributeName), projContext.getResourceShadowDiscriminator(), inboundMappingTypes.size());
        }
        if (!inboundMappingTypes.isEmpty()) {
            PropertyLimitations limitations = attrDef.getLimitations(LayerType.MODEL);
            if (limitations != null) {
                PropertyAccessType access = limitations.getAccess();
                if (access != null) {
                    if (access.isRead() == null || !access.isRead()) {
                        LOGGER.warn("Inbound mapping for non-readable attribute {} in {}, skipping", accountAttributeName, projContext.getHumanReadableName());
                        continue;
                    }
                }
            }
            for (MappingType inboundMappingType : inboundMappingTypes) {
                // we want to reconcile also the existing attribute value? This probably would not work.
                if (inboundMappingType.getStrength() == MappingStrengthType.STRONG) {
                    LOGGER.trace("There is an inbound mapping with strength == STRONG, trying to load full account now.");
                    if (!projContext.isFullShadow() && !projContext.isDelete()) {
                        accountCurrent = loadProjection(context, projContext, task, result, accountCurrent);
                        if (projContext.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
                            return;
                        }
                    }
                }
                if (attributeAPrioriDelta == null && !projContext.isFullShadow() && !LensUtil.hasDependentContext(context, projContext)) {
                    LOGGER.trace("Skipping inbound for {} in {}: Not a full shadow and account a priori delta exists, but doesn't have change for processed property.", accountAttributeName, projContext.getResourceShadowDiscriminator());
                    continue;
                }
                PrismObject<F> focus;
                if (context.getFocusContext().getObjectCurrent() != null) {
                    focus = context.getFocusContext().getObjectCurrent();
                } else {
                    focus = context.getFocusContext().getObjectNew();
                }
                ItemDelta focusItemDelta = null;
                if (attributeAPrioriDelta != null) {
                    LOGGER.trace("Processing inbound from a priori delta: {}", aPrioriDelta);
                    focusItemDelta = evaluateInboundMapping(context, inboundMappingType, accountAttributeName, null, attributeAPrioriDelta, focus, accountNew, projContext.getResource(), task, result);
                } else if (accountCurrent != null) {
                    if (!projContext.isFullShadow()) {
                        // todo change to trace level eventually
                        LOGGER.warn("Attempted to execute inbound expression on account shadow {} WITHOUT full account. Trying to load the account now.", projContext.getOid());
                        accountCurrent = loadProjection(context, projContext, task, result, accountCurrent);
                        if (projContext.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
                            return;
                        }
                        if (!projContext.isFullShadow()) {
                            if (projContext.getResourceShadowDiscriminator().getOrder() > 0) {
                                // higher-order context. It is OK not to load this
                                LOGGER.trace("Skipped load of higher-order account with shadow OID {} skipping inbound processing on it", projContext.getOid());
                                return;
                            }
                            // TODO: is it good to mark as broken? what is
                            // the resorce is down?? if there is no
                            // assignment and the account was added directly
                            // it can cause that the account will be
                            // unlinked from the user FIXME
                            LOGGER.warn("Couldn't load account with shadow OID {}, setting context as broken and skipping inbound processing on it", projContext.getOid());
                            projContext.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.BROKEN);
                            return;
                        }
                    }
                    PrismProperty<?> oldAccountProperty = accountCurrent.findProperty(new ItemPath(ShadowType.F_ATTRIBUTES, accountAttributeName));
                    LOGGER.trace("Processing inbound from account sync absolute state (currentAccount): {}", oldAccountProperty);
                    focusItemDelta = evaluateInboundMapping(context, inboundMappingType, accountAttributeName, oldAccountProperty, null, focus, accountNew, projContext.getResource(), task, result);
                }
                if (focusItemDelta != null && !focusItemDelta.isEmpty()) {
                    if (LOGGER.isTraceEnabled()) {
                        LOGGER.trace("Created delta (from inbound expression for {} on {})\n{}", accountAttributeName, projContext.getResource(), focusItemDelta.debugDump(1));
                    }
                    context.getFocusContext().swallowToProjectionWaveSecondaryDelta(focusItemDelta);
                    context.recomputeFocus();
                } else {
                    LOGGER.trace("Created delta (from inbound expression for {} on {}) was null or empty.", accountAttributeName, projContext.getResource());
                }
            }
        }
    }
    if (isDeleteAccountDelta(projContext)) {
        // we don't need to do inbound if account was deleted
        return;
    }
    processSpecialPropertyInbound(accountDefinition.getPasswordInbound(), SchemaConstants.PATH_PASSWORD_VALUE, context.getFocusContext().getObjectNew(), projContext, accountDefinition, context, task, now, result);
    processSpecialPropertyInbound(accountDefinition.getActivationBidirectionalMappingType(ActivationType.F_ADMINISTRATIVE_STATUS), SchemaConstants.PATH_ACTIVATION_ADMINISTRATIVE_STATUS, context.getFocusContext().getObjectNew(), projContext, accountDefinition, context, task, now, result);
    processSpecialPropertyInbound(accountDefinition.getActivationBidirectionalMappingType(ActivationType.F_VALID_FROM), SchemaConstants.PATH_ACTIVATION_VALID_FROM, context.getFocusContext().getObjectNew(), projContext, accountDefinition, context, task, now, result);
    processSpecialPropertyInbound(accountDefinition.getActivationBidirectionalMappingType(ActivationType.F_VALID_TO), SchemaConstants.PATH_ACTIVATION_VALID_TO, context.getFocusContext().getObjectNew(), projContext, accountDefinition, context, task, now, result);
}
Also used : QName(javax.xml.namespace.QName) PropertyLimitations(com.evolveum.midpoint.common.refinery.PropertyLimitations) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 3 with RefinedAttributeDefinition

use of com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition in project midpoint by Evolveum.

the class ProjectionValuesProcessor method checkSchemaAndPolicies.

/**
	 * Check that the primary deltas do not violate schema and policies
	 * TODO: implement schema check 
	 */
public <F extends ObjectType> void checkSchemaAndPolicies(LensContext<F> context, LensProjectionContext accountContext, String activityDescription, OperationResult result) throws SchemaException, PolicyViolationException {
    ObjectDelta<ShadowType> primaryDelta = accountContext.getPrimaryDelta();
    if (primaryDelta == null || primaryDelta.isDelete()) {
        return;
    }
    RefinedObjectClassDefinition rAccountDef = accountContext.getCompositeObjectClassDefinition();
    if (rAccountDef == null) {
        throw new SchemaException("No definition for account type '" + accountContext.getResourceShadowDiscriminator() + "' in " + accountContext.getResource());
    }
    if (primaryDelta.isAdd()) {
        PrismObject<ShadowType> accountToAdd = primaryDelta.getObjectToAdd();
        ResourceAttributeContainer attributesContainer = ShadowUtil.getAttributesContainer(accountToAdd);
        if (attributesContainer != null) {
            for (ResourceAttribute<?> attribute : attributesContainer.getAttributes()) {
                RefinedAttributeDefinition rAttrDef = rAccountDef.findAttributeDefinition(attribute.getElementName());
                if (!rAttrDef.isTolerant()) {
                    throw new PolicyViolationException("Attempt to add object with non-tolerant attribute " + attribute.getElementName() + " in " + "account " + accountContext.getResourceShadowDiscriminator() + " during " + activityDescription);
                }
            }
        }
    } else if (primaryDelta.isModify()) {
        for (ItemDelta<?, ?> modification : primaryDelta.getModifications()) {
            if (modification.getParentPath().equivalent(SchemaConstants.PATH_ATTRIBUTES)) {
                PropertyDelta<?> attrDelta = (PropertyDelta<?>) modification;
                RefinedAttributeDefinition rAttrDef = rAccountDef.findAttributeDefinition(attrDelta.getElementName());
                if (!rAttrDef.isTolerant()) {
                    throw new PolicyViolationException("Attempt to modify non-tolerant attribute " + attrDelta.getElementName() + " in " + "account " + accountContext.getResourceShadowDiscriminator() + " during " + activityDescription);
                }
            }
        }
    } else {
        throw new IllegalStateException("Whoops!");
    }
}
Also used : RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) ResourceAttributeContainer(com.evolveum.midpoint.schema.processor.ResourceAttributeContainer) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException)

Example 4 with RefinedAttributeDefinition

use of com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition in project midpoint by Evolveum.

the class ResourceObjectPattern method matches.

private boolean matches(ResourceAttribute<?> identifier, ResourceAttribute<?> attributeToMatch, MatchingRuleRegistry matchingRuleRegistry) throws SchemaException {
    if (!identifier.getElementName().equals(attributeToMatch.getElementName())) {
        return false;
    }
    RefinedAttributeDefinition rAttrDef = rOcDef.findAttributeDefinition(identifier.getElementName());
    QName matchingRuleQName = rAttrDef.getMatchingRuleQName();
    if (matchingRuleQName == null || matchingRuleRegistry == null) {
        return identifier.equalsRealValue(attributeToMatch);
    }
    MatchingRule<Object> matchingRule = matchingRuleRegistry.getMatchingRule(matchingRuleQName, rAttrDef.getTypeName());
    return matchingRule.match(identifier.getRealValue(), attributeToMatch.getRealValue());
}
Also used : QName(javax.xml.namespace.QName) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) PrismObject(com.evolveum.midpoint.prism.PrismObject)

Example 5 with RefinedAttributeDefinition

use of com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition in project midpoint by Evolveum.

the class AbstractModelImplementationIntegrationTest method createAccountDelta.

protected <T> ObjectDelta<ShadowType> createAccountDelta(LensProjectionContext accCtx, String accountOid, String attributeLocalName, T... propertyValues) throws SchemaException {
    ResourceType resourceType = accCtx.getResource();
    QName attrQName = new QName(ResourceTypeUtil.getResourceNamespace(resourceType), attributeLocalName);
    ItemPath attrPath = new ItemPath(ShadowType.F_ATTRIBUTES, attrQName);
    RefinedObjectClassDefinition refinedAccountDefinition = accCtx.getCompositeObjectClassDefinition();
    RefinedAttributeDefinition attrDef = refinedAccountDefinition.findAttributeDefinition(attrQName);
    assertNotNull("No definition of attribute " + attrQName + " in account def " + refinedAccountDefinition, attrDef);
    ObjectDelta<ShadowType> accountDelta = ObjectDelta.createEmptyModifyDelta(ShadowType.class, accountOid, prismContext);
    PropertyDelta<T> attrDelta = new PropertyDelta<T>(attrPath, attrDef, prismContext);
    attrDelta.setValuesToReplace(PrismPropertyValue.createCollection(propertyValues));
    accountDelta.addModification(attrDelta);
    return accountDelta;
}
Also used : RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) QName(javax.xml.namespace.QName) RefinedAttributeDefinition(com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Aggregations

RefinedAttributeDefinition (com.evolveum.midpoint.common.refinery.RefinedAttributeDefinition)28 RefinedObjectClassDefinition (com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition)12 QName (javax.xml.namespace.QName)10 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)8 RefinedResourceSchema (com.evolveum.midpoint.common.refinery.RefinedResourceSchema)6 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)5 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)5 PropertyLimitations (com.evolveum.midpoint.common.refinery.PropertyLimitations)4 PropertyDelta (com.evolveum.midpoint.prism.delta.PropertyDelta)4 ResourceAttributeContainer (com.evolveum.midpoint.schema.processor.ResourceAttributeContainer)4 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)4 PrismObject (com.evolveum.midpoint.prism.PrismObject)3 ItemDelta (com.evolveum.midpoint.prism.delta.ItemDelta)3 PropertyAccessType (com.evolveum.midpoint.xml.ns._public.common.common_3.PropertyAccessType)3 PrismPropertyDefinition (com.evolveum.midpoint.prism.PrismPropertyDefinition)2 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)2 ObjectQuery (com.evolveum.midpoint.prism.query.ObjectQuery)2 PrismAsserts.assertEqualsPolyString (com.evolveum.midpoint.prism.util.PrismAsserts.assertEqualsPolyString)2 SecurityViolationException (com.evolveum.midpoint.util.exception.SecurityViolationException)2 SystemException (com.evolveum.midpoint.util.exception.SystemException)2