Skip to content

Commit

Permalink
Attempt to replicate MID-2370
Browse files Browse the repository at this point in the history
  • Loading branch information
semancik committed Jul 7, 2015
1 parent 39b6c19 commit ccee8c0
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 28 deletions.
Expand Up @@ -53,7 +53,11 @@ public void addMember(String newMember) throws SchemaViolationException, Connect
}

public boolean containsMember(String member) {
return getMembers().contains(member); // TODO ok? what about case ignoring scenarios?
Collection<String> members = getMembers();
if (members == null) {
return false;
}
return members.contains(member); // TODO ok? what about case ignoring scenarios?
}

public void removeMember(String newMember) throws SchemaViolationException, ConnectException, FileNotFoundException {
Expand Down
Expand Up @@ -579,14 +579,17 @@ private void reconcileShadow(PrismObject<ShadowType> shadow, PrismObject<Resourc
} catch (ObjectNotFoundException e) {
// Account is gone
reactShadowGone(shadow, resource, task, opResult);
if (opResult.isUnknown()) {
opResult.setStatus(OperationResultStatus.HANDLED_ERROR);
}
} catch (CommunicationException e) {
processShadowReconErrror(e, shadow, opResult);
processShadowReconError(e, shadow, opResult);
} catch (SchemaException e) {
processShadowReconErrror(e, shadow, opResult);
processShadowReconError(e, shadow, opResult);
} catch (ConfigurationException e) {
processShadowReconErrror(e, shadow, opResult);
processShadowReconError(e, shadow, opResult);
} catch (SecurityViolationException e) {
processShadowReconErrror(e, shadow, opResult);
processShadowReconError(e, shadow, opResult);
}
}

Expand All @@ -606,17 +609,17 @@ private void reactShadowGone(PrismObject<ShadowType> shadow, PrismObject<Resourc
Utils.clearRequestee(task);
changeNotificationDispatcher.notifyChange(change, task, result);
} catch (SchemaException e) {
processShadowReconErrror(e, shadow, result);
processShadowReconError(e, shadow, result);
} catch (ObjectNotFoundException e) {
processShadowReconErrror(e, shadow, result);
processShadowReconError(e, shadow, result);
} catch (CommunicationException e) {
processShadowReconErrror(e, shadow, result);
processShadowReconError(e, shadow, result);
} catch (ConfigurationException e) {
processShadowReconErrror(e, shadow, result);
processShadowReconError(e, shadow, result);
}
}

private void processShadowReconErrror(Exception e, PrismObject<ShadowType> shadow, OperationResult opResult) {
private void processShadowReconError(Exception e, PrismObject<ShadowType> shadow, OperationResult opResult) {
LOGGER.error("Error reconciling shadow {}: {}", new Object[]{shadow, e.getMessage(), e});
opResult.recordFatalError(e);
// TODO: store error in the shadow?
Expand Down
Expand Up @@ -162,6 +162,9 @@ public class TestImportRecon extends AbstractInitializedModelIntegrationTest {
private static final String ACCOUNT_CRUFF_OID = "22220000-2200-0000-0000-444400004468";
private static final String ACCOUNT_CRUFF_NAME = "cruff";
private static final String ACCOUNT_CRUFF_FULLNAME = "Cruff";

private static final String ACCOUNT_HTM_NAME = "htm";
private static final String ACCOUNT_HTM_FULL_NAME = "Horatio Torquemada Marley";

protected static final File RESOURCE_DUMMY_AZURE_FILE = new File(TEST_DIR, "resource-dummy-azure.xml");
protected static final File RESOURCE_DUMMY_AZURE_DEPRECATED_FILE = new File(TEST_DIR, "resource-dummy-azure-deprecated.xml");
Expand Down Expand Up @@ -900,7 +903,101 @@ public void test229ReconcileDummyFixed() throws Exception {
display("Recon task result", reconTaskResult);
TestUtil.assertSuccess(reconTaskResult);
}


@Test
public void test230ReconcileDummyRename() throws Exception {
final String TEST_NAME = "test230ReconcileDummyRename";
TestUtil.displayTestTile(this, TEST_NAME);

// GIVEN
Task task = createTask(TestImportRecon.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
assumeAssignmentPolicy(AssignmentPolicyEnforcementType.NONE);

dummyResource.setBreakMode(BreakMode.NONE);
dummyResource.getAccountByUsername(ACCOUNT_GUYBRUSH_DUMMY_USERNAME).setModifyBreakMode(BreakMode.NONE);

PrismObject<UserType> userHerman = findUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
String hermanShadowOid = getSingleLinkOid(userHerman);

assertShadows(14);

dummyResource.renameAccount(ACCOUNT_HERMAN_DUMMY_USERNAME, ACCOUNT_HERMAN_DUMMY_USERNAME, ACCOUNT_HTM_NAME);
DummyAccount dummyAccountHtm = getDummyAccount(null, ACCOUNT_HTM_NAME);
dummyAccountHtm.replaceAttributeValues(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME, ACCOUNT_HTM_FULL_NAME);

dummyResource.purgeScriptHistory();
dummyAuditService.clear();
rememberShadowFetchOperationCount();
reconciliationTaskResultListener.clear();

// WHEN
TestUtil.displayWhen(TEST_NAME);
restartTask(TASK_RECONCILE_DUMMY_OID);
waitForTaskFinish(TASK_RECONCILE_DUMMY_OID, false, DEFAULT_TASK_WAIT_TIMEOUT, true);

// THEN
TestUtil.displayThen(TEST_NAME);
// First fetch: searchIterative
// Second fetch: "fetchback" of modified account (htm)
assertShadowFetchOperationCountIncrement(2);

reconciliationTaskResultListener.assertResult(RESOURCE_DUMMY_OID, 0, 7, 0, 1);

List<PrismObject<UserType>> users = modelService.searchObjects(UserType.class, null, null, task, result);
display("Users after import", users);

assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME); // not deleted. reaction=unlink

assertNoObject(ShadowType.class, hermanShadowOid, task, result);

assertImportedUserByOid(USER_ADMINISTRATOR_OID);
assertImportedUserByOid(USER_JACK_OID);
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_GUYBRUSH_OID, RESOURCE_DUMMY_OID);
assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME,
"Dubrish Freepweed");
assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME,
"Melee Island");
assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME,
"Feather duster");
assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME,
"rum");
assertDummyAccountAttribute(null, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_QUOTE_NAME,
"Arr!", "I want to be a pirate!");

assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertNoImporterUserByUsername(ACCOUNT_DAVIEJONES_DUMMY_USERNAME);
assertNoImporterUserByUsername(ACCOUNT_CALYPSO_DUMMY_USERNAME);
assertDummyAccountAttribute(null, ACCOUNT_CALYPSO_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME,
"Calypso");

assertEquals("Unexpected number of users", 11, users.size());

display("Dummy resource", dummyResource.debugDump());

display("Script history", dummyResource.getScriptHistory());

ArrayList<ProvisioningScriptSpec> scripts = new ArrayList<ProvisioningScriptSpec>();
addReconScripts(scripts, ACCOUNT_GUYBRUSH_DUMMY_USERNAME, "Guybrush Threepwood", false);
addReconScripts(scripts, ACCOUNT_STAN_NAME, ACCOUNT_STAN_FULLNAME, false);
addReconScripts(scripts, USER_RAPP_USERNAME, "Rapp Scallion", false);
addReconScripts(scripts, ACCOUNT_HTM_NAME, ACCOUNT_HTM_FULL_NAME, true);
addReconScripts(scripts, ACCOUNT_ELAINE_DUMMY_USERNAME, "Elaine Marley", false);
IntegrationTestTools.assertScripts(dummyResource.getScriptHistory(), scripts.toArray(new ProvisioningScriptSpec[0]));

assertReconAuditModifications(2, TASK_RECONCILE_DUMMY_OID); // the second modification is unlink

assertShadows(14);

// Task result
PrismObject<TaskType> reconTaskAfter = getTask(TASK_RECONCILE_DUMMY_OID);
OperationResultType reconTaskResult = reconTaskAfter.asObjectable().getResult();
display("Recon task result", reconTaskResult);
TestUtil.assertSuccess(reconTaskResult);
}

private void addReconScripts(Collection<ProvisioningScriptSpec> scripts, String username, String fullName, boolean modified) {
addReconScripts(scripts, username, fullName, modified, true);
}
Expand Down Expand Up @@ -968,7 +1065,8 @@ public void test300ReconcileDummyAzure() throws Exception {
assertImportedUserByOid(USER_JACK_OID);
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);

// Otis
assertNoImporterUserByUsername(ACCOUNT_OTIS_NAME);
Expand All @@ -982,7 +1080,7 @@ public void test300ReconcileDummyAzure() throws Exception {
"Calypso");


assertEquals("Unexpected number of users", 10, users.size());
assertEquals("Unexpected number of users", 11, users.size());

display("Dummy resource (azure)", dummyResourceAzure.debugDump());

Expand Down Expand Up @@ -1027,7 +1125,9 @@ public void test310ReconcileDummyAzureAgain() throws Exception {
assertImportedUserByOid(USER_JACK_OID);
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);


// Otis
assertNoImporterUserByUsername(ACCOUNT_OTIS_NAME);
Expand All @@ -1040,7 +1140,7 @@ public void test310ReconcileDummyAzureAgain() throws Exception {
assertDummyAccountAttribute(null, ACCOUNT_CALYPSO_DUMMY_USERNAME, DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_FULLNAME_NAME,
"Calypso");

assertEquals("Unexpected number of users", 10, users.size());
assertEquals("Unexpected number of users", 11, users.size());

display("Dummy resource (azure)", dummyResourceAzure.debugDump());

Expand Down Expand Up @@ -1084,14 +1184,15 @@ public void test400ReconcileDummyLimeAddAccount() throws Exception {
assertImportedUserByOid(USER_JACK_OID);
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);
assertNoImporterUserByUsername(ACCOUNT_OTIS_NAME);
assertDummyAccount(RESOURCE_DUMMY_AZURE_NAME, ACCOUNT_OTIS_NAME, ACCOUNT_OTIS_FULLNAME, false);

// Kate Capsize: user should be created
assertImportedUserByUsername(ACCOUNT_CAPSIZE_NAME, RESOURCE_DUMMY_LIME_OID);

assertEquals("Unexpected number of users", 11, users.size());
assertEquals("Unexpected number of users", 12, users.size());

display("Dummy resource (lime)", dummyResourceLime.debugDump());

Expand Down Expand Up @@ -1136,14 +1237,15 @@ public void test410ReconcileDummyLimeDeleteLinkedAccount() throws Exception {
assertImportedUserByOid(USER_JACK_OID);
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);
assertNoImporterUserByUsername(ACCOUNT_OTIS_NAME);
assertDummyAccount(RESOURCE_DUMMY_AZURE_NAME, ACCOUNT_OTIS_NAME, ACCOUNT_OTIS_FULLNAME, false);

// Kate Capsize: user should be gone
assertNoImporterUserByUsername(ACCOUNT_CAPSIZE_NAME);

assertEquals("Unexpected number of users", 10, users.size());
assertEquals("Unexpected number of users", 11, users.size());

display("Dummy resource (lime)", dummyResourceLime.debugDump());

Expand All @@ -1168,7 +1270,7 @@ public void test500ImportTAugustusFromResourceDummy() throws Exception {
provisioningService.addObject(accountStan, null, null, task, result);

// Preconditions
assertUsers(10);
assertUsers(11);
dummyAuditService.clear();
rememberShadowFetchOperationCount();

Expand Down Expand Up @@ -1200,7 +1302,7 @@ public void test500ImportTAugustusFromResourceDummy() throws Exception {
assertNoImporterUserByUsername(ACCOUNT_DAVIEJONES_DUMMY_USERNAME);
assertNoImporterUserByUsername(ACCOUNT_CALYPSO_DUMMY_USERNAME);

assertUsers(11);
assertUsers(12);

assertShadowKindIntent(ACCOUNT_TAUGUSTUS_OID, ShadowKindType.ACCOUNT, INTENT_TEST);

Expand All @@ -1226,7 +1328,7 @@ public void test502ImportAugustusFromResourceDummy() throws Exception {
provisioningService.addObject(account, null, null, task, result);

// Preconditions
assertUsers(11);
assertUsers(12);
dummyAuditService.clear();
rememberShadowFetchOperationCount();

Expand Down Expand Up @@ -1255,7 +1357,7 @@ public void test502ImportAugustusFromResourceDummy() throws Exception {
assertNoImporterUserByUsername(ACCOUNT_DAVIEJONES_DUMMY_USERNAME);
assertNoImporterUserByUsername(ACCOUNT_CALYPSO_DUMMY_USERNAME);

assertUsers(11);
assertUsers(12);

assertShadowKindIntent(ACCOUNT_AUGUSTUS_OID, ShadowKindType.ACCOUNT, SchemaConstants.INTENT_DEFAULT);
assertShadowKindIntent(ACCOUNT_TAUGUSTUS_OID, ShadowKindType.ACCOUNT, INTENT_TEST);
Expand Down Expand Up @@ -1303,7 +1405,7 @@ public void test510ImportFromResourceDummy() throws Exception {
provisioningService.addObject(account, null, null, task, result);

// Preconditions
assertUsers(11);
assertUsers(12);
dummyAuditService.clear();
rememberShadowFetchOperationCount();

Expand Down Expand Up @@ -1337,7 +1439,8 @@ public void test510ImportFromResourceDummy() throws Exception {
assertImportedUserByOid(USER_BARBOSSA_OID);
assertImportedUserByOid(USER_GUYBRUSH_OID, RESOURCE_DUMMY_OID);
assertImportedUserByOid(USER_RAPP_OID, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_LIME_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_HERMAN_DUMMY_USERNAME);
assertImportedUserByUsername(ACCOUNT_HTM_NAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_STAN_NAME, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(USER_AUGUSTUS_NAME, RESOURCE_DUMMY_OID, RESOURCE_DUMMY_OID);
assertImportedUserByUsername(ACCOUNT_KENNY_NAME, RESOURCE_DUMMY_OID);
Expand All @@ -1351,7 +1454,7 @@ public void test510ImportFromResourceDummy() throws Exception {
assertNoImporterUserByUsername(ACCOUNT_DAVIEJONES_DUMMY_USERNAME);
assertNoImporterUserByUsername(ACCOUNT_CALYPSO_DUMMY_USERNAME);

assertUsers(17);
assertUsers(18);

assertShadowKindIntent(ACCOUNT_AUGUSTUS_OID, ShadowKindType.ACCOUNT, SchemaConstants.INTENT_DEFAULT);
assertShadowKindIntent(ACCOUNT_TAUGUSTUS_OID, ShadowKindType.ACCOUNT, INTENT_TEST);
Expand All @@ -1367,7 +1470,7 @@ public void test900DeleteDummyShadows() throws Exception {
OperationResult result = task.getResult();

// Preconditions
assertUsers(17);
assertUsers(18);
dummyAuditService.clear();
rememberShadowFetchOperationCount();

Expand Down Expand Up @@ -1397,7 +1500,7 @@ public void test900DeleteDummyShadows() throws Exception {
assertEquals("Wrong exec operation count", 17, opExecResult.getCount());
assertTrue("Too many subresults: "+deleteTaskResult.getSubresults().size(), deleteTaskResult.getSubresults().size() < 10);

assertUsers(17);
assertUsers(18);

ObjectQuery query = ObjectQueryUtil.createResourceAndObjectClassQuery(RESOURCE_DUMMY_OID,
new QName(RESOURCE_DUMMY_NAMESPACE, "AccountObjectClass"), prismContext);
Expand Down
Expand Up @@ -1011,5 +1011,16 @@ protected void assertSyncToken(Task task, Object expectedValue, OperationResult
}
}

protected void assertShadows(int expected) throws SchemaException {
OperationResult result = new OperationResult("assertShadows");
assertShadows(expected, result);
result.computeStatus();
TestUtil.assertSuccess(result);
}

protected void assertShadows(int expected, OperationResult result) throws SchemaException {
int actual = repositoryService.countObjects(ShadowType.class, null, result);
assertEquals("Unexpected number of (repository) shadows", expected, actual);
}

}

0 comments on commit ccee8c0

Please sign in to comment.