Search in sources :

Example 6 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext 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 7 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext 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 8 with LensProjectionContext

use of com.evolveum.midpoint.model.impl.lens.LensProjectionContext 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)

Example 9 with LensProjectionContext

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

the class ContextLoader method determineFocusContext.

/** 
	 * try to load focus context from the projections, e.g. by determining account owners
	 */
public <F extends FocusType> void determineFocusContext(LensContext<F> context, OperationResult result) throws ObjectNotFoundException, SchemaException {
    if (context.getFocusContext() != null) {
        // already done
        return;
    }
    String focusOid = null;
    PrismObject<F> focusObject = null;
    LensProjectionContext projectionContextThatYeildedFocusOid = null;
    for (LensProjectionContext projectionContext : context.getProjectionContexts()) {
        String projectionOid = projectionContext.getOid();
        if (projectionOid != null) {
            PrismObject<F> shadowOwner = cacheRepositoryService.searchShadowOwner(projectionOid, SelectorOptions.createCollection(GetOperationOptions.createAllowNotFound()), result);
            if (shadowOwner != null) {
                if (focusOid == null || focusOid.equals(shadowOwner.getOid())) {
                    focusOid = shadowOwner.getOid();
                    focusObject = shadowOwner;
                    projectionContextThatYeildedFocusOid = projectionContext;
                } else {
                    throw new IllegalArgumentException("The context does not have explicit focus. Attempt to determine focus failed because two " + "projections points to different foci: " + projectionContextThatYeildedFocusOid + "->" + focusOid + "; " + projectionContext + "->" + shadowOwner);
                }
            }
        }
    }
    if (focusOid != null) {
        LensFocusContext<F> focusContext = context.getOrCreateFocusContext(focusObject.getCompileTimeClass());
        PrismObject<F> object = cacheRepositoryService.getObject(focusContext.getObjectTypeClass(), focusOid, null, result);
        focusContext.setLoadedObject(object);
    }
}
Also used : LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext)

Example 10 with LensProjectionContext

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

the class ContextLoader method getOrCreateAccountContext.

private <F extends FocusType> LensProjectionContext getOrCreateAccountContext(LensContext<F> context, PrismObject<ShadowType> projection, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, PolicyViolationException, ExpressionEvaluationException {
    ShadowType accountType = projection.asObjectable();
    String resourceOid = ShadowUtil.getResourceOid(accountType);
    if (resourceOid == null) {
        throw new SchemaException("The " + projection + " has null resource reference OID");
    }
    LensProjectionContext projectionContext = context.findProjectionContextByOid(accountType.getOid());
    if (projectionContext == null) {
        String intent = ShadowUtil.getIntent(accountType);
        ShadowKindType kind = ShadowUtil.getKind(accountType);
        ResourceType resource = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
        intent = LensUtil.refineProjectionIntent(kind, intent, resource, prismContext);
        boolean thombstone = false;
        if (ShadowUtil.isDead(accountType)) {
            thombstone = true;
        }
        ResourceShadowDiscriminator rsd = new ResourceShadowDiscriminator(resourceOid, kind, intent, thombstone);
        projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd);
        if (projectionContext.getOid() == null) {
            projectionContext.setOid(projection.getOid());
        } else if (projection.getOid() != null && !projectionContext.getOid().equals(projection.getOid())) {
            // slightly inefficient here and check for existing shadow existence
            try {
                GetOperationOptions rootOpt = GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE);
                rootOpt.setDoNotDiscovery(true);
                Collection<SelectorOptions<GetOperationOptions>> opts = SelectorOptions.createCollection(rootOpt);
                LOGGER.trace("Projection conflict detected, exsting: {}, new {}", projectionContext.getOid(), projection.getOid());
                PrismObject<ShadowType> existingShadow = provisioningService.getObject(ShadowType.class, projectionContext.getOid(), opts, task, result);
                // Maybe it is the other way around
                try {
                    PrismObject<ShadowType> newShadow = provisioningService.getObject(ShadowType.class, projection.getOid(), opts, task, result);
                    // Obviously, two projections with the same discriminator exists
                    if (LOGGER.isTraceEnabled()) {
                        LOGGER.trace("Projection {} already exists in context\nExisting:\n{}\nNew:\n{}", new Object[] { rsd, existingShadow.debugDump(1), newShadow.debugDump(1) });
                    }
                    throw new PolicyViolationException("Projection " + rsd + " already exists in context (existing " + existingShadow + ", new " + projection);
                } catch (ObjectNotFoundException e) {
                    // This is somehow expected, fix it and we can go on
                    result.muteLastSubresultError();
                    // We have to create new context in this case, but it has to have thumbstone set
                    rsd.setThombstone(true);
                    projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd);
                    // We have to mark it as dead right now, otherwise the uniqueness check may fail
                    markShadowDead(projection.getOid(), result);
                }
            } catch (ObjectNotFoundException e) {
                // This is somehow expected, fix it and we can go on
                result.muteLastSubresultError();
                String shadowOid = projectionContext.getOid();
                projectionContext.getResourceShadowDiscriminator().setThombstone(true);
                projectionContext = LensUtil.getOrCreateProjectionContext(context, rsd);
                // We have to mark it as dead right now, otherwise the uniqueness check may fail
                markShadowDead(shadowOid, result);
            }
        }
    }
    return projectionContext;
}
Also used : SchemaException(com.evolveum.midpoint.util.exception.SchemaException) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) PrismObject(com.evolveum.midpoint.prism.PrismObject) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) Collection(java.util.Collection) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) PrismObject(com.evolveum.midpoint.prism.PrismObject) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException)

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