Search in sources :

Example 41 with PrismContainerValue

use of com.evolveum.midpoint.prism.PrismContainerValue in project midpoint by Evolveum.

the class AddAssociationAspect method getApprovalRequestsFromShadowModify.

private List<ApprovalRequest<AssociationAdditionType>> getApprovalRequestsFromShadowModify(PcpAspectConfigurationType config, PrismObject<ShadowType> shadowOld, ObjectDelta<ShadowType> change, ResourceShadowDiscriminator rsd, ModelContext<?> modelContext, Task taskFromModel, OperationResult result) {
    LOGGER.trace("Relevant associations in shadow modify delta:");
    List<ApprovalRequest<AssociationAdditionType>> approvalRequestList = new ArrayList<>();
    Iterator<? extends ItemDelta> deltaIterator = change.getModifications().iterator();
    final ItemPath ASSOCIATION_PATH = new ItemPath(ShadowType.F_ASSOCIATION);
    while (deltaIterator.hasNext()) {
        ItemDelta delta = deltaIterator.next();
        if (!ASSOCIATION_PATH.equivalent(delta.getPath())) {
            continue;
        }
        if (delta.getValuesToAdd() != null && !delta.getValuesToAdd().isEmpty()) {
            Iterator<PrismContainerValue<ShadowAssociationType>> valueIterator = delta.getValuesToAdd().iterator();
            while (valueIterator.hasNext()) {
                PrismContainerValue<ShadowAssociationType> association = valueIterator.next();
                ApprovalRequest<AssociationAdditionType> req = processAssociationToAdd(config, association, rsd, modelContext, taskFromModel, result);
                if (req != null) {
                    approvalRequestList.add(req);
                    valueIterator.remove();
                }
            }
        }
        if (delta.getValuesToReplace() != null && !delta.getValuesToReplace().isEmpty()) {
            Iterator<PrismContainerValue<ShadowAssociationType>> valueIterator = delta.getValuesToReplace().iterator();
            while (valueIterator.hasNext()) {
                PrismContainerValue<ShadowAssociationType> association = valueIterator.next();
                if (existsEquivalentValue(shadowOld, association)) {
                    continue;
                }
                ApprovalRequest<AssociationAdditionType> req = processAssociationToAdd(config, association, rsd, modelContext, taskFromModel, result);
                if (req != null) {
                    approvalRequestList.add(req);
                    valueIterator.remove();
                }
            }
        }
        // let's sanitize the delta
        if (delta.getValuesToAdd() != null && delta.getValuesToAdd().isEmpty()) {
            // empty set of values to add is an illegal state
            delta.resetValuesToAdd();
        }
        if (delta.getValuesToAdd() == null && delta.getValuesToReplace() == null && delta.getValuesToDelete() == null) {
            deltaIterator.remove();
        }
    }
    return approvalRequestList;
}
Also used : PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) ApprovalRequest(com.evolveum.midpoint.wf.impl.processes.itemApproval.ApprovalRequest) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 42 with PrismContainerValue

use of com.evolveum.midpoint.prism.PrismContainerValue in project midpoint by Evolveum.

the class AccCertCaseOperationsHelper method getDeltasToCreateCases.

<F extends FocusType> List<ItemDelta<?, ?>> getDeltasToCreateCases(final AccessCertificationCampaignType campaign, AccessCertificationStageType stage, final CertificationHandler handler, final Task task, final OperationResult result) throws SchemaException, ObjectNotFoundException {
    final List<ItemDelta<?, ?>> rv = new ArrayList<>();
    final String campaignShortName = toShortString(campaign);
    final AccessCertificationScopeType scope = campaign.getScopeDefinition();
    LOGGER.trace("Creating cases for scope {} in campaign {}", scope, campaignShortName);
    if (scope != null && !(scope instanceof AccessCertificationObjectBasedScopeType)) {
        throw new IllegalStateException("Unsupported access certification scope type: " + scope.getClass() + " for campaign " + campaignShortName);
    }
    final AccessCertificationObjectBasedScopeType objectBasedScope = (AccessCertificationObjectBasedScopeType) scope;
    final List<AccessCertificationCaseType> existingCases = queryHelper.searchCases(campaign.getOid(), null, null, result);
    if (!existingCases.isEmpty()) {
        throw new IllegalStateException("Unexpected " + existingCases.size() + " certification case(s) in campaign object " + campaignShortName + ". At this time there should be none.");
    }
    // create a query to find target objects from which certification cases will be created
    final ObjectQuery query = new ObjectQuery();
    final QName scopeDeclaredObjectType;
    if (objectBasedScope != null) {
        scopeDeclaredObjectType = objectBasedScope.getObjectType();
    } else {
        scopeDeclaredObjectType = null;
    }
    final QName objectType;
    if (scopeDeclaredObjectType != null) {
        objectType = scopeDeclaredObjectType;
    } else {
        objectType = handler.getDefaultObjectType();
    }
    if (objectType == null) {
        throw new IllegalStateException("Unspecified object type (and no default one provided) for campaign " + campaignShortName);
    }
    @SuppressWarnings({ "unchecked", "raw" }) final Class<F> objectClass = (Class<F>) prismContext.getSchemaRegistry().getCompileTimeClassForObjectType(objectType);
    if (objectClass == null) {
        throw new IllegalStateException("Object class not found for object type " + objectType + " in campaign " + campaignShortName);
    }
    final SearchFilterType searchFilter = objectBasedScope != null ? objectBasedScope.getSearchFilter() : null;
    if (searchFilter != null) {
        ObjectFilter filter = QueryConvertor.parseFilter(searchFilter, objectClass, prismContext);
        query.setFilter(filter);
    }
    final List<AccessCertificationCaseType> caseList = new ArrayList<>();
    // create certification cases by executing the query and caseExpression on its results
    // here the subclasses of this class come into play
    ResultHandler<F> resultHandler = (object, parentResult) -> {
        try {
            caseList.addAll(handler.createCasesForObject(object, campaign, task, parentResult));
        } catch (ExpressionEvaluationException | ObjectNotFoundException | SchemaException e) {
            // TODO process the exception more intelligently
            throw new SystemException("Cannot create certification case for object " + toShortString(object.asObjectable()) + ": " + e.getMessage(), e);
        }
        return true;
    };
    repositoryService.searchObjectsIterative(objectClass, query, resultHandler, null, false, result);
    AccessCertificationReviewerSpecificationType reviewerSpec = reviewersHelper.findReviewersSpecification(campaign, 1, task, result);
    ContainerDelta<AccessCertificationCaseType> caseDelta = ContainerDelta.createDelta(F_CASE, AccessCertificationCampaignType.class, prismContext);
    for (AccessCertificationCaseType _case : caseList) {
        _case.setStageNumber(1);
        _case.setCurrentStageCreateTimestamp(stage.getStartTimestamp());
        _case.setCurrentStageDeadline(stage.getDeadline());
        List<ObjectReferenceType> reviewers = reviewersHelper.getReviewersForCase(_case, campaign, reviewerSpec, task, result);
        _case.getWorkItem().addAll(createWorkItems(reviewers, 1));
        String currentStageOutcome = OutcomeUtils.toUri(computationHelper.computeOutcomeForStage(_case, campaign, 1));
        _case.setCurrentStageOutcome(currentStageOutcome);
        _case.setOutcome(OutcomeUtils.toUri(computationHelper.computeOverallOutcome(_case, campaign, currentStageOutcome)));
        @SuppressWarnings({ "raw", "unchecked" }) PrismContainerValue<AccessCertificationCaseType> caseCVal = _case.asPrismContainerValue();
        caseDelta.addValueToAdd(caseCVal);
        LOGGER.trace("Adding certification case:\n{}", caseCVal.debugDumpLazily());
    }
    rv.add(caseDelta);
    LOGGER.trace("Created {} deltas to create {} cases for campaign {}", rv.size(), caseList.size(), campaignShortName);
    return rv;
}
Also used : java.util(java.util) com.evolveum.midpoint.xml.ns._public.common.common_3(com.evolveum.midpoint.xml.ns._public.common.common_3) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) SecurityEnforcer(com.evolveum.midpoint.security.api.SecurityEnforcer) Autowired(org.springframework.beans.factory.annotation.Autowired) Trace(com.evolveum.midpoint.util.logging.Trace) com.evolveum.midpoint.util.exception(com.evolveum.midpoint.util.exception) ObjectFilter(com.evolveum.midpoint.prism.query.ObjectFilter) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ObjectTypeUtil(com.evolveum.midpoint.schema.util.ObjectTypeUtil) PrismContext(com.evolveum.midpoint.prism.PrismContext) Qualifier(org.springframework.beans.factory.annotation.Qualifier) F_CASE(com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCampaignType.F_CASE) RepositoryService(com.evolveum.midpoint.repo.api.RepositoryService) ContainerDelta(com.evolveum.midpoint.prism.delta.ContainerDelta) CloneUtil(com.evolveum.midpoint.prism.util.CloneUtil) XmlTypeConverter(com.evolveum.midpoint.prism.xml.XmlTypeConverter) ResultHandler(com.evolveum.midpoint.schema.ResultHandler) DeltaBuilder(com.evolveum.midpoint.prism.delta.builder.DeltaBuilder) IdItemPathSegment(com.evolveum.midpoint.prism.path.IdItemPathSegment) Task(com.evolveum.midpoint.task.api.Task) XMLGregorianCalendar(javax.xml.datatype.XMLGregorianCalendar) CertCampaignTypeUtil(com.evolveum.midpoint.schema.util.CertCampaignTypeUtil) ObjectUtils(org.apache.commons.lang.ObjectUtils) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) QueryConvertor(com.evolveum.midpoint.prism.marshaller.QueryConvertor) Objects(java.util.Objects) Component(org.springframework.stereotype.Component) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) NameItemPathSegment(com.evolveum.midpoint.prism.path.NameItemPathSegment) SearchFilterType(com.evolveum.prism.xml.ns._public.query_3.SearchFilterType) CertificationHandler(com.evolveum.midpoint.certification.impl.handlers.CertificationHandler) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) ObjectQuery(com.evolveum.midpoint.prism.query.ObjectQuery) QName(javax.xml.namespace.QName) NotNull(org.jetbrains.annotations.NotNull) Clock(com.evolveum.midpoint.common.Clock) AccessCertificationCaseType(com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType) OutcomeUtils(com.evolveum.midpoint.certification.api.OutcomeUtils) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) ObjectTypeUtil.toShortString(com.evolveum.midpoint.schema.util.ObjectTypeUtil.toShortString) AccessCertificationCaseType(com.evolveum.midpoint.xml.ns._public.common.common_3.AccessCertificationCaseType) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ObjectTypeUtil.toShortString(com.evolveum.midpoint.schema.util.ObjectTypeUtil.toShortString) SearchFilterType(com.evolveum.prism.xml.ns._public.query_3.SearchFilterType) QName(javax.xml.namespace.QName) ObjectFilter(com.evolveum.midpoint.prism.query.ObjectFilter) ObjectQuery(com.evolveum.midpoint.prism.query.ObjectQuery)

Example 43 with PrismContainerValue

use of com.evolveum.midpoint.prism.PrismContainerValue in project midpoint by Evolveum.

the class ConsolidationProcessor method consolidateValuesToModifyDelta.

private <F extends FocusType> ObjectDelta<ShadowType> consolidateValuesToModifyDelta(LensContext<F> context, LensProjectionContext projCtx, boolean addUnchangedValues, Task task, OperationResult result) throws SchemaException, ExpressionEvaluationException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException {
    // "Squeeze" all the relevant mappings into a data structure that we can process conveniently. We want to have all the
    // (meta)data about relevant for a specific attribute in one data structure, not spread over several account constructions.
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> squeezedAttributes = sqeeze(projCtx, construction -> (Collection) construction.getAttributeMappings());
    projCtx.setSqueezedAttributes(squeezedAttributes);
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> squeezedAssociations = sqeeze(projCtx, construction -> construction.getAssociationMappings());
    projCtx.setSqueezedAssociations(squeezedAssociations);
    // So, we do it here - once and for all.
    if (!squeezedAssociations.isEmpty()) {
        fillInAssociationNames(squeezedAssociations);
    }
    MappingExtractor<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>, F> auxiliaryObjectClassExtractor = construction -> {
        PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> prod = new PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>() {

            @Override
            public QName getMappingQName() {
                return ShadowType.F_AUXILIARY_OBJECT_CLASS;
            }

            @Override
            public PrismValueDeltaSetTriple<PrismPropertyValue<QName>> getOutputTriple() {
                PrismValueDeltaSetTriple<PrismPropertyValue<QName>> triple = new PrismValueDeltaSetTriple<>();
                if (construction.getAuxiliaryObjectClassDefinitions() != null) {
                    for (RefinedObjectClassDefinition auxiliaryObjectClassDefinition : construction.getAuxiliaryObjectClassDefinitions()) {
                        triple.addToZeroSet(new PrismPropertyValue<QName>(auxiliaryObjectClassDefinition.getTypeName()));
                    }
                }
                return triple;
            }

            @Override
            public MappingStrengthType getStrength() {
                return MappingStrengthType.STRONG;
            }

            @Override
            public PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> clone() {
                return this;
            }

            @Override
            public boolean isExclusive() {
                return false;
            }

            @Override
            public boolean isAuthoritative() {
                return true;
            }

            @Override
            public boolean isSourceless() {
                return false;
            }
        };
        Collection<PrismValueDeltaSetTripleProducer<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> col = new ArrayList<>(1);
        col.add(prod);
        return col;
    };
    Map<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> squeezedAuxiliaryObjectClasses = sqeeze(projCtx, auxiliaryObjectClassExtractor);
    projCtx.setSqueezedAuxiliaryObjectClasses(squeezedAuxiliaryObjectClasses);
    ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
    ObjectDelta<ShadowType> objectDelta = new ObjectDelta<ShadowType>(ShadowType.class, ChangeType.MODIFY, prismContext);
    objectDelta.setOid(projCtx.getOid());
    // Let's be very very lazy about fetching the account from the resource.
    if (!projCtx.hasFullShadow() && (hasActiveWeakMapping(squeezedAttributes, projCtx) || hasActiveWeakMapping(squeezedAssociations, projCtx) || (hasActiveStrongMapping(squeezedAttributes, projCtx) || hasActiveStrongMapping(squeezedAssociations, projCtx)))) {
        // Full account was not yet loaded. This will cause problems as
        // the weak mapping may be applied even though it should not be
        // applied
        // and also same changes may be discarded because of unavailability
        // of all
        // account's attributes.Therefore load the account now, but with
        // doNotDiscovery options..
        // We also need to get account if there are strong mappings. Strong mappings
        // should always be applied. So reading the account now will indirectly
        // trigger reconciliation which makes sure that the strong mappings are
        // applied.
        // By getting accounts from provisioning, there might be a problem with
        // resource availability. We need to know, if the account was read full
        // or we have only the shadow from the repository. If we have only
        // shadow, the weak mappings may applied even if they should not be. 
        contextLoader.loadFullShadow(context, projCtx, "weak or strong mapping", task, result);
        if (projCtx.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
            return null;
        }
    }
    boolean completeAccount = projCtx.hasFullShadow();
    ObjectDelta<ShadowType> existingDelta = projCtx.getDelta();
    // AUXILIARY OBJECT CLASSES
    ItemPath auxiliaryObjectClassItemPath = new ItemPath(ShadowType.F_AUXILIARY_OBJECT_CLASS);
    PrismPropertyDefinition<QName> auxiliaryObjectClassPropertyDef = projCtx.getObjectDefinition().findPropertyDefinition(auxiliaryObjectClassItemPath);
    PropertyDelta<QName> auxiliaryObjectClassAPrioriDelta = null;
    RefinedResourceSchema refinedSchema = projCtx.getRefinedResourceSchema();
    List<QName> auxOcNames = new ArrayList<>();
    List<RefinedObjectClassDefinition> auxOcDefs = new ArrayList<>();
    ObjectDelta<ShadowType> projDelta = projCtx.getDelta();
    if (projDelta != null) {
        auxiliaryObjectClassAPrioriDelta = projDelta.findPropertyDelta(auxiliaryObjectClassItemPath);
    }
    for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>>> entry : squeezedAuxiliaryObjectClasses.entrySet()) {
        DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>>> ivwoTriple = entry.getValue();
        LOGGER.trace("CONSOLIDATE auxiliary object classes ({})", new Object[] { discr });
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Auxiliary object class triple:\n{}", ivwoTriple.debugDump());
        }
        for (ItemValueWithOrigin<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> ivwo : ivwoTriple.getAllValues()) {
            QName auxObjectClassName = ivwo.getItemValue().getValue();
            if (auxOcNames.contains(auxObjectClassName)) {
                continue;
            }
            auxOcNames.add(auxObjectClassName);
            RefinedObjectClassDefinition auxOcDef = refinedSchema.getRefinedDefinition(auxObjectClassName);
            if (auxOcDef == null) {
                LOGGER.error("Auxiliary object class definition {} for {} not found in the schema, but it should be there, dumping context:\n{}", auxObjectClassName, discr, context.debugDump());
                throw new IllegalStateException("Auxiliary object class definition " + auxObjectClassName + " for " + discr + " not found in the context, but it should be there");
            }
            auxOcDefs.add(auxOcDef);
        }
        ItemDelta<PrismPropertyValue<QName>, PrismPropertyDefinition<QName>> itemDelta = LensUtil.consolidateTripleToDelta(auxiliaryObjectClassItemPath, ivwoTriple, auxiliaryObjectClassPropertyDef, auxiliaryObjectClassAPrioriDelta, projCtx.getObjectNew(), null, null, addUnchangedValues, completeAccount, false, discr.toHumanReadableDescription(), false);
        PropertyDelta<QName> propDelta = (PropertyDelta) itemDelta;
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Auxiliary object class delta:\n{}", propDelta.debugDump());
        }
        if (!propDelta.isEmpty()) {
            objectDelta.addModification(propDelta);
        }
    }
    RefinedObjectClassDefinition structuralObjectClassDefinition = projCtx.getStructuralObjectClassDefinition();
    if (structuralObjectClassDefinition == null) {
        LOGGER.error("Structural object class definition for {} not found in the context, but it should be there, dumping context:\n{}", discr, context.debugDump());
        throw new IllegalStateException("Structural object class definition for " + discr + " not found in the context, but it should be there");
    }
    RefinedObjectClassDefinition rOcDef = new CompositeRefinedObjectClassDefinitionImpl(structuralObjectClassDefinition, auxOcDefs);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Object class definition for {} consolidation:\n{}", discr, rOcDef.debugDump());
    }
    // with the data in ItemValueWithOrigin triples.
    for (Map.Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>>> entry : squeezedAttributes.entrySet()) {
        QName attributeName = entry.getKey();
        DeltaSetTriple<ItemValueWithOrigin<PrismPropertyValue<?>, PrismPropertyDefinition<?>>> triple = entry.getValue();
        PropertyDelta<?> propDelta = consolidateAttribute(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, attributeName, (DeltaSetTriple) triple);
        if (propDelta != null) {
            objectDelta.addModification(propDelta);
        }
    }
    // ASSOCIATIONS
    for (Entry<QName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>>> entry : squeezedAssociations.entrySet()) {
        QName associationName = entry.getKey();
        DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>> triple = entry.getValue();
        ContainerDelta<ShadowAssociationType> containerDelta = consolidateAssociation(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeAccount, associationName, triple);
        if (containerDelta != null) {
            objectDelta.addModification(containerDelta);
        }
    }
    return objectDelta;
}
Also used : PrismValue(com.evolveum.midpoint.prism.PrismValue) Construction(com.evolveum.midpoint.model.impl.lens.Construction) ChangeType(com.evolveum.midpoint.prism.delta.ChangeType) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) Autowired(org.springframework.beans.factory.annotation.Autowired) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) com.evolveum.midpoint.common.refinery(com.evolveum.midpoint.common.refinery) LensContext(com.evolveum.midpoint.model.impl.lens.LensContext) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) Map(java.util.Map) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) PrismProperty(com.evolveum.midpoint.prism.PrismProperty) Mapping(com.evolveum.midpoint.model.common.mapping.Mapping) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) InternalsConfig.consistencyChecks(com.evolveum.midpoint.schema.internals.InternalsConfig.consistencyChecks) Collection(java.util.Collection) Task(com.evolveum.midpoint.task.api.Task) MatchingRuleRegistry(com.evolveum.midpoint.prism.match.MatchingRuleRegistry) ObjectUtils(org.apache.commons.lang.ObjectUtils) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) List(java.util.List) FocusType(com.evolveum.midpoint.xml.ns._public.common.common_3.FocusType) Entry(java.util.Map.Entry) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) QName(javax.xml.namespace.QName) MappingStrengthType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) ItemDefinition(com.evolveum.midpoint.prism.ItemDefinition) Trace(com.evolveum.midpoint.util.logging.Trace) HashMap(java.util.HashMap) ExpressionEvaluationException(com.evolveum.midpoint.util.exception.ExpressionEvaluationException) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) ArrayList(java.util.ArrayList) SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) PrismContext(com.evolveum.midpoint.prism.PrismContext) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) ContainerDelta(com.evolveum.midpoint.prism.delta.ContainerDelta) LensUtil(com.evolveum.midpoint.model.impl.lens.LensUtil) PrismPropertyDefinition(com.evolveum.midpoint.prism.PrismPropertyDefinition) Iterator(java.util.Iterator) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) PrismObject(com.evolveum.midpoint.prism.PrismObject) SynchronizationPolicyDecision(com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) Component(org.springframework.stereotype.Component) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) LayerType(com.evolveum.midpoint.xml.ns._public.common.common_3.LayerType) PrismReference(com.evolveum.midpoint.prism.PrismReference) Comparator(java.util.Comparator) TraceManager(com.evolveum.midpoint.util.logging.TraceManager) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) ArrayList(java.util.ArrayList) PropertyDelta(com.evolveum.midpoint.prism.delta.PropertyDelta) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) MappingStrengthType(com.evolveum.midpoint.xml.ns._public.common.common_3.MappingStrengthType) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) Collection(java.util.Collection) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) Map(java.util.Map) HashMap(java.util.HashMap) PrismPropertyDefinition(com.evolveum.midpoint.prism.PrismPropertyDefinition) PrismValueDeltaSetTripleProducer(com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) QName(javax.xml.namespace.QName) ShadowType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType) PrismContainerDefinition(com.evolveum.midpoint.prism.PrismContainerDefinition) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 44 with PrismContainerValue

use of com.evolveum.midpoint.prism.PrismContainerValue in project midpoint by Evolveum.

the class ConsolidationProcessor method consolidateAssociation.

private <V extends PrismValue> ContainerDelta<ShadowAssociationType> consolidateAssociation(RefinedObjectClassDefinition rOcDef, ResourceShadowDiscriminator discr, ObjectDelta<ShadowType> existingDelta, LensProjectionContext projCtx, boolean addUnchangedValues, boolean completeShadow, QName associationName, DeltaSetTriple<ItemValueWithOrigin<PrismContainerValue<ShadowAssociationType>, PrismContainerDefinition<ShadowAssociationType>>> triple) throws SchemaException, ExpressionEvaluationException, PolicyViolationException {
    ItemPath itemPath = new ItemPath(ShadowType.F_ASSOCIATION);
    PrismContainerDefinition<ShadowAssociationType> asspcContainerDef = getAssociationDefinition();
    RefinedAssociationDefinition associationDef = rOcDef.findAssociationDefinition(associationName);
    Comparator<PrismContainerValue<ShadowAssociationType>> comparator = new Comparator<PrismContainerValue<ShadowAssociationType>>() {

        @Override
        public int compare(PrismContainerValue<ShadowAssociationType> o1, PrismContainerValue<ShadowAssociationType> o2) {
            if (o1 == null && o2 == null) {
                LOGGER.trace("Comparing {} and {}: 0 (A)", o1, o2);
                return 0;
            }
            if (o1 == null || o2 == null) {
                LOGGER.trace("Comparing {} and {}: 2 (B)", o1, o2);
                return 1;
            }
            PrismReference ref1 = o1.findReference(ShadowAssociationType.F_SHADOW_REF);
            PrismReference ref2 = o2.findReference(ShadowAssociationType.F_SHADOW_REF);
            // We do not want to compare references in details. Comparing OIDs suffices.
            // Otherwise we get into problems, as one of the references might be e.g. without type,
            // causing unpredictable behavior (MID-2368)
            String oid1 = ref1 != null ? ref1.getOid() : null;
            String oid2 = ref2 != null ? ref2.getOid() : null;
            if (ObjectUtils.equals(oid1, oid2)) {
                LOGGER.trace("Comparing {} and {}: 0 (C)", o1, o2);
                return 0;
            }
            LOGGER.trace("Comparing {} and {}: 1 (D)", o1, o2);
            return 1;
        }
    };
    ContainerDelta<ShadowAssociationType> delta = (ContainerDelta<ShadowAssociationType>) consolidateItem(rOcDef, discr, existingDelta, projCtx, addUnchangedValues, completeShadow, associationDef.isExclusiveStrong(), itemPath, asspcContainerDef, triple, null, comparator, "association " + associationName);
    if (delta != null) {
        setAssociationName(delta.getValuesToAdd(), associationName);
        setAssociationName(delta.getValuesToDelete(), associationName);
        setAssociationName(delta.getValuesToReplace(), associationName);
    }
    return delta;
}
Also used : PrismContainerValue(com.evolveum.midpoint.prism.PrismContainerValue) ContainerDelta(com.evolveum.midpoint.prism.delta.ContainerDelta) PrismReference(com.evolveum.midpoint.prism.PrismReference) ShadowAssociationType(com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType) ItemPath(com.evolveum.midpoint.prism.path.ItemPath) Comparator(java.util.Comparator)

Example 45 with PrismContainerValue

use of com.evolveum.midpoint.prism.PrismContainerValue 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)

Aggregations

PrismContainerValue (com.evolveum.midpoint.prism.PrismContainerValue)59 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)22 Task (com.evolveum.midpoint.task.api.Task)22 AssignmentType (com.evolveum.midpoint.xml.ns._public.common.common_3.AssignmentType)22 PrismContainerDefinition (com.evolveum.midpoint.prism.PrismContainerDefinition)21 Test (org.testng.annotations.Test)18 UserType (com.evolveum.midpoint.xml.ns._public.common.common_3.UserType)17 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)15 ItemDeltaItem (com.evolveum.midpoint.repo.common.expression.ItemDeltaItem)15 ArrayList (java.util.ArrayList)14 ObjectDeltaObject (com.evolveum.midpoint.repo.common.expression.ObjectDeltaObject)13 PrismObject (com.evolveum.midpoint.prism.PrismObject)10 QName (javax.xml.namespace.QName)10 PrismContainer (com.evolveum.midpoint.prism.PrismContainer)9 PrismReference (com.evolveum.midpoint.prism.PrismReference)9 ItemDelta (com.evolveum.midpoint.prism.delta.ItemDelta)9 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)9 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)8 ContainerDelta (com.evolveum.midpoint.prism.delta.ContainerDelta)6 ShadowAssociationType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAssociationType)6