Skip to content

Commit

Permalink
Consistency update: more fixes - dead shadows (MID-3603)
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Aug 8, 2018
1 parent 3079ddd commit 48a3997
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
Expand Up @@ -1401,7 +1401,13 @@ public static LensProjectionContext fromLensProjectionContextType(LensProjection
}

// determines whether full shadow is present, based on operation result got from provisioning
public void determineFullShadowFlag(OperationResultType fetchResult) {
public void determineFullShadowFlag(PrismObject<ShadowType> loadedShadow) {
ShadowType shadowType = loadedShadow.asObjectable();
if (ShadowUtil.isDead(shadowType) || !ShadowUtil.isExists(shadowType)) {
setFullShadow(false);
return;
}
OperationResultType fetchResult = shadowType.getFetchResult();
if (fetchResult != null
&& (fetchResult.getStatus() == OperationResultStatusType.PARTIAL_ERROR
|| fetchResult.getStatus() == OperationResultStatusType.FATAL_ERROR)
Expand Down
Expand Up @@ -1059,14 +1059,17 @@ private <F extends ObjectType> void finishLoadOfProjectionContext(LensContext<F>
}
}
projContext.setLoadedObject(objectOld);
ShadowType oldShadow = objectOld.asObjectable();
if (projContext.isDoReconciliation()) {
projContext.determineFullShadowFlag(oldShadow.getFetchResult());
projContext.determineFullShadowFlag(objectOld);
} else {
projContext.setFullShadow(false);
}
projContext.setExists(ShadowUtil.isExists(objectOld.asObjectable()));
projectionObject = objectOld;
if (!ShadowUtil.isExists(objectOld.asObjectable())) {
projContext.setExists(false);
LOGGER.debug("Foud only dead {} for projection context {}.", objectOld, projectionHumanReadableName);
refreshContextAfterShadowNotFound(context, projContext, options, task, result);
}

} catch (ObjectNotFoundException ex) {
LOGGER.debug("Could not find object with oid {} for projection context {}.", projectionObjectOid, projectionHumanReadableName);
Expand Down Expand Up @@ -1268,17 +1271,16 @@ public <F extends ObjectType> void loadFullShadow(LensContext<F> context, LensPr
Collection<SelectorOptions<GetOperationOptions>> options = SelectorOptions.createCollection(getOptions);
applyAttributesToGet(projCtx, options);
try {
PrismObject<ShadowType> objectCurrent = provisioningService.getObject(ShadowType.class,
projCtx.getOid(), options, task, result);
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());
projCtx.determineFullShadowFlag(objectCurrent);
if (!ShadowUtil.isExists(objectCurrent.asObjectable())) {
LOGGER.debug("Load of full resource object {} ended with non-existent shadow (options={})", projCtx, getOptions);
projCtx.setExists(false);
refreshContextAfterShadowNotFound(context, projCtx, options, task, result);
}

} catch (ObjectNotFoundException ex) {
LOGGER.debug("Load of full resource object {} ended with ObjectNotFoundException (options={})", projCtx, getOptions);
Expand Down
Expand Up @@ -161,10 +161,9 @@ private <F extends ObjectType> void processReconciliationFocus(LensContext<F> co
PrismObject<ShadowType> objectOld = provisioningService.getObject(ShadowType.class,
projCtx.getOid(), SelectorOptions.createCollection(rootOps),
task, result);
ShadowType oldShadow = objectOld.asObjectable();
projCtx.determineFullShadowFlag(oldShadow.getFetchResult());
projCtx.determineFullShadowFlag(objectOld);
projCtx.setLoadedObject(objectOld);

projCtx.setExists(ShadowUtil.isExists(objectOld.asObjectable()));
projCtx.recompute();
}

Expand Down
Expand Up @@ -94,11 +94,23 @@ public PrismObject<ShadowType> handleGetError(ProvisioningContext ctx,
}

if (repositoryShadow != null) {
// We always want to return repository shadow it such shadow is available.
// The shadow may be dead, or it may be marked as "not exists", but we want
// to return something if shadow exists in the repo. Otherwise model may
// unlink the shadow or otherwise "forget" about it.
LOGGER.debug("Shadow {} not found on the resource. However still have it in the repository. Therefore returning repository version.", repositoryShadow);

if (ShadowUtil.isExists(repositoryShadow.asObjectable())) {
// This is some kind of reality mismatch. We obviously have shadow that is supposed
// to be alive (exists=true). But it does not exist on resource.
// This is NOT gestation quantum state, as that is handled directly in ShadowCache.
// This may be "lost shadow" - shadow which exists but the resource object has disappeared without trace.
// Or this may be a corpse - quantum state that has just collapsed to to tombstone.
// Either way, it should be safe to set exists=false.
LOGGER.trace("Setting {} as tombstone. This may be a quntum state collapse. Or maybe a lost shadow.", repositoryShadow);
repositoryShadow = shadowManager.markShadowDead(repositoryShadow, parentResult);
} else {
// We always want to return repository shadow it such shadow is available.
// The shadow may be dead, or it may be marked as "not exists", but we want
// to return something if shadow exists in the repo. Otherwise model may
// unlink the shadow or otherwise "forget" about it.
LOGGER.debug("Shadow {} not found on the resource. However still have it in the repository. Therefore returning repository version.", repositoryShadow);
}
parentResult.setStatus(OperationResultStatus.HANDLED_ERROR);
return repositoryShadow;
}
Expand Down

0 comments on commit 48a3997

Please sign in to comment.