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;
}
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);
}
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;
}
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);
}
}
}
}
}
}
}
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;
}
Aggregations