diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java index bcb738e235c..12f244450c1 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/AssignmentEvaluator.java @@ -238,7 +238,16 @@ private void evaluateAssignment(EvaluatedAssignmentImpl evalAssignment, Assig if (assignmentType.getTarget() != null) { target = assignmentType.getTarget().asPrismObject(); } else if (assignmentType.getTargetRef() != null) { - target = resolveTarget(assignmentType, source, sourceDescription, task, result); + try { + target = resolveTarget(assignmentType, source, sourceDescription, task, result); + } catch (ObjectNotFoundException ex) { + // Do not throw an exception. We don't have referential integrity. Therefore if a role is deleted then throwing + // an exception would prohibit any operations with the users that have the role, including removal of the reference. + // The failure is recorded in the result and we will log it. It should be enough. + LOGGER.error(ex.getMessage()+" in assignment target reference in "+sourceDescription,ex); + // For OrgType references we trigger the reconciliation (see MID-2242) + evalAssignment.setForceRecon(true); + } } if (target != null && evalAssignment.getTarget() == null) { evalAssignment.setTarget(target); @@ -390,19 +399,12 @@ private PrismObject resolveTarget(AssignmentType assignmentType, ObjectType s throw new SchemaException("Missing type in target reference in " + assignmentType + " in " + sourceDescription); } PrismObject target = null; - try { - target = repository.getObject(clazz, oid, null, result); - if (target == null) { - throw new IllegalArgumentException("Got null target from repository, oid:"+oid+", class:"+clazz+" (should not happen, probably a bug) in "+sourceDescription); - } - } catch (ObjectNotFoundException ex) { - // Do not throw an exception. We don't have referential integrity. Therefore if a role is deleted then throwing - // an exception would prohibit any operations with the users that have the role, including removal of the reference. - // The failure is recorded in the result and we will log it. It should be enough. - LOGGER.error(ex.getMessage()+" in assignment target reference in "+sourceDescription,ex); -// throw new ObjectNotFoundException(ex.getMessage()+" in assignment target reference in "+sourceDescription,ex); - } - + target = repository.getObject(clazz, oid, null, result); + if (target == null) { + throw new IllegalArgumentException("Got null target from repository, oid:"+oid+", class:"+clazz+" (should not happen, probably a bug) in "+sourceDescription); + } + // Handling ObjectNotFoundException - we just pass it to the caller + return target; } diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java index 95ca388370b..89fbaef2178 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/EvaluatedAssignmentImpl.java @@ -61,7 +61,7 @@ public class EvaluatedAssignmentImpl implements EvaluatedAs private Collection>> focusMappings; private PrismObject target; private boolean isValid; - private boolean forceRecon; + private boolean forceRecon; // used also to force recomputation of parentOrgRefs public EvaluatedAssignmentImpl() { constructions = new DeltaSetTriple<>(); diff --git a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java index a92c57d58e4..26fd5f8b854 100644 --- a/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java +++ b/model/model-impl/src/main/java/com/evolveum/midpoint/model/impl/lens/projector/AssignmentProcessor.java @@ -782,19 +782,25 @@ private ObjectType determineSource(LensFocusContext fo private void collectToZero(DeltaSetTriple> evaluatedAssignmentTriple, EvaluatedAssignmentImpl evaluatedAssignment, boolean forceRecon) { - evaluatedAssignment.setForceRecon(forceRecon); + if (forceRecon) { + evaluatedAssignment.setForceRecon(true); + } evaluatedAssignmentTriple.addToZeroSet(evaluatedAssignment); } private void collectToPlus(DeltaSetTriple> evaluatedAssignmentTriple, EvaluatedAssignmentImpl evaluatedAssignment, boolean forceRecon) { - evaluatedAssignment.setForceRecon(forceRecon); + if (forceRecon) { + evaluatedAssignment.setForceRecon(true); + } evaluatedAssignmentTriple.addToPlusSet(evaluatedAssignment); } private void collectToMinus(DeltaSetTriple> evaluatedAssignmentTriple, EvaluatedAssignmentImpl evaluatedAssignment, boolean forceRecon) { - evaluatedAssignment.setForceRecon(forceRecon); + if (forceRecon) { + evaluatedAssignment.setForceRecon(true); + } evaluatedAssignmentTriple.addToMinusSet(evaluatedAssignment); } @@ -1194,6 +1200,16 @@ public void processOrgAssignments(LensContext context, break; } } + // for zero and minus sets we check isForceRecon for all non-construction-related assignments (MID-2242) + if (!forceRecon) { + for (EvaluatedAssignmentImpl assignment: evaluatedAssignmentTriple.getNonPositiveValues()) { + if (assignment.isForceRecon() && + (assignment.getConstructions() == null || assignment.getConstructions().isEmpty())) { + forceRecon = true; + break; + } + } + } if (!forceRecon) { // if no recon, we simply add/delete values as needed diff --git a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestOrgStruct.java b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestOrgStruct.java index 214da119bab..9b90be722d8 100644 --- a/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestOrgStruct.java +++ b/model/model-intest/src/test/java/com/evolveum/midpoint/model/intest/TestOrgStruct.java @@ -78,6 +78,9 @@ public class TestOrgStruct extends AbstractInitializedModelIntegrationTest { public static final File ROLE_DEFENDER_FILE = new File(TEST_DIR, "role-defender.xml"); public static final String ROLE_DEFENDER_OID = "12345111-1111-2222-1111-121212111567"; + public static final File ORG_TEMP_FILE = new File(TEST_DIR, "org-temp.xml"); + public static final String ORG_TEMP_OID = "43214321-4311-0952-4762-854392584320"; + @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); @@ -1228,6 +1231,54 @@ public void test412JackChangeMinistryOfOffenseMemberToManagerByModifyingAssignme } } + // import temp org + assign to jack (preparation for the next test) + @Test + public void test420JackAssignTempOrg() throws Exception { + final String TEST_NAME = "test420JackAssignTempOrg"; + TestUtil.displayTestTile(this, TEST_NAME); + + Task task = taskManager.createTaskInstance(TestOrgStruct.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + addObject(ORG_TEMP_FILE); + + // WHEN + assignOrg(USER_JACK_OID, ORG_TEMP_OID, task, result); + + // THEN + PrismObject userJack = getUser(USER_JACK_OID); + display("User jack after", userJack); + assertUserAssignedOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID, ORG_TEMP_OID); + assertUserHasOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID, ORG_TEMP_OID); + + // Postcondition + assertMonkeyIslandOrgSanity(); + } + + // delete the org and then unassign it + @Test + public void test425JackUnassignDeletedOrg() throws Exception { + final String TEST_NAME = "test425JackUnassignDeletedOrg"; + TestUtil.displayTestTile(this, TEST_NAME); + + Task task = taskManager.createTaskInstance(TestOrgStruct.class.getName() + "." + TEST_NAME); + OperationResult result = task.getResult(); + + deleteObject(OrgType.class, ORG_TEMP_OID, task, result); + + // WHEN + unassignOrg(USER_JACK_OID, ORG_TEMP_OID, task, result); + + // THEN + PrismObject userJack = getUser(USER_JACK_OID); + display("User jack after", userJack); + assertUserAssignedOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID); + assertUserHasOrgs(userJack, ORG_MINISTRY_OF_OFFENSE_OID); + + // Postcondition + assertMonkeyIslandOrgSanity(); + } + /** * Now let's test working with assignments when there is an object template that prescribes an org assignment * based on organizationalUnit property. diff --git a/model/model-intest/src/test/resources/orgstruct/org-temp.xml b/model/model-intest/src/test/resources/orgstruct/org-temp.xml new file mode 100644 index 00000000000..e5d63be01f9 --- /dev/null +++ b/model/model-intest/src/test/resources/orgstruct/org-temp.xml @@ -0,0 +1,26 @@ + + + + + TEMP + Suddenly appearing and disappearing org + Temp Org + oooo + functional + CCoooo + +