Search in sources :

Example 6 with ResourceShadowDiscriminator

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

Example 7 with ResourceShadowDiscriminator

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

the class ContextLoader method finishLoadOfProjectionContext.

/**
	 * Check reconcile flag in account sync context and set accountOld
     * variable if it's not set (from provisioning), load resource (if not set already), etc.
	 */
private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F> context, LensProjectionContext projContext, Task task, OperationResult result) throws ObjectNotFoundException, CommunicationException, SchemaException, ConfigurationException, SecurityViolationException, ExpressionEvaluationException {
    String projectionHumanReadableName = projContext.getHumanReadableName();
    if (projContext.getSynchronizationPolicyDecision() == SynchronizationPolicyDecision.BROKEN) {
        return;
    }
    // MID-2436 (volatile objects) - as a quick but effective hack, we set reconciliation:=TRUE for volatile accounts
    ResourceObjectTypeDefinitionType objectDefinition = projContext.getResourceObjectTypeDefinitionType();
    if (objectDefinition != null && objectDefinition.getVolatility() == ResourceObjectVolatilityType.UNPREDICTABLE && !projContext.isDoReconciliation()) {
        LOGGER.trace("Resource object volatility is UNPREDICTABLE => setting doReconciliation to TRUE for {}", projContext.getResourceShadowDiscriminator());
        projContext.setDoReconciliation(true);
    }
    // Remember OID before the object could be wiped
    String projectionObjectOid = projContext.getOid();
    if (projContext.isDoReconciliation() && !projContext.isFullShadow()) {
        // The current object is useless here. So lets just wipe it so it will get loaded
        projContext.setObjectCurrent(null);
    }
    // Load current object
    boolean thombstone = false;
    PrismObject<ShadowType> projectionObject = projContext.getObjectCurrent();
    if (projContext.getObjectCurrent() == null || needToReload(context, projContext)) {
        if (projContext.isAdd()) {
            // No need to load old object, there is none
            projContext.setExists(false);
            projContext.recompute();
            projectionObject = projContext.getObjectNew();
        } else {
            if (projectionObjectOid == null) {
                projContext.setExists(false);
                if (projContext.getResourceShadowDiscriminator() == null || projContext.getResourceShadowDiscriminator().getResourceOid() == null) {
                    throw new SystemException("Projection " + projectionHumanReadableName + " with null OID, no representation and no resource OID in account sync context " + projContext);
                }
            } else {
                projContext.setExists(true);
                GetOperationOptions rootOptions = GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE);
                if (projContext.isDoReconciliation()) {
                    if (SchemaConstants.CHANGE_CHANNEL_DISCOVERY_URI.equals(context.getChannel())) {
                        // Avoid discovery loops
                        rootOptions.setDoNotDiscovery(true);
                    }
                } else {
                    rootOptions.setNoFetch(true);
                }
                rootOptions.setAllowNotFound(true);
                Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(rootOptions);
                if (LOGGER.isTraceEnabled()) {
                    LOGGER.trace("Loading shadow {} for projection {}, options={}", projectionObjectOid, projectionHumanReadableName, options);
                }
                try {
                    PrismObject<ShadowType> objectOld = provisioningService.getObject(projContext.getObjectTypeClass(), projectionObjectOid, options, task, result);
                    if (LOGGER.isTraceEnabled()) {
                        if (!GetOperationOptions.isNoFetch(rootOptions) && !GetOperationOptions.isRaw(rootOptions)) {
                            if (LOGGER.isTraceEnabled()) {
                                LOGGER.trace("Full shadow loaded for {}:\n{}", projectionHumanReadableName, objectOld.debugDump(1));
                            }
                        }
                    }
                    Validate.notNull(objectOld.getOid());
                    if (InternalsConfig.consistencyChecks) {
                        String resourceOid = projContext.getResourceOid();
                        if (resourceOid != null && !resourceOid.equals(objectOld.asObjectable().getResourceRef().getOid())) {
                            throw new IllegalStateException("Loaded shadow with wrong resourceRef. Loading shadow " + projectionObjectOid + ", got " + objectOld.getOid() + ", expected resourceRef " + resourceOid + ", but was " + objectOld.asObjectable().getResourceRef().getOid() + " for context " + projectionHumanReadableName);
                        }
                    }
                    projContext.setLoadedObject(objectOld);
                    ShadowType oldShadow = objectOld.asObjectable();
                    if (projContext.isDoReconciliation()) {
                        projContext.determineFullShadowFlag(oldShadow.getFetchResult());
                    } else {
                        projContext.setFullShadow(false);
                    }
                    projectionObject = objectOld;
                } catch (ObjectNotFoundException ex) {
                    // This does not mean BROKEN. The projection was there, but it gone now. What we really want here
                    // is a thombstone projection.
                    thombstone = true;
                    projContext.setFullShadow(false);
                    LOGGER.warn("Could not find object with oid {}. The projection context {} is marked as thombstone.", projectionObjectOid, projectionHumanReadableName);
                } catch (CommunicationException | SchemaException | ConfigurationException | SecurityViolationException | RuntimeException | Error e) {
                    LOGGER.warn("Problem while getting object with oid {}. Projection context {} is marked as broken: {}: {}", projectionObjectOid, projectionHumanReadableName, e.getClass().getSimpleName(), e.getMessage());
                    projContext.setSynchronizationPolicyDecision(SynchronizationPolicyDecision.BROKEN);
                    ResourceType resourceType = projContext.getResource();
                    if (resourceType == null) {
                        throw e;
                    } else {
                        ErrorSelectorType errorSelector = null;
                        if (resourceType.getConsistency() != null) {
                            errorSelector = resourceType.getConsistency().getConnectorErrorCriticality();
                        }
                        if (errorSelector == null) {
                            if (e instanceof SchemaException) {
                                // We cannot do any better.
                                return;
                            } else {
                                throw e;
                            }
                        } else {
                            if (ExceptionUtil.isSelected(errorSelector, e)) {
                                throw e;
                            } else {
                                return;
                            }
                        }
                    }
                }
            }
            projContext.setFresh(true);
        }
    } else {
        projectionObject = projContext.getObjectCurrent();
        if (projectionObjectOid != null) {
            projContext.setExists(true);
        }
    }
    // Determine Resource
    ResourceType resourceType = projContext.getResource();
    String resourceOid = null;
    if (resourceType == null) {
        if (projectionObject != null) {
            ShadowType shadowType = projectionObject.asObjectable();
            resourceOid = ShadowUtil.getResourceOid(shadowType);
        } else if (projContext.getResourceShadowDiscriminator() != null) {
            resourceOid = projContext.getResourceShadowDiscriminator().getResourceOid();
        } else if (!thombstone) {
            throw new IllegalStateException("No shadow, no discriminator and not thombstone? That won't do. Projection " + projectionHumanReadableName);
        }
    } else {
        resourceOid = resourceType.getOid();
    }
    // Determine discriminator
    ResourceShadowDiscriminator discr = projContext.getResourceShadowDiscriminator();
    if (discr == null) {
        if (projectionObject != null) {
            ShadowType accountShadowType = projectionObject.asObjectable();
            String intent = ShadowUtil.getIntent(accountShadowType);
            ShadowKindType kind = ShadowUtil.getKind(accountShadowType);
            discr = new ResourceShadowDiscriminator(resourceOid, kind, intent, thombstone);
        } else {
            discr = new ResourceShadowDiscriminator(null, null, null, thombstone);
        }
        projContext.setResourceShadowDiscriminator(discr);
    } else {
        if (thombstone) {
            // We do not want to reset thombstone flag if it was set before
            discr.setThombstone(thombstone);
        }
    }
    // Load resource
    if (resourceType == null && resourceOid != null) {
        resourceType = LensUtil.getResourceReadOnly(context, resourceOid, provisioningService, task, result);
        projContext.setResource(resourceType);
    }
    //Determine refined schema and password policies for account type
    RefinedObjectClassDefinition structuralObjectClassDef = projContext.getStructuralObjectClassDefinition();
    if (structuralObjectClassDef != null) {
        ObjectReferenceType passwordPolicyRef = structuralObjectClassDef.getPasswordPolicy();
        if (passwordPolicyRef != null && passwordPolicyRef.getOid() != null) {
            PrismObject<ValuePolicyType> passwordPolicy = cacheRepositoryService.getObject(ValuePolicyType.class, passwordPolicyRef.getOid(), null, result);
            if (passwordPolicy != null) {
                projContext.setAccountPasswordPolicy(passwordPolicy.asObjectable());
            }
        }
    }
    //set limitation, e.g. if this projection context should be recomputed and processed by projector
    if (ModelExecuteOptions.isLimitPropagation(context.getOptions())) {
        if (context.getTriggeredResourceOid() != null) {
            if (!context.getTriggeredResourceOid().equals(resourceOid)) {
                projContext.setCanProject(false);
            }
        }
    }
    setPrimaryDeltaOldValue(projContext);
}
Also used : SecurityViolationException(com.evolveum.midpoint.util.exception.SecurityViolationException) RefinedObjectClassDefinition(com.evolveum.midpoint.common.refinery.RefinedObjectClassDefinition) GetOperationOptions(com.evolveum.midpoint.schema.GetOperationOptions) SystemException(com.evolveum.midpoint.util.exception.SystemException) ConfigurationException(com.evolveum.midpoint.util.exception.ConfigurationException) SchemaException(com.evolveum.midpoint.util.exception.SchemaException) CommunicationException(com.evolveum.midpoint.util.exception.CommunicationException) SelectorOptions(com.evolveum.midpoint.schema.SelectorOptions) ObjectNotFoundException(com.evolveum.midpoint.util.exception.ObjectNotFoundException) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 8 with ResourceShadowDiscriminator

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

the class ContextLoader method needToReload.

private <F extends ObjectType> boolean needToReload(LensContext<F> context, LensProjectionContext projContext) {
    ResourceShadowDiscriminator discr = projContext.getResourceShadowDiscriminator();
    if (discr == null) {
        return false;
    }
    // changes applied to one of them are not automatically reflected on on other. therefore we need to reload.
    if (discr.getOrder() == 0) {
        return false;
    }
    int executionWave = context.getExecutionWave();
    int projCtxWave = projContext.getWave();
    if (executionWave == projCtxWave - 1) {
        // Reload right before its execution wave
        return true;
    }
    return false;
}
Also used : ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 9 with ResourceShadowDiscriminator

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

the class DependencyProcessor method preprocessDependencies.

public <F extends ObjectType> void preprocessDependencies(LensContext<F> context) {
    //in the first wave we do not have enough information to preprocess contexts
    if (context.getExecutionWave() == 0) {
        return;
    }
    for (LensProjectionContext projContext : context.getProjectionContexts()) {
        if (!projContext.isCanProject()) {
            continue;
        }
        for (ResourceObjectTypeDependencyType dependency : projContext.getDependencies()) {
            ResourceShadowDiscriminator refRat = new ResourceShadowDiscriminator(dependency, projContext.getResource().getOid(), projContext.getKind());
            LOGGER.trace("LOOKING FOR {}", refRat);
            LensProjectionContext dependencyAccountContext = context.findProjectionContext(refRat);
            ResourceObjectTypeDependencyStrictnessType strictness = ResourceTypeUtil.getDependencyStrictness(dependency);
            if (dependencyAccountContext != null) {
                if (!dependencyAccountContext.isCanProject()) {
                    continue;
                }
                // We have the context of the object that we depend on. We need to check if it was provisioned.
                if (strictness == ResourceObjectTypeDependencyStrictnessType.STRICT || strictness == ResourceObjectTypeDependencyStrictnessType.RELAXED) {
                    if (wasExecuted(dependencyAccountContext)) {
                        // everything OK
                        if (ResourceTypeUtil.isForceLoadDependentShadow(dependency) && !dependencyAccountContext.isDelete()) {
                            dependencyAccountContext.setDoReconciliation(true);
                            projContext.setDoReconciliation(true);
                        }
                    }
                }
            }
        }
    }
}
Also used : ResourceObjectTypeDependencyType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyType) ResourceObjectTypeDependencyStrictnessType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyStrictnessType) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator)

Example 10 with ResourceShadowDiscriminator

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

the class DependencyProcessor method determineProjectionWaveProvision.

private <F extends ObjectType> LensProjectionContext determineProjectionWaveProvision(LensContext<F> context, LensProjectionContext projectionContext, ResourceObjectTypeDependencyType inDependency, List<ResourceObjectTypeDependencyType> depPath) throws PolicyViolationException {
    if (depPath == null) {
        depPath = new ArrayList<ResourceObjectTypeDependencyType>();
    }
    int determinedWave = 0;
    int determinedOrder = 0;
    for (ResourceObjectTypeDependencyType outDependency : projectionContext.getDependencies()) {
        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("DEP: {}", outDependency);
        }
        if (inDependency != null && isHigerOrder(outDependency, inDependency)) {
            // otherwise we can end up in endless loop even for legal dependencies.
            continue;
        }
        checkForCircular(depPath, outDependency);
        depPath.add(outDependency);
        ResourceShadowDiscriminator refDiscr = new ResourceShadowDiscriminator(outDependency, projectionContext.getResource().getOid(), projectionContext.getKind());
        LensProjectionContext dependencyProjectionContext = findDependencyTargetContext(context, projectionContext, outDependency);
        //			}
        if (dependencyProjectionContext == null || dependencyProjectionContext.isDelete()) {
            ResourceObjectTypeDependencyStrictnessType outDependencyStrictness = ResourceTypeUtil.getDependencyStrictness(outDependency);
            if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.STRICT) {
                throw new PolicyViolationException("Unsatisfied strict dependency of account " + projectionContext.getResourceShadowDiscriminator() + " dependent on " + refDiscr + ": Account not provisioned");
            } else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.LAX) {
                // independent object not in the context, just ignore it
                LOGGER.debug("Unsatisfied lax dependency of account " + projectionContext.getResourceShadowDiscriminator() + " dependent on " + refDiscr + "; dependency skipped");
            } else if (outDependencyStrictness == ResourceObjectTypeDependencyStrictnessType.RELAXED) {
                // independent object not in the context, just ignore it
                LOGGER.debug("Unsatisfied relaxed dependency of account " + projectionContext.getResourceShadowDiscriminator() + " dependent on " + refDiscr + "; dependency skipped");
            } else {
                throw new IllegalArgumentException("Unknown dependency strictness " + outDependency.getStrictness() + " in " + refDiscr);
            }
        } else {
            dependencyProjectionContext = determineProjectionWave(context, dependencyProjectionContext, outDependency, depPath);
            if (dependencyProjectionContext.getWave() + 1 > determinedWave) {
                determinedWave = dependencyProjectionContext.getWave() + 1;
                if (outDependency.getOrder() == null) {
                    determinedOrder = 0;
                } else {
                    determinedOrder = outDependency.getOrder();
                }
            }
        }
        depPath.remove(outDependency);
    }
    LensProjectionContext resultAccountContext = projectionContext;
    if (projectionContext.getWave() >= 0 && projectionContext.getWave() != determinedWave) {
        // Wave for this context was set during the run of this method (it was not set when we
        // started, we checked at the beginning). Therefore this context must have been visited again.
        // therefore there is a circular dependency. Therefore we need to create another context to split it.
        ResourceShadowDiscriminator origDiscr = projectionContext.getResourceShadowDiscriminator();
        ResourceShadowDiscriminator discr = new ResourceShadowDiscriminator(origDiscr.getResourceOid(), origDiscr.getKind(), origDiscr.getIntent(), origDiscr.isThombstone());
        discr.setOrder(determinedOrder);
        if (!projectionContext.compareResourceShadowDiscriminator(discr, true)) {
            resultAccountContext = createAnotherContext(context, projectionContext, discr);
        }
    }
    //		LOGGER.trace("Wave for {}: {}", resultAccountContext.getResourceAccountType(), wave);
    resultAccountContext.setWave(determinedWave);
    return resultAccountContext;
}
Also used : ResourceObjectTypeDependencyType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyType) ResourceObjectTypeDependencyStrictnessType(com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceObjectTypeDependencyStrictnessType) LensProjectionContext(com.evolveum.midpoint.model.impl.lens.LensProjectionContext) ResourceShadowDiscriminator(com.evolveum.midpoint.schema.ResourceShadowDiscriminator) PolicyViolationException(com.evolveum.midpoint.util.exception.PolicyViolationException)

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