Search in sources :

Example 46 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext in project midpoint by Evolveum.

the class ContextLoader method loadLinkRefsFromDelta.

private <F extends FocusType> void loadLinkRefsFromDelta(LensContext<F> context, PrismObject<F> focus, ObjectDelta<F> focusPrimaryDelta, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException {
    if (focusPrimaryDelta == null) {
        return;
    }
    ReferenceDelta linkRefDelta;
    if (focusPrimaryDelta.getChangeType() == ChangeType.ADD) {
        PrismReference linkRef = focusPrimaryDelta.getObjectToAdd().findReference(FocusType.F_LINK_REF);
        if (linkRef == null) {
            // Adding new focus with no linkRef -> nothing to do
            return;
        }
        linkRefDelta = linkRef.createDelta(new ItemPath(FocusType.F_LINK_REF));
        linkRefDelta.addValuesToAdd(PrismValue.cloneValues(linkRef.getValues()));
    } else if (focusPrimaryDelta.getChangeType() == ChangeType.MODIFY) {
        linkRefDelta = focusPrimaryDelta.findReferenceModification(FocusType.F_LINK_REF);
        if (linkRefDelta == null) {
            return;
        }
    } else {
        // delete, all existing account are already marked for delete
        return;
    }
    if (linkRefDelta.isReplace()) {
        // process "replace" by distributing values to delete and add
        linkRefDelta = (ReferenceDelta) linkRefDelta.clone();
        PrismReference linkRef = focus.findReference(FocusType.F_LINK_REF);
        linkRefDelta.distributeReplace(linkRef == null ? null : linkRef.getValues());
    }
    if (linkRefDelta.getValuesToAdd() != null) {
        for (PrismReferenceValue refVal : linkRefDelta.getValuesToAdd()) {
            String oid = refVal.getOid();
            LensProjectionContext accountContext = null;
            PrismObject<ShadowType> shadow = null;
            boolean isCombinedAdd = false;
            if (oid == null) {
                // Adding new account
                shadow = refVal.getObject();
                if (shadow == null) {
                    throw new SchemaException("Null or empty OID in account reference " + refVal + " in " + focus);
                }
                provisioningService.applyDefinition(shadow, task, result);
                if (consistencyChecks)
                    ShadowUtil.checkConsistence(shadow, "account from " + linkRefDelta);
                // Check for conflicting change
                accountContext = LensUtil.getProjectionContext(context, shadow, provisioningService, prismContext, task, result);
                if (accountContext != null) {
                    // There is already existing context for the same discriminator. Tolerate this only if
                    // the deltas match. It is an error otherwise.
                    ObjectDelta<ShadowType> primaryDelta = accountContext.getPrimaryDelta();
                    if (primaryDelta == null) {
                        throw new SchemaException("Attempt to add " + shadow + " to a user that already contains " + accountContext.getHumanReadableKind() + " of type '" + accountContext.getResourceShadowDiscriminator().getIntent() + "' on " + accountContext.getResource());
                    }
                    if (!primaryDelta.isAdd()) {
                        throw new SchemaException("Conflicting changes in the context. " + "Add of accountRef in the user delta with embedded object conflicts with explicit delta " + primaryDelta);
                    }
                    if (!shadow.equals(primaryDelta.getObjectToAdd())) {
                        throw new SchemaException("Conflicting changes in the context. " + "Add of accountRef in the user delta with embedded object is not adding the same object as explicit delta " + primaryDelta);
                    }
                } else {
                    // Create account context from embedded object
                    accountContext = createProjectionContext(context, shadow, task, result);
                }
                // This is a new account that is to be added. So it should
                // go to account primary delta
                ObjectDelta<ShadowType> accountPrimaryDelta = shadow.createAddDelta();
                accountContext.setPrimaryDelta(accountPrimaryDelta);
                accountContext.setFullShadow(true);
                accountContext.setExists(false);
                isCombinedAdd = true;
            } else {
                // therefore check for account existence to decide
                try {
                    // Using NO_FETCH so we avoid reading in a full account. This is more efficient as we don't need full account here.
                    // We need to fetch from provisioning and not repository so the correct definition will be set.
                    GetOperationOptions rootOpts = GetOperationOptions.createNoFetch();
                    rootOpts.setPointInTimeType(PointInTimeType.FUTURE);
                    Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(rootOpts);
                    shadow = provisioningService.getObject(ShadowType.class, oid, options, task, result);
                    // Create account context from retrieved object
                    accountContext = getOrCreateAccountContext(context, shadow, task, result);
                    accountContext.setLoadedObject(shadow);
                    accountContext.setExists(true);
                } catch (ObjectNotFoundException e) {
                    if (refVal.getObject() == null) {
                        // ref -> this is really an error
                        throw e;
                    } else {
                        // New account (with OID)
                        result.muteLastSubresultError();
                        shadow = refVal.getObject();
                        if (!shadow.hasCompleteDefinition()) {
                            provisioningService.applyDefinition(shadow, task, result);
                        }
                        // Create account context from embedded object
                        accountContext = createProjectionContext(context, shadow, task, result);
                        ObjectDelta<ShadowType> accountPrimaryDelta = shadow.createAddDelta();
                        accountContext.setPrimaryDelta(accountPrimaryDelta);
                        accountContext.setFullShadow(true);
                        accountContext.setExists(false);
                        isCombinedAdd = true;
                    }
                }
            }
            if (context.isDoReconciliationForAllProjections() && !isCombinedAdd) {
                accountContext.setDoReconciliation(true);
            }
            accountContext.setFresh(true);
        }
    }
    if (linkRefDelta.getValuesToDelete() != null) {
        for (PrismReferenceValue refVal : linkRefDelta.getValuesToDelete()) {
            String oid = refVal.getOid();
            LensProjectionContext accountContext = null;
            PrismObject<ShadowType> account = null;
            if (oid == null) {
                throw new SchemaException("Cannot delete account ref without an oid in " + focus);
            } else {
                try {
                    // Using NO_FETCH so we avoid reading in a full account. This is more efficient as we don't need full account here.
                    // We need to fetch from provisioning and not repository so the correct definition will be set.
                    Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createNoFetch());
                    account = provisioningService.getObject(ShadowType.class, oid, options, task, result);
                    // Create account context from retrieved object
                    accountContext = getOrCreateAccountContext(context, account, task, result);
                    accountContext.setLoadedObject(account);
                    accountContext.setExists(true);
                } catch (ObjectNotFoundException e) {
                    try {
                        // Broken accountRef. We need to try again with raw options, because the error should be thrown because of non-existent resource
                        Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(GetOperationOptions.createRaw());
                        account = provisioningService.getObject(ShadowType.class, oid, options, task, result);
                        accountContext = getOrCreateEmptyThombstoneProjectionContext(context, oid);
                        accountContext.setFresh(true);
                        accountContext.setExists(false);
                        OperationResult getObjectSubresult = result.getLastSubresult();
                        getObjectSubresult.setErrorsHandled();
                    } catch (ObjectNotFoundException ex) {
                        // This is still OK. It means deleting an accountRef
                        // that points to non-existing object
                        // just log a warning
                        LOGGER.warn("Deleting accountRef of " + focus + " that points to non-existing OID " + oid);
                    }
                }
            }
            if (accountContext != null) {
                if (refVal.getObject() == null) {
                    accountContext.setSynchronizationIntent(SynchronizationIntent.UNLINK);
                } else {
                    accountContext.setSynchronizationIntent(SynchronizationIntent.DELETE);
                    ObjectDelta<ShadowType> accountPrimaryDelta = account.createDeleteDelta();
                    accountContext.setPrimaryDelta(accountPrimaryDelta);
                }
                accountContext.setFresh(true);
            }
        }
    }
    if (focusPrimaryDelta.getChangeType() == ChangeType.ADD) {
        focusPrimaryDelta.getObjectToAdd().removeReference(FocusType.F_LINK_REF);
    } else if (focusPrimaryDelta.getChangeType() == ChangeType.MODIFY) {
        focusPrimaryDelta.removeReferenceModification(FocusType.F_LINK_REF);
    }
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ReferenceDelta(com.evolveum.midpoint.prism.delta.ReferenceDelta) OperationResult(com.evolveum.midpoint.schema.result.OperationResult) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) PrismReferenceValue(com.evolveum.midpoint.prism.PrismReferenceValue) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) PrismReference(com.evolveum.midpoint.prism.PrismReference) Collection(java.util.Collection) ObjectDelta(com.evolveum.midpoint.prism.delta.ObjectDelta) ItemPath(com.evolveum.midpoint.prism.path.ItemPath)

Example 47 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext in project midpoint by Evolveum.

the class ContextLoader method loadProjectionContextsSync.

private <F extends ObjectType> void loadProjectionContextsSync(LensContext<F> context, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    for (LensProjectionContext projCtx : context.getProjectionContexts()) {
        if (projCtx.isFresh() && projCtx.getObjectCurrent() != null) {
            // already loaded
            continue;
        }
        ObjectDelta<ShadowType> syncDelta = projCtx.getSyncDelta();
        if (syncDelta != null) {
            if (projCtx.isDoReconciliation()) {
                // Do not load old account now. It will get loaded later in the
                // reconciliation step. Just mark it as fresh.
                projCtx.setFresh(true);
                continue;
            }
            String oid = syncDelta.getOid();
            PrismObject<ShadowType> shadow = null;
            if (syncDelta.getChangeType() == ChangeType.ADD) {
                shadow = syncDelta.getObjectToAdd().clone();
                projCtx.setLoadedObject(shadow);
                projCtx.setExists(true);
            } else {
                if (oid == null) {
                    throw new IllegalArgumentException("No OID in sync delta in " + projCtx);
                }
                // Using NO_FETCH so we avoid reading in a full account. This is more efficient as we don't need full account here.
                // We need to fetch from provisioning and not repository so the correct definition will be set.
                GetOperationOptions option = GetOperationOptions.createNoFetch();
                option.setDoNotDiscovery(true);
                option.setPointInTimeType(PointInTimeType.FUTURE);
                Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(option);
                try {
                    shadow = provisioningService.getObject(ShadowType.class, oid, options, task, result);
                } catch (ObjectNotFoundException e) {
                    LOGGER.trace("Loading shadow {} from sync delta failed: not found", oid);
                    projCtx.setExists(false);
                    projCtx.setObjectCurrent(null);
                }
                // shadow)
                if (syncDelta.getChangeType() == ChangeType.DELETE) {
                    projCtx.setExists(false);
                    projCtx.getResourceShadowDiscriminator().setThombstone(true);
                } else if (shadow != null) {
                    syncDelta.applyTo(shadow);
                    projCtx.setLoadedObject(shadow);
                    projCtx.setExists(true);
                }
            }
            // Make sure OID is set correctly
            projCtx.setOid(oid);
            // Make sure that resource is also resolved
            if (projCtx.getResource() == null && shadow != null) {
                String resourceOid = ShadowUtil.getResourceOid(shadow.asObjectable());
                if (resourceOid == null) {
                    throw new IllegalArgumentException("No resource OID in " + shadow);
                }
                ResourceType resourceType = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
                projCtx.setResource(resourceType);
            }
            projCtx.setFresh(true);
        }
    }
}
Also used : GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException)

Example 48 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext in project midpoint by Evolveum.

the class ContextLoader method removeRottenContexts.

/**
	 * Removes projection contexts that are not fresh.
	 * These are usually artifacts left after the context reload. E.g. an account that used to be linked to a user before
	 * but was removed in the meantime.
	 */
private <F extends ObjectType> void removeRottenContexts(LensContext<F> context) {
    Iterator<LensProjectionContext> projectionIterator = context.getProjectionContextsIterator();
    while (projectionIterator.hasNext()) {
        LensProjectionContext projectionContext = projectionIterator.next();
        if (projectionContext.getPrimaryDelta() != null && !projectionContext.getPrimaryDelta().isEmpty()) {
            // Vox populi vox dei
            continue;
        }
        if (projectionContext.getWave() >= context.getExecutionWave()) {
            // chance to be executed yet
            continue;
        }
        ResourceShadowDiscriminator discr = projectionContext.getResourceShadowDiscriminator();
        if (discr != null && discr.getOrder() > 0) {
            // HACK never rot higher-order context. TODO: check if lower-order context is rotten, the also rot this one
            continue;
        }
        if (!projectionContext.isFresh()) {
            if (LOGGER.isTraceEnabled()) {
                LOGGER.trace("Removing rotten context {}", projectionContext.getHumanReadableName());
            }
            if (projectionContext.isToBeArchived()) {
                context.getHistoricResourceObjects().add(projectionContext.getResourceShadowDiscriminator());
            }
            List<LensObjectDeltaOperation<ShadowType>> executedDeltas = projectionContext.getExecutedDeltas();
            context.getRottenExecutedDeltas().addAll(executedDeltas);
            projectionIterator.remove();
        }
    }
}
Also used : LensObjectDeltaOperation(com.evolveum.midpoint.model.impl.lens.LensObjectDeltaOperation) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 49 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext in project midpoint by Evolveum.

the class ContextLoader method load.

public <F extends ObjectType> void load(LensContext<F> context, String activityDescription, Task task, OperationResult result) throws SchemaException, ObjectNotFoundException, CommunicationException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException {
    context.checkAbortRequested();
    context.recompute();
    for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
        preprocessProjectionContext(context, projectionContext, task, result);
    }
    if (consistencyChecks)
        context.checkConsistence();
    determineFocusContext((LensContext<? extends FocusType>) context, result);
    LensFocusContext<F> focusContext = context.getFocusContext();
    if (focusContext != null) {
        loadObjectCurrent(context, result);
        context.recomputeFocus();
        loadFromSystemConfig(context, result);
        if (FocusType.class.isAssignableFrom(context.getFocusClass())) {
            // this also removes the accountRef deltas
            loadLinkRefs((LensContext<? extends FocusType>) context, task, result);
            LOGGER.trace("loadLinkRefs done");
        }
        // Some cleanup
        if (focusContext.getPrimaryDelta() != null && focusContext.getPrimaryDelta().isModify() && focusContext.getPrimaryDelta().isEmpty()) {
            focusContext.setPrimaryDelta(null);
        }
        for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
            if (projectionContext.getSynchronizationIntent() != null) {
                // Accounts with explicitly set intent are never rotten. These are explicitly requested actions
                // if they fail then they really should fail.
                projectionContext.setFresh(true);
            }
        }
        setPrimaryDeltaOldValue(focusContext);
    } else {
        // Projection contexts are not rotten in this case. There is no focus so there is no way to refresh them.
        for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
            projectionContext.setFresh(true);
        }
    }
    removeRottenContexts(context);
    if (consistencyChecks)
        context.checkConsistence();
    for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
        context.checkAbortRequested();
        finishLoadOfProjectionContext(context, projectionContext, task, result);
    }
    if (consistencyChecks)
        context.checkConsistence();
    context.recompute();
    if (consistencyChecks) {
        fullCheckConsistence(context);
    }
    LensUtil.traceContext(LOGGER, activityDescription, "after load", false, context, false);
}
Also used : LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext)

Example 50 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext in project midpoint by Evolveum.

the class DependencyProcessor method findReverseDependecies.

private <F extends ObjectType> Collection<DependencyAndSource> findReverseDependecies(LensContext<F> context, LensProjectionContext targetProjectionContext) throws PolicyViolationException {
    Collection<DependencyAndSource> deps = new ArrayList<>();
    for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
        for (ResourceObjectTypeDependencyType dependency : projectionContext.getDependencies()) {
            if (LensUtil.isDependencyTargetContext(projectionContext, targetProjectionContext, dependency)) {
                DependencyAndSource ds = new DependencyAndSource();
                ds.dependency = dependency;
                ds.sourceProjectionContext = projectionContext;
                deps.add(ds);
            }
        }
    }
    return deps;
}
Also used : ResourceObjectTypeDependencyType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyType) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ArrayList(java.util.ArrayList)

Aggregations

LensProjectionContext (com.evolveum.midpoint.model.impl.lens.LensProjectionContext)71 ResourceShadowDiscriminator (com.evolveum.midpoint.schema.ResourceShadowDiscriminator)28 OperationResult (com.evolveum.midpoint.schema.result.OperationResult)24 Task (com.evolveum.midpoint.task.api.Task)19 ShadowType (com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType)18 Test (org.testng.annotations.Test)17 UserType (com.evolveum.midpoint.xml.ns._public.common.common_3.UserType)15 AbstractInternalModelIntegrationTest (com.evolveum.midpoint.model.impl.AbstractInternalModelIntegrationTest)14 ObjectNotFoundException (com.evolveum.midpoint.util.exception.ObjectNotFoundException)12 SchemaException (com.evolveum.midpoint.util.exception.SchemaException)11 PolicyViolationException (com.evolveum.midpoint.util.exception.PolicyViolationException)10 MockLensDebugListener (com.evolveum.midpoint.model.impl.util.mock.MockLensDebugListener)8 PrismObject (com.evolveum.midpoint.prism.PrismObject)8 ResourceObjectShadowChangeDescription (com.evolveum.midpoint.provisioning.api.ResourceObjectShadowChangeDescription)8 ObjectDelta (com.evolveum.midpoint.prism.delta.ObjectDelta)7 SynchronizationPolicyDecision (com.evolveum.midpoint.model.api.context.SynchronizationPolicyDecision)5 LensContext (com.evolveum.midpoint.model.impl.lens.LensContext)5 PrismReference (com.evolveum.midpoint.prism.PrismReference)5 ItemPath (com.evolveum.midpoint.prism.path.ItemPath)5 GetOperationOptions (com.evolveum.midpoint.schema.GetOperationOptions)5