Skip to content

Commit

Permalink
Fix tombstone marking in reconciliation
Browse files Browse the repository at this point in the history
The remaining shadows reconciliation activity (after recent changes)
did not mark deleted shadows as tombstones. This is now fixed.
  • Loading branch information
mederly committed Aug 25, 2021
1 parent c853833 commit faaed42
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,8 @@ public void test006TestReconDelete() throws Exception {
assertTask(TASK_RECON_DUMMY_OID, "after")
.display(); // TODO

PrismObject<ShadowType> shadow = repositoryService.getObject(ShadowType.class, ACCOUNT_BEFORE_SCRIPT_OID, null, parentResult);
ShadowAsserter.forShadow(shadow)
assertRepoShadow(ACCOUNT_BEFORE_SCRIPT_OID)
.display()
.assertDead()
.assertIsNotExists();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,11 @@ public PrismObject<ShadowType> handleGetError(ProvisioningContext ctx,
if (getErrorReportingMethod(rootOptions) == FetchErrorReportingMethodType.FORCED_EXCEPTION) {
LOGGER.debug("Trying to handle {} but 'forced exception' mode is selected. Will rethrow it.",
cause.getClass().getSimpleName());
return super.handleGetError(ctx, null, rootOptions, cause, task, parentResult);

if (repositoryShadow != null && ShadowUtil.isExists(repositoryShadow.asObjectable())) {
markShadowTombstoneIfExecutionMode(repositoryShadow, task, parentResult);
return super.handleGetError(ctx, null, rootOptions, cause, task, parentResult);
}
}

if (ProvisioningUtil.isDoDiscovery(ctx.getResource(), rootOptions)) {
Expand All @@ -84,19 +88,7 @@ public PrismObject<ShadowType> handleGetError(ProvisioningContext ctx,

if (repositoryShadow != null) {
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.
if (TaskUtil.isExecute(task)) {
LOGGER.trace("Setting {} as tombstone. This may be a quantum state collapse. Or maybe a lost shadow.",
repositoryShadow);
repositoryShadow = shadowManager.markShadowTombstone(repositoryShadow, task, parentResult);
} else {
LOGGER.trace("Not in execute mode ({}). Keeping shadow marked as 'exists'.", TaskUtil.getExecutionMode(task));
}
repositoryShadow = markShadowTombstoneIfExecutionMode(repositoryShadow, task, 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
Expand All @@ -112,6 +104,24 @@ public PrismObject<ShadowType> handleGetError(ProvisioningContext ctx,
}
}

private PrismObject<ShadowType> markShadowTombstoneIfExecutionMode(PrismObject<ShadowType> repositoryShadow, Task task,
OperationResult parentResult) throws SchemaException {
// 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.
if (TaskUtil.isExecute(task)) {
LOGGER.trace("Setting {} as tombstone. This may be a quantum state collapse. Or maybe a lost shadow.",
repositoryShadow);
repositoryShadow = shadowManager.markShadowTombstone(repositoryShadow, task, parentResult);
} else {
LOGGER.trace("Not in execute mode ({}). Keeping shadow marked as 'exists'.", TaskUtil.getExecutionMode(task));
}
return repositoryShadow;
}

@Override
public OperationResultStatus handleModifyError(ProvisioningContext ctx, PrismObject<ShadowType> repoShadow,
Collection<? extends ItemDelta> modifications, ProvisioningOperationOptions options,
Expand Down

0 comments on commit faaed42

Please sign in to comment.