Search in sources :

Example 1 with ResourceShadowDiscriminator

use of com.evolveum.midpoint.schema.ResourceShadowDiscriminator 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 ResourceShadowDiscriminator

use of com.evolveum.midpoint.schema.ResourceShadowDiscriminator in project midpoint by Evolveum.

the class AssignmentProcessor method processAssignmentsProjectionsWithFocus.

/**
     * Processing focus-projection assignments (including roles).
     */
@SuppressWarnings({ "rawtypes", "unchecked" })
private <F extends FocusType> void processAssignmentsProjectionsWithFocus(LensContext<F> context, XMLGregorianCalendar now, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, ExpressionEvaluationException, PolicyViolationException, CommunicationException, ConfigurationException, SecurityViolationException {
    // PREPARE ASSIGNMENT DELTA
    LensFocusContext<F> focusContext = context.getFocusContext();
    ObjectDelta<F> focusDelta = focusContext.getDelta();
    if (focusDelta != null && focusDelta.isDelete()) {
        processFocusDelete(context, result);
        return;
    }
    checkAssignmentDeltaSanity(context);
    // ASSIGNMENT EVALUATION
    // Initializing assignment evaluator. This will be used later to process all the assignments including the nested
    // assignments (roles).
    AssignmentEvaluator<F> assignmentEvaluator = createAssignmentEvaluator(context, now);
    ObjectType source = determineSource(focusContext);
    AssignmentTripleEvaluator<F> assignmentTripleEvaluator = new AssignmentTripleEvaluator<>();
    assignmentTripleEvaluator.setActivationComputer(activationComputer);
    assignmentTripleEvaluator.setAssignmentEvaluator(assignmentEvaluator);
    assignmentTripleEvaluator.setContext(context);
    assignmentTripleEvaluator.setNow(now);
    assignmentTripleEvaluator.setPrismContext(prismContext);
    assignmentTripleEvaluator.setResult(result);
    assignmentTripleEvaluator.setSource(source);
    assignmentTripleEvaluator.setTask(task);
    // Normal processing. The enforcement policy requires that assigned accounts should be added, so we need to figure out
    // which assignments were added. Do a complete recompute for all the enforcement modes. We can do that because this does
    // not create deltas, it just creates the triples. So we can decide what to do later when we convert triples to deltas.
    // Evaluates all assignments and sorts them to triple: added, removed and untouched assignments.
    // This is where most of the assignment-level action happens.
    DeltaSetTriple<EvaluatedAssignmentImpl<F>> evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
    policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
    context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
    }
    // PROCESSING POLICIES
    policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
    boolean needToReevaluateAssignments = policyRuleProcessor.processPruning(context, evaluatedAssignmentTriple, result);
    if (needToReevaluateAssignments) {
        LOGGER.debug("Re-evaluating assignments because exclusion pruning rule was triggered");
        evaluatedAssignmentTriple = assignmentTripleEvaluator.processAllAssignments();
        context.setEvaluatedAssignmentTriple((DeltaSetTriple) evaluatedAssignmentTriple);
        policyRuleProcessor.addGlobalPoliciesToAssignments(context, evaluatedAssignmentTriple, task, result);
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("re-evaluatedAssignmentTriple:\n{}", evaluatedAssignmentTriple.debugDump());
        }
        policyRuleProcessor.processPolicies(context, evaluatedAssignmentTriple, result);
    }
    //policyRuleProcessor.storeAssignmentPolicySituation(context, evaluatedAssignmentTriple, result);
    // PROCESSING FOCUS
    Map<ItemPath, DeltaSetTriple<? extends ItemValueWithOrigin<?, ?>>> focusOutputTripleMap = new HashMap<>();
    collectFocusTripleFromMappings(evaluatedAssignmentTriple.getPlusSet(), focusOutputTripleMap, PlusMinusZero.PLUS);
    collectFocusTripleFromMappings(evaluatedAssignmentTriple.getMinusSet(), focusOutputTripleMap, PlusMinusZero.MINUS);
    collectFocusTripleFromMappings(evaluatedAssignmentTriple.getZeroSet(), focusOutputTripleMap, PlusMinusZero.ZERO);
    ObjectDeltaObject<F> focusOdo = focusContext.getObjectDeltaObject();
    Collection<ItemDelta<?, ?>> focusDeltas = objectTemplateProcessor.computeItemDeltas(focusOutputTripleMap, null, focusOdo.getObjectDelta(), focusOdo.getNewObject(), focusContext.getObjectDefinition(), "focus mappings in assignments of " + focusContext.getHumanReadableName());
    LOGGER.trace("Computed focus deltas: {}", focusDeltas);
    focusContext.applyProjectionWaveSecondaryDeltas(focusDeltas);
    focusContext.recompute();
    // PROCESSING PROJECTIONS
    // Evaluate the constructions in assignements now. These were not evaluated in the first pass of AssignmentEvaluator
    // because there may be interaction from focusMappings of some roles to outbound mappings of other roles.
    // Now we have complete focus with all the focusMappings so we can evaluate the constructions
    evaluateConstructions(context, evaluatedAssignmentTriple, task, result);
    ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>> consumer = new ComplexConstructionConsumer<ResourceShadowDiscriminator, Construction<F>>() {

        private boolean processOnlyExistingProjCxts;

        @Override
        public boolean before(ResourceShadowDiscriminator rat) {
            if (rat.getResourceOid() == null) {
                throw new IllegalStateException("Resource OID null in ResourceAccountType during assignment processing");
            }
            if (rat.getIntent() == null) {
                throw new IllegalStateException("Account type is null in ResourceAccountType during assignment processing");
            }
            processOnlyExistingProjCxts = false;
            if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
                if (context.getTriggeredResourceOid() != null && !rat.getResourceOid().equals(context.getTriggeredResourceOid())) {
                    LOGGER.trace("Skipping processing construction for shadow identified by {} because of limitation to propagate changes only for resource {}", rat, context.getTriggeredResourceOid());
                    return false;
                }
                if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY.equals(QNameUtil.uriToQName(context.getChannel()))) {
                    // TODO is this message OK? [med]
                    LOGGER.trace("Processing of shadow identified by {} will be skipped because of limitation for discovery channel.");
                    processOnlyExistingProjCxts = true;
                }
            }
            return true;
        }

        @Override
        public void onAssigned(ResourceShadowDiscriminator rat, String desc) {
            LensProjectionContext projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
            projectionContext.setAssigned(true);
            projectionContext.setAssignedOld(false);
            projectionContext.setLegalOld(false);
            AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
            if (assignmentPolicyEnforcement != AssignmentPolicyEnforcementType.NONE) {
                LOGGER.trace("Projection {} legal: assigned (valid)", desc);
                projectionContext.setLegal(true);
            }
        }

        @Override
        public void onUnchangedValid(ResourceShadowDiscriminator key, String desc) {
            LensProjectionContext projectionContext = context.findProjectionContext(key);
            if (projectionContext == null) {
                if (processOnlyExistingProjCxts) {
                    return;
                }
                // The projection should exist before the change but it does not
                // This happens during reconciliation if there is an inconsistency. 
                // Pretend that the assignment was just added. That should do.
                projectionContext = LensUtil.getOrCreateProjectionContext(context, key);
            }
            LOGGER.trace("Projection {} legal: unchanged (valid)", desc);
            projectionContext.setLegal(true);
            projectionContext.setLegalOld(true);
            projectionContext.setAssigned(true);
            projectionContext.setAssignedOld(true);
        }

        @Override
        public void onUnchangedInvalid(ResourceShadowDiscriminator rat, String desc) {
            LensProjectionContext projectionContext = context.findProjectionContext(rat);
            if (projectionContext == null) {
                if (processOnlyExistingProjCxts) {
                    return;
                }
                // The projection should exist before the change but it does not
                // This happens during reconciliation if there is an inconsistency. 
                // Pretend that the assignment was just added. That should do.
                projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
            }
            LOGGER.trace("Projection {} illegal: unchanged (invalid)", desc);
            projectionContext.setLegal(false);
            projectionContext.setLegalOld(false);
            projectionContext.setAssigned(false);
            projectionContext.setAssignedOld(false);
        }

        @Override
        public void onUnassigned(ResourceShadowDiscriminator rat, String desc) {
            if (accountExists(context, rat)) {
                LensProjectionContext projectionContext = context.findProjectionContext(rat);
                if (projectionContext == null) {
                    if (processOnlyExistingProjCxts) {
                        return;
                    }
                    projectionContext = LensUtil.getOrCreateProjectionContext(context, rat);
                }
                projectionContext.setAssigned(false);
                projectionContext.setAssignedOld(true);
                projectionContext.setLegalOld(true);
                AssignmentPolicyEnforcementType assignmentPolicyEnforcement = projectionContext.getAssignmentPolicyEnforcementType();
                // TODO: check for MARK and LEGALIZE enforcement policies ....add delete laso for relative enforcemenet
                if (assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.FULL || assignmentPolicyEnforcement == AssignmentPolicyEnforcementType.RELATIVE) {
                    LOGGER.trace("Projection {} illegal: unassigned", desc);
                    projectionContext.setLegal(false);
                } else {
                    LOGGER.trace("Projection {} legal: unassigned, but allowed by policy ({})", desc, assignmentPolicyEnforcement);
                    projectionContext.setLegal(true);
                }
            } else {
                LOGGER.trace("Projection {} nothing: unassigned (valid->invalid) but not there", desc);
            // We have to delete something that is not there. Nothing to do.
            }
        }

        @Override
        public void after(ResourceShadowDiscriminator rat, String desc, DeltaMapTriple<ResourceShadowDiscriminator, ConstructionPack<Construction<F>>> constructionMapTriple) {
            PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> projectionConstructionDeltaSetTriple = new PrismValueDeltaSetTriple<>(getConstructions(constructionMapTriple.getZeroMap().get(rat), true), getConstructions(constructionMapTriple.getPlusMap().get(rat), true), getConstructions(constructionMapTriple.getMinusMap().get(rat), false));
            LensProjectionContext projectionContext = context.findProjectionContext(rat);
            if (projectionContext != null) {
                // This can be null in a exotic case if we delete already deleted account
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Construction delta set triple for {}:\n{}", rat, projectionConstructionDeltaSetTriple.debugDump(1));
                }
                projectionContext.setConstructionDeltaSetTriple(projectionConstructionDeltaSetTriple);
                if (isForceRecon(constructionMapTriple.getZeroMap().get(rat)) || isForceRecon(constructionMapTriple.getPlusMap().get(rat)) || isForceRecon(constructionMapTriple.getMinusMap().get(rat))) {
                    projectionContext.setDoReconciliation(true);
                }
            }
        }
    };
    constructionProcessor.processConstructions(context, evaluatedAssignmentTriple, evaluatedAssignment -> evaluatedAssignment.getConstructionTriple(), construction -> getConstructionMapKey(context, construction, task, result), consumer, task, result);
    removeIgnoredContexts(context);
    finishLegalDecisions(context);
}
Also used : PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) DeltaSetTriple(com.evolveum.midpoint.prism.delta.DeltaSetTriple) ItemDelta(com.evolveum.midpoint.prism.delta.ItemDelta) DeltaMapTriple(com.evolveum.midpoint.prism.delta.DeltaMapTriple) PrismPropertyValue(com.evolveum.midpoint.prism.PrismPropertyValue) Construction(com.evolveum.midpoint.model.impl.lens.Construction) PrismValueDeltaSetTriple(com.evolveum.midpoint.prism.delta.PrismValueDeltaSetTriple) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) EvaluatedAssignmentImpl(com.evolveum.midpoint.model.impl.lens.EvaluatedAssignmentImpl) ItemValueWithOrigin(com.evolveum.midpoint.model.impl.lens.ItemValueWithOrigin) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 3 with ResourceShadowDiscriminator

use of com.evolveum.midpoint.schema.ResourceShadowDiscriminator in project midpoint by Evolveum.

the class ContextLoader method createProjectionContext.

private <F extends FocusType> LensProjectionContext createProjectionContext(LensContext<F> context, PrismObject<ShadowType> account, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    ShadowType shadowType = account.asObjectable();
    String resourceOid = ShadowUtil.getResourceOid(shadowType);
    if (resourceOid == null) {
        throw new SchemaException("The " + account + " has null resource reference OID");
    }
    String intent = ShadowUtil.getIntent(shadowType);
    ShadowKindType kind = ShadowUtil.getKind(shadowType);
    ResourceType resource = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
    String accountIntent = LensUtil.refineProjectionIntent(kind, intent, resource, prismContext);
    ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, kind, accountIntent);
    LensProjectionContext accountSyncContext = context.findProjectionContext(rsd);
    if (accountSyncContext != null) {
        throw new SchemaException("Attempt to add " + account + " to a user that already contains account of type '" + accountIntent + "' on " + resource);
    }
    accountSyncContext = context.createProjectionContext(rsd);
    accountSyncContext.setResource(resource);
    accountSyncContext.setOid(account.getOid());
    return accountSyncContext;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 4 with ResourceShadowDiscriminator

use of com.evolveum.midpoint.schema.ResourceShadowDiscriminator in project midpoint by Evolveum.

the class ContextLoader method loadFullShadow.

public <F extends ObjectType> void loadFullShadow(LensContext<F> context, LensProjectionContext projCtx, String reason, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    if (projCtx.isFullShadow()) {
        // already loaded
        return;
    }
    if (projCtx.isAdd() && projCtx.getOid() == null) {
        // nothing to load yet
        return;
    }
    if (projCtx.isThombstone()) {
        // loading is futile
        return;
    }
    ResourceShadowDiscriminator discr = projCtx.getResourceShadowDiscriminator();
    if (discr != null && discr.getOrder() > 0) {
        // It may be just too early to load the projection
        if (LensUtil.hasLowerOrderContext(context, projCtx) && (context.getExecutionWave() < projCtx.getWave())) {
            // We cannot reliably load the context now
            return;
        }
    }
    GetOperationOptions getOptions = GetOperationOptions.createAllowNotFound();
    getOptions.setPointInTimeType(PointInTimeType.FUTURE);
    if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY_URI.equals(context.getChannel())) {
        LOGGER.trace("Loading full resource object {} from provisioning - with doNotDiscover to avoid loops; reason: {}", projCtx, reason);
        // Avoid discovery loops
        getOptions.setDoNotDiscovery(true);
    } else {
        LOGGER.trace("Loading full resource object {} from provisioning (discovery enabled), reason: {}, channel: {}", projCtx, reason, context.getChannel());
    }
    try {
        Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(getOptions);
        applyAttributesToGet(projCtx, options);
        PrismObject<ShadowType> objectCurrent = provisioningService.getObject(ShadowType.class, projCtx.getOid(), options, task, result);
        Validate.notNull(objectCurrent.getOid());
        // TODO: use setLoadedObject() instead?
        projCtx.setObjectCurrent(objectCurrent);
        ShadowType oldShadow = objectCurrent.asObjectable();
        projCtx.determineFullShadowFlag(oldShadow.getFetchResult());
        // The getObject may return different OID than we have requested in case that compensation happened
        // TODO: this probably need to be fixed in the consistency mechanism
        // TODO: the following line is a temporary fix
        projCtx.setOid(objectCurrent.getOid());
    } catch (ObjectNotFoundException ex) {
        LOGGER.trace("Load of full resource object {} ended with ObjectNotFoundException (options={})", projCtx, getOptions);
        if (projCtx.isDelete()) {
            //this is OK, shadow was deleted, but we will continue in processing with old shadow..and set it as full so prevent from other full loading
            projCtx.setFullShadow(true);
        } else {
            boolean compensated = false;
            if (!GetOperationOptions.isDoNotDiscovery(getOptions)) {
                // The account might have been re-created by the discovery.
                // Reload focus, try to find out if there is a new matching link (and the old is gone)
                LensFocusContext<F> focusContext = context.getFocusContext();
                if (focusContext != null) {
                    Class<F> focusClass = focusContext.getObjectTypeClass();
                    if (FocusType.class.isAssignableFrom(focusClass)) {
                        LOGGER.trace("Reloading focus to check for new links");
                        PrismObject<F> focusCurrent = cacheRepositoryService.getObject(focusContext.getObjectTypeClass(), focusContext.getOid(), null, result);
                        FocusType focusType = (FocusType) focusCurrent.asObjectable();
                        for (ObjectReferenceType linkRef : focusType.getLinkRef()) {
                            if (linkRef.getOid().equals(projCtx.getOid())) {
                                // The deleted shadow is still in the linkRef. This should not happen, but it obviously happens sometimes.
                                // Maybe some strange race condition? Anyway, we want a robust behavior and this linkeRef should NOT be there.
                                // So simple remove it.
                                LOGGER.warn("The OID " + projCtx.getOid() + " of deleted shadow still exists in the linkRef after discovery (" + focusCurrent + "), removing it");
                                ReferenceDelta unlinkDelta = ReferenceDelta.createModificationDelete(FocusType.F_LINK_REF, focusContext.getObjectDefinition(), linkRef.asReferenceValue().clone());
                                focusContext.swallowToSecondaryDelta(unlinkDelta);
                                continue;
                            }
                            boolean found = false;
                            for (LensProjectionContext pCtx : context.getProjectionContexts()) {
                                if (linkRef.getOid().equals(pCtx.getOid())) {
                                    found = true;
                                    break;
                                }
                            }
                            if (!found) {
                                // This link is new, it is not in the existing lens context
                                PrismObject<ShadowType> newLinkRepoShadow = cacheRepositoryService.getObject(ShadowType.class, linkRef.getOid(), null, result);
                                if (ShadowUtil.matches(newLinkRepoShadow, projCtx.getResourceShadowDiscriminator())) {
                                    LOGGER.trace("Found new matching link: {}, updating projection context", newLinkRepoShadow);
                                    // MID-3317
                                    LOGGER.trace("Applying definition from provisioning first.");
                                    provisioningService.applyDefinition(newLinkRepoShadow, task, result);
                                    projCtx.setObjectCurrent(newLinkRepoShadow);
                                    projCtx.setOid(newLinkRepoShadow.getOid());
                                    projCtx.recompute();
                                    compensated = true;
                                    break;
                                } else {
                                    LOGGER.trace("Found new link: {}, but skipping it because it does not match the projection context", newLinkRepoShadow);
                                }
                            }
                        }
                    }
                }
            }
            if (!compensated) {
                LOGGER.trace("ObjectNotFound error is not compensated, setting context to thombstone");
                projCtx.getResourceShadowDiscriminator().setThombstone(true);
                projCtx.setExists(false);
                projCtx.setFullShadow(false);
            }
        }
    }
    projCtx.recompute();
    if (LOGGER.isTraceEnabled()) {
        LOGGER.trace("Loaded full resource object:\n{}", projCtx.debugDump(1));
    }
}
Also used : LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ReferenceDelta(com.evolveum.midpoint.prism.delta.ReferenceDelta) PrismObject(com.evolveum.midpoint.prism.PrismObject) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) LensFocusContext(com.evolveum.midpoint.model.impl.lens.LensFocusContext)

Example 5 with ResourceShadowDiscriminator

use of com.evolveum.midpoint.schema.ResourceShadowDiscriminator in project midpoint by Evolveum.

the class ContextLoader method preprocessProjectionContext.

/**
	 * Make sure that the context is OK and consistent. It means that is has a resource, it has correctly processed
	 * discriminator, etc.
	 */
private <F extends ObjectType> void preprocessProjectionContext(LensContext<F> context, LensProjectionContext projectionContext, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    if (!ShadowType.class.isAssignableFrom(projectionContext.getObjectTypeClass())) {
        return;
    }
    String resourceOid = null;
    boolean isThombstone = false;
    ShadowKindType kind = ShadowKindType.ACCOUNT;
    String intent = null;
    int order = 0;
    ResourceShadowDiscriminator rsd = projectionContext.getResourceShadowDiscriminator();
    if (rsd != null) {
        resourceOid = rsd.getResourceOid();
        isThombstone = rsd.isThombstone();
        kind = rsd.getKind();
        intent = rsd.getIntent();
        order = rsd.getOrder();
    }
    if (resourceOid == null && projectionContext.getObjectCurrent() != null) {
        resourceOid = ShadowUtil.getResourceOid((ShadowType) projectionContext.getObjectCurrent().asObjectable());
    }
    if (resourceOid == null && projectionContext.getObjectNew() != null) {
        resourceOid = ShadowUtil.getResourceOid((ShadowType) projectionContext.getObjectNew().asObjectable());
    }
    if (resourceOid != null) {
        if (intent == null && projectionContext.getObjectNew() != null) {
            ShadowType shadowNewType = projectionContext.getObjectNew().asObjectable();
            kind = ShadowUtil.getKind(shadowNewType);
            intent = ShadowUtil.getIntent(shadowNewType);
        }
        ResourceType resource = projectionContext.getResource();
        if (resource == null) {
            resource = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
            projectionContext.setResource(resource);
        }
        String refinedIntent = LensUtil.refineProjectionIntent(kind, intent, resource, prismContext);
        rsd = new ResourceShadowDiscriminator(resourceOid, kind, refinedIntent, isThombstone);
        rsd.setOrder(order);
        projectionContext.setResourceShadowDiscriminator(rsd);
    }
    if (projectionContext.getOid() == null && rsd.getOrder() != 0) {
        // Try to determine OID from lower-order contexts
        for (LensProjectionContext aProjCtx : context.getProjectionContexts()) {
            ResourceShadowDiscriminator aDiscr = aProjCtx.getResourceShadowDiscriminator();
            if (rsd.equivalent(aDiscr) && aProjCtx.getOid() != null) {
                projectionContext.setOid(aProjCtx.getOid());
                break;
            }
        }
    }
}
Also used : LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Aggregations

ResourceShadowDiscriminator (com.evolveum.midpoint.schema.ResourceShadowDiscriminator)78 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)41 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)34 Task (com.evolveum.midpoint.task.api.Task)30 Test (org.testng.annotations.Test)30 LensProjectionContext (com.evolveum.midpoint.model.impl.lens.LensProjectionContext)28 UserType (com.evolveum.midpoint.xml.ns._public.common.common_3.UserType)18 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)17 ResourceObjectShadowChangeDescription (com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription)17 ModelProjectionContext (com.evolveum.midpoint.model.api.context.ModelProjectionContext)11 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)10 ObjectType (com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType)10 DummyAccount (com.evolveum.icf.dummy.resource.DummyAccount)9 ModelExecuteOptions (com.evolveum.midpoint.model.api.ModelExecuteOptions)9 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)9 AbstractInternalModelIntegrationTest (com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest)8 MockLensDebugListener (com.evolveum.midpoint.model.impl.util.mock.MockLensDebugListener)8 PrismObject (com.evolveum.midpoint.prism.PrismObject)8 QName (javax.xml.namespace.QName)7 PolyString (com.evolveum.midpoint.prism.polystring.PolyString)6