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