diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java index a9899a71b92..62a8fd0b593 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/LensProjectionContext.java @@ -1257,7 +1257,7 @@ public String debugDump(int indent, boolean showTriples) { sb.append(", NOT FRESH"); } if (resourceShadowDiscriminator != null && resourceShadowDiscriminator.isTombstone()) { - sb.append(", THOMBSTONE"); + sb.append(", TOMBSTONE"); } if (syncAbsoluteTrigger) { sb.append(", SYNC TRIGGER"); diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractDirectManualResourceTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractDirectManualResourceTest.java index 6f2f8e9d3f1..bf76dc71c3e 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractDirectManualResourceTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractDirectManualResourceTest.java @@ -1084,12 +1084,7 @@ public void test300UnassignAccountWill() throws Exception { pendingOperation = findPendingOperation(shadowModel, OperationResultStatusType.IN_PROGRESS); assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); assertSteadyResources(); @@ -1158,12 +1153,7 @@ public void test302RecomputeWill() throws Exception { pendingOperation = findPendingOperation(shadowModel, OperationResultStatusType.IN_PROGRESS); assertPendingOperation(shadowModel, pendingOperation, accountWillReqestTimestampStart, accountWillReqestTimestampEnd); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); // Make sure that the account is still linked PrismObject userAfter = getUser(userWillOid); @@ -1238,9 +1228,7 @@ public void test310CloseCaseAndReconcileWill() throws Exception { assertUnassignedShadow(shadowModelAsserter, false, ActivationStatusType.ENABLED); // backing store not yet updated assertShadowPassword(shadowModelAsserter); - PrismObject shadowModelFuture = assertModelShadowFuture(accountWillOid) - .getObject(); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -1297,12 +1285,7 @@ public void test320RecomputeWillAfter5min() throws Exception { assertUnassignedShadow(shadowModelAsserter, false, ActivationStatusType.ENABLED); // backing store not yet updated assertShadowPassword(shadowModelAsserter); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -1346,7 +1329,7 @@ public void test330UpdateBackingStoreAndRecomputeWill() throws Exception { .end(); assertUnassignedShadow(shadowRepoAsserter, true, null); - ShadowAsserter shadowModelAsserter = assertModelShadowNoFetch(accountWillOid) + ShadowAsserter shadowModelAsserterNoFetch = assertModelShadowNoFetch(accountWillOid) .assertName(USER_WILL_NAME) .assertKind(ShadowKindType.ACCOUNT) .pendingOperations() @@ -1357,17 +1340,12 @@ public void test330UpdateBackingStoreAndRecomputeWill() throws Exception { .assertCompletionTimestamp(accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd) .end() .end(); - assertUnassignedShadow(shadowModelAsserter, true, ActivationStatusType.DISABLED); + assertUnassignedShadow(shadowModelAsserterNoFetch, true, null); // Do NOT assert password here. There is no password even for semi-manual case as the shadow is dead and account gone. - assertModelShadow(accountWillOid) - .assertTombstone(); - - assertModelShadowFuture(accountWillOid) - .assertTombstone(); - - assertModelShadowFutureNoFetch(accountWillOid) - .assertTombstone(); + assertUnassignedShadow(assertModelShadow(accountWillOid), true, ActivationStatusType.DISABLED); + assertUnassignedShadow(assertModelShadowFuture(accountWillOid), true, ActivationStatusType.DISABLED); + assertUnassignedShadow(assertModelShadowFutureNoFetch(accountWillOid), true, ActivationStatusType.DISABLED); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -1402,11 +1380,18 @@ public void test340RecomputeWillAfter25min() throws Exception { assertUserAfter(userWillOid) .singleLink() - .resolveTarget() - .assertOid(accountWillOid) - .assertDead() - .pendingOperations() - .singleOperation(); + .assertOid(accountWillOid); + + ShadowAsserter shadowRepoAsserter = assertRepoShadow(accountWillOid) + .pendingOperations() + .singleOperation() + .assertRequestTimestamp(accountWillReqestTimestampStart, accountWillReqestTimestampEnd) + .assertExecutionStatus(PendingOperationExecutionStatusType.COMPLETED) + .assertResultStatus(OperationResultStatusType.SUCCESS) + .assertCompletionTimestamp(accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd) + .end() + .end(); + assertUnassignedShadow(shadowRepoAsserter, true, null); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -1439,12 +1424,14 @@ public void test342RecomputeWillAfter35min() throws Exception { assertUserAfter(userWillOid) .singleLink() - .resolveTarget() - .assertOid(accountWillOid) - .assertDead() - .pendingOperations() - .assertNone(); + .assertOid(accountWillOid); + ShadowAsserter shadowRepoAsserter = assertRepoShadow(accountWillOid) + .pendingOperations() + .assertNone() + .end(); + assertUnassignedShadow(shadowRepoAsserter, true, null); + assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); assertSteadyResources(); @@ -1515,9 +1502,10 @@ public void test500AssignWillRoleOne() throws Exception { /** * Unassign account before anybody had the time to do anything about it. + * Snapshot (backing store) is never updated. * Create ticket is not closed, the account is not yet created and we * want to delete it. - * The shadow should exist, all the operations are should be cancelled. + * The shadow should exist, all the operations should be cancelled. * MID-4037 */ @Test @@ -1569,9 +1557,9 @@ public void test510UnassignWillRoleOne() throws Exception { .pendingOperations() .assertOperations(2); - assertModelShadowFuture(accountWillOid) - .assertName(USER_WILL_NAME) - .assertTombstone(); + ShadowAsserter shadowFutureAsserter = assertModelShadowFuture(accountWillOid) + .assertName(USER_WILL_NAME); + assertUnassignedShadow(shadowFutureAsserter, true, ActivationStatusType.DISABLED); // Make sure that the account is still linked assertUserAfter(userWillOid) @@ -1635,9 +1623,9 @@ public void test512ReconcileWill() throws Exception { .pendingOperations() .assertOperations(2); - assertModelShadowFuture(accountWillOid) - .assertName(USER_WILL_NAME) - .assertTombstone(); + ShadowAsserter shadowFutureAsserter = assertModelShadowFuture(accountWillOid) + .assertName(USER_WILL_NAME); + assertUnassignedShadow(shadowFutureAsserter, true, ActivationStatusType.DISABLED); // Make sure that the account is still linked assertUserAfter(userWillOid) @@ -1652,7 +1640,14 @@ public void test512ReconcileWill() throws Exception { } /** - * Close both cases at the same time. + * Close both cases (assign and unassign) at the same time. + * + * This is an interesting case for SemiManualDisable. In that case + * we would expect that the account was created and that it was disabled. + * But snapshot (backing store) is never updated as the account was not + * created at all. But as long as the pending operations are in + * grace period we have to pretend that the account was created. + * * MID-4037 */ @Test @@ -1680,6 +1675,8 @@ public void test515CloseCasesAndReconcileWill() throws Exception { accountWillCompletionTimestampEnd = clock.currentTimeXMLGregorianCalendar(); + // For SemiManualDisable case the shadow is not dead yet. We do not know whether + // the account was created or not. We have to assume that it was created. ShadowAsserter shadowRepoAsserter = assertRepoShadow(accountWillOid) .pendingOperations() .assertOperations(2) @@ -1701,12 +1698,12 @@ public void test515CloseCasesAndReconcileWill() throws Exception { .assertKind(ShadowKindType.ACCOUNT); assertUnassignedShadow(shadowModelAsserter, true, null); // Shadow in not in the backing store - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, false); + // For SemiManualDisable case we still pretend that the shadow will exist + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), false); + + assertUserAfter(userWillOid) + .singleLink() + .assertOid(accountWillOid); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); assertCase(willSecondLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -1744,6 +1741,14 @@ protected void assertWillUnassignPendingOperationCompleted(ShadowAsserter /** * ff 20min, grace period expired, But we keep pending operation and shadow * because they are not expired yet. + * + * SemiManualDisable case gets even more interesting here. + * Snapshot (backing store) was never updated as the account was in fact not + * created at all. As pending operations are over grace period now, we stop + * pretending that the account was created. And the reality shows that the + * account was in fact not created at all. This is the point where we should + * end up with a dead shadow. + * * MID-4037 */ @Test diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractGroupingManualResourceTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractGroupingManualResourceTest.java index e2fd037c944..b0a3c9bf881 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractGroupingManualResourceTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractGroupingManualResourceTest.java @@ -695,12 +695,7 @@ public void test300UnassignAccountWill() throws Exception { PendingOperationExecutionStatusType.EXECUTION_PENDING, null, null, null); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); // Make sure that the account is still linked PrismObject userAfter = getUser(userWillOid); @@ -779,12 +774,7 @@ public void test302RunPropagationAfterInterval() throws Exception { null, null); assertEquals("Case ID mismatch", willLastCaseOid, pendingOperation.getAsynchronousOperationReference()); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); // Make sure that the account is still linked PrismObject userAfter = getUser(userWillOid); @@ -846,12 +836,7 @@ public void test310CloseCaseAndRecomputeWill() throws Exception { OperationResultStatusType.SUCCESS, accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, true); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), true); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); } @@ -897,12 +882,7 @@ public void test330UpdateBackingStoreAndRecomputeWill() throws Exception { OperationResultStatusType.SUCCESS, accountWillCompletionTimestampStart, accountWillCompletionTimestampEnd); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountWillOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertWillUnassignedFuture(shadowModelFuture, false); + assertWillUnassignedFuture(assertModelShadowFuture(accountWillOid), false); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java index 0b8a9847685..dd1e384efee 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/AbstractManualResourceTest.java @@ -1090,12 +1090,12 @@ public void test132RecomputeWillAfter32min() throws Exception { assertSuccess(result); assertRepoShadow(accountWillOid) - .pendingOperations() - .assertNone(); + .pendingOperations() + .assertNone(); assertModelShadow(accountWillOid) - .pendingOperations() - .assertNone(); + .pendingOperations() + .assertNone(); assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); @@ -2302,15 +2302,17 @@ protected void assertWillAfterCreateCaseClosed(final String TEST_NAME, boolean b assertCase(willLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); } - protected void assertWillUnassignedFuture(PrismObject shadowModelFuture, boolean assertPassword) { - assertShadowName(shadowModelFuture, USER_WILL_NAME); - assertUnassignedFuture(shadowModelFuture, assertPassword); + protected void assertWillUnassignedFuture(ShadowAsserter shadowModelAsserterFuture, boolean assertPassword) { + shadowModelAsserterFuture + .assertName(USER_WILL_NAME); + assertUnassignedFuture(shadowModelAsserterFuture, assertPassword); } - protected void assertUnassignedFuture(PrismObject shadowModelFuture, boolean assertPassword) { - assertShadowDead(shadowModelFuture); + protected void assertUnassignedFuture(ShadowAsserter shadowModelAsserterFuture, boolean assertPassword) { + shadowModelAsserterFuture + .assertDead(); if (assertPassword) { - assertShadowPassword(shadowModelFuture); + assertShadowPassword(shadowModelAsserterFuture); } } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManual.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManual.java index ad4ece4907a..bbc90938002 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManual.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManual.java @@ -238,13 +238,7 @@ public void test710UnassignAccountJack() throws Exception { pendingOperation = findPendingOperation(shadowModel, OperationResultStatusType.IN_PROGRESS); assertPendingOperation(shadowModel, pendingOperation, accountJackReqestTimestampStart, accountJackReqestTimestampEnd); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountJackOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertShadowName(shadowModelFuture, USER_JACK_USERNAME); - assertUnassignedFuture(shadowModelFuture, true); + assertUnassignedFuture(assertModelShadowFuture(accountJackOid), true); assertCase(jackLastCaseOid, SchemaConstants.CASE_STATE_OPEN); } @@ -302,13 +296,7 @@ public void test712CloseCaseAndRecomputeJack() throws Exception { .end(); assertUnassignedShadow(shadowModelAsserter, true, ActivationStatusType.DISABLED); - PrismObject shadowModelFuture = modelService.getObject(ShadowType.class, - accountJackOid, - SelectorOptions.createCollection(GetOperationOptions.createPointInTimeType(PointInTimeType.FUTURE)), - task, result); - display("Model shadow (future)", shadowModelFuture); - assertShadowName(shadowModelFuture, USER_JACK_USERNAME); - assertUnassignedFuture(shadowModelFuture, false); + assertUnassignedFuture(assertModelShadowFuture(accountJackOid), false); assertCase(jackLastCaseOid, SchemaConstants.CASE_STATE_CLOSED); } diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManualDisable.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManualDisable.java index d12b673c14c..fb2e91883de 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManualDisable.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/manual/TestSemiManualDisable.java @@ -116,10 +116,12 @@ protected void assertUnassignedShadow(ShadowAsserter shadowModelAsserter, boo } @Override - protected void assertUnassignedFuture(PrismObject shadowModelFuture, boolean assertPassword) { - assertShadowActivationAdministrativeStatus(shadowModelFuture, ActivationStatusType.DISABLED); + protected void assertUnassignedFuture(ShadowAsserter shadowModelAsserterFuture, boolean assertPassword) { + shadowModelAsserterFuture + .assertLife() + .assertAdministrativeStatus(ActivationStatusType.DISABLED); if (assertPassword) { - assertShadowPassword(shadowModelFuture); + assertShadowPassword(shadowModelAsserterFuture); } } diff --git a/model/model-intest/src/test/resources/manual/resource-semi-manual-disable.xml b/model/model-intest/src/test/resources/manual/resource-semi-manual-disable.xml index 7764e2dcdea..3804efbe414 100644 --- a/model/model-intest/src/test/resources/manual/resource-semi-manual-disable.xml +++ b/model/model-intest/src/test/resources/manual/resource-semi-manual-disable.xml @@ -200,6 +200,8 @@ true light PT15M + PT30M + PT2H true @@ -224,9 +226,6 @@ deleted true - - http://midpoint.evolveum.com/xml/ns/public/model/action-3#unlink - unlinked