/* * Copyright (c) 2010-2017 Evolveum * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.evolveum.midpoint.model.impl.lens; import com.evolveum.midpoint.common.Clock; import com.evolveum.midpoint.model.api.context.EvaluatedPolicyRule; import com.evolveum.midpoint.model.common.mapping.Mapping; import com.evolveum.midpoint.model.common.mapping.PrismValueDeltaSetTripleProducer; import com.evolveum.midpoint.model.impl.lens.projector.AssignmentProcessor; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismPropertyDefinition; import com.evolveum.midpoint.prism.PrismPropertyValue; import com.evolveum.midpoint.prism.delta.*; import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.prism.polystring.PolyString; import com.evolveum.midpoint.prism.util.PrismAsserts; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.DummyResourceContoller; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.xml.ns._public.common.common_3.*; import org.springframework.beans.factory.annotation.Autowired; import org.testng.annotations.Test; import javax.xml.bind.JAXBException; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import java.util.*; import static com.evolveum.midpoint.prism.delta.PlusMinusZero.MINUS; import static com.evolveum.midpoint.prism.delta.PlusMinusZero.PLUS; import static com.evolveum.midpoint.prism.delta.PlusMinusZero.ZERO; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import static org.testng.AssertJUnit.*; /** * @author semancik */ public class TestAssignmentProcessor extends AbstractLensTest { private static final ItemPath ATTRIBUTES_PARENT_PATH = new ItemPath(ShadowType.F_ATTRIBUTES); @Autowired private AssignmentProcessor assignmentProcessor; @Autowired private Clock clock; public TestAssignmentProcessor() throws JAXBException { super(); } @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); addObjects(ROLE_CORP_FILES); } /** * Test empty change. Run the outbound processor with empty user (no assignments) and no change. Check that the * resulting changes are also empty. */ @Test public void test001OutboundEmpty() throws Exception { final String TEST_NAME = "test001OutboundEmpty"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_JACK_OID, result); context.recompute(); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertNull(context.getFocusContext().getPrimaryDelta()); assertNull(context.getFocusContext().getSecondaryDelta()); assertTrue(context.getProjectionContexts().isEmpty()); } @Test public void test002ModifyUser() throws Exception { final String TEST_NAME = "test002ModifyUser"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_BARBOSSA_OID, result); fillContextWithAccount(context, ACCOUNT_HBARBOSSA_DUMMY_OID, result); addModificationToContextReplaceUserProperty(context, UserType.F_LOCALITY, new PolyString("Tortuga")); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); display("accountConstructionDeltaSetTriple", accountConstructionDeltaSetTriple); PrismAsserts.assertTripleNoMinus(accountConstructionDeltaSetTriple); PrismAsserts.assertTripleNoPlus(accountConstructionDeltaSetTriple); assertSetSize("zero", accountConstructionDeltaSetTriple.getZeroSet(), 2); Construction zeroAccountConstruction = getZeroAccountConstruction(accountConstructionDeltaSetTriple, "Brethren account construction"); assertNoZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME), "Tortuga"); assertMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME), "Caribbean"); } @Test public void test011AddAssignmentAddAccountDirect() throws Exception { final String TEST_NAME = "test011AddAssignmentAddAccountDirect"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_JACK_OID, result); addFocusModificationToContext(context, REQ_USER_JACK_MODIFY_ADD_ASSIGNMENT_ACCOUNT_DUMMY); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); } @Test public void test012AddAssignmentAddAccountDirectAssignmentWithAttrs() throws Exception { final String TEST_NAME = "test012AddAssignmentAddAccountDirectAssignmentWithAttrs"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_JACK_OID, result); addFocusModificationToContext(context, REQ_USER_JACK_MODIFY_ADD_ASSIGNMENT_ACCOUNT_DUMMY_ATTR); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN TestUtil.displayWhen(TEST_NAME); assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN TestUtil.displayThen(TEST_NAME); display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); PrismAsserts.assertTripleNoMinus(accountConstructionDeltaSetTriple); PrismAsserts.assertTripleNoZero(accountConstructionDeltaSetTriple); assertSetSize("plus", accountConstructionDeltaSetTriple.getPlusSet(), 1); Construction plusAccountConstruction = getPlusAccountConstruction(accountConstructionDeltaSetTriple); assertZeroAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME), "Pirate Brethren, Inc."); assertNoPlusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertNoMinusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertZeroAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME), "Caribbean"); assertNoPlusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertNoMinusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); } @Test public void test021AddAssignmentModifyAccountAssignment() throws Exception { final String TEST_NAME = "test021AddAssignmentModifyAccountAssignment"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_BARBOSSA_OID, result); fillContextWithAccount(context, ACCOUNT_HBARBOSSA_DUMMY_OID, result); addFocusModificationToContext(context, REQ_USER_BARBOSSA_MODIFY_ADD_ASSIGNMENT_ACCOUNT_DUMMY_ATTR); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); PrismAsserts.assertTripleNoMinus(accountConstructionDeltaSetTriple); assertSetSize("zero", accountConstructionDeltaSetTriple.getZeroSet(), 2); Construction zeroAccountConstruction = getZeroAccountConstruction(accountConstructionDeltaSetTriple, "Brethren account construction"); assertZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME), "Pirate Brethren, Inc."); assertNoPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertNoMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME), "Caribbean"); assertNoPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertNoMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME), "Sword"); assertNoPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); assertNoMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); assertSetSize("plus", accountConstructionDeltaSetTriple.getPlusSet(), 1); Construction plusAccountConstruction = getPlusAccountConstruction(accountConstructionDeltaSetTriple, "Monkey account construction"); assertZeroAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME), "Rum"); assertNoPlusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME)); assertNoMinusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_DRINK_NAME)); assertZeroAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME), "Dagger", "Pistol"); assertNoPlusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); assertNoMinusAttributeValues(plusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); } @Test public void test031DeleteAssignmentModifyAccount() throws Exception { final String TEST_NAME = "test031DeleteAssignmentModifyAccount"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_BARBOSSA_OID, result); fillContextWithAccount(context, ACCOUNT_HBARBOSSA_DUMMY_OID, result); addFocusModificationToContext(context, REQ_USER_BARBOSSA_MODIFY_DELETE_ASSIGNMENT_ACCOUNT_DUMMY_ATTR); context.recomputeFocus(); display("Input context", context); PrismObject<UserType> userNew = context.getFocusContext().getObjectNew(); assertEquals("Unexpected number of assignemnts in userNew after recompute", 1, userNew.asObjectable().getAssignment().size()); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context.dump(true)); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); PrismAsserts.assertTripleNoPlus(accountConstructionDeltaSetTriple); assertSetSize("zero", accountConstructionDeltaSetTriple.getZeroSet(), 1); Construction zeroAccountConstruction = getZeroAccountConstruction(accountConstructionDeltaSetTriple); assertZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME), "Caribbean"); assertNoPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertNoMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME)); assertZeroAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME), "Pirate Brethren, Inc."); assertNoPlusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertNoMinusAttributeValues(zeroAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_SHIP_NAME)); assertSetSize("minus", accountConstructionDeltaSetTriple.getMinusSet(), 1); Construction minusAccountConstruction = getMinusAccountConstruction(accountConstructionDeltaSetTriple); assertZeroAttributeValues(minusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME), "Undead Monkey"); assertNoPlusAttributeValues(minusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); assertNoMinusAttributeValues(minusAccountConstruction, getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_WEAPON_NAME)); } @Test public void test032ModifyUserLegalizeAccount() throws Exception { final String TEST_NAME = "test032ModifyUserLegalizeAccount"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); repoAddObjectFromFile(USER_LARGO_FILE, result); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_LARGO_OID, result); fillContextWithAccountFromFile(context, ACCOUNT_SHADOW_ELAINE_DUMMY_FILE, result); context.recompute(); ProjectionPolicyType accountSynchronizationSettings = new ProjectionPolicyType(); accountSynchronizationSettings.setLegalize(Boolean.TRUE); accountSynchronizationSettings.setAssignmentPolicyEnforcement(AssignmentPolicyEnforcementType.POSITIVE); context.setAccountSynchronizationSettings(accountSynchronizationSettings); assumeResourceAssigmentPolicy(RESOURCE_DUMMY_OID, AssignmentPolicyEnforcementType.POSITIVE, true); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); context.recompute(); // THEN display("Output context", context); display("outbound processor result", result); assertNotNull("Expected assigment change in secondary user changes, but it does not exist.", context.getFocusContext().getSecondaryDelta()); assertEquals("Unexpected number of secundary changes. ", 1, context.getFocusContext().getSecondaryDelta().getModifications().size()); assertNotNull("Expected assigment delta in secondary changes, but it does not exist.", ContainerDelta.findContainerDelta(context.getFocusContext().getSecondaryDelta().getModifications(), UserType.F_ASSIGNMENT)); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); LensProjectionContext accContext = context.getProjectionContexts().iterator().next(); assertNoDecision(accContext); assertLegal(accContext); } @Test public void test100AddAssignmentWithConditionalMetarole() throws Exception { final String TEST_NAME = "test100AddAssignmentWithConditionalMetarole"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); fillContextWithUser(context, USER_JACK_OID, result); addFocusModificationToContext(context, REQ_USER_JACK_MODIFY_ADD_ASSIGNMENT_ROLE_ENGINEER); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); PrismAsserts.assertTripleNoMinus(accountConstructionDeltaSetTriple); PrismAsserts.assertTripleNoZero(accountConstructionDeltaSetTriple); final QName TITLE_QNAME = getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME); final QName LOCATION_QNAME = getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME); assertSetSize("plus", accountConstructionDeltaSetTriple.getPlusSet(), 4); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, ZERO, "Engineer", "Employee"); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, MINUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, ZERO, "Caribbean"); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, MINUS); } /** * There is a conditional metarole that references 'costCenter' attribute. * Let us change the value of this attribute. */ @Test public void test102EnableConditionalMetarole() throws Exception { final String TEST_NAME = "test102EnableConditionalMetarole"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); PrismObject<UserType> user = getUser(USER_JACK_OID); AssignmentType assignmentType = getAssignmentType(ASSIGNMENT_ROLE_MANAGER_FILE); assignmentType.asPrismContainerValue().setParent(null); user.asObjectable().getAssignment().add(assignmentType); fillContextWithFocus(context, user); addFocusModificationToContext(context, REQ_USER_JACK_MODIFY_SET_COST_CENTER); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN display("Output context", context); display("outbound processor result", result); // assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); Collection<LensProjectionContext> accountContexts = context.getProjectionContexts(); assertEquals(1, accountContexts.size()); LensProjectionContext accContext = accountContexts.iterator().next(); assertNull(accContext.getPrimaryDelta()); ObjectDelta<ShadowType> accountSecondaryDelta = accContext.getSecondaryDelta(); assertNull("Account secondary delta sneaked in", accountSecondaryDelta); assertNoDecision(accContext); assertLegal(accContext); assignmentProcessor.processAssignmentsAccountValues(accContext, result); PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple = accContext.getConstructionDeltaSetTriple(); PrismAsserts.assertTripleNoMinus(accountConstructionDeltaSetTriple); final QName TITLE_QNAME = getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_TITLE_NAME); final QName LOCATION_QNAME = getDummyResourceController().getAttributeQName(DummyResourceContoller.DUMMY_ACCOUNT_ATTRIBUTE_LOCATION_NAME); assertSetSize("zero", accountConstructionDeltaSetTriple.getZeroSet(), 3); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), TITLE_QNAME, ZERO, "Employee"); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), TITLE_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), TITLE_QNAME, MINUS); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), LOCATION_QNAME, ZERO, "Caribbean"); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), LOCATION_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getZeroSet(), LOCATION_QNAME, MINUS); assertSetSize("plus", accountConstructionDeltaSetTriple.getPlusSet(), 1); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, ZERO, "Manager"); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), TITLE_QNAME, MINUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, ZERO); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, PLUS); assertAttributeValues(accountConstructionDeltaSetTriple.getPlusSet(), LOCATION_QNAME, MINUS); } /** * NOTE - these two tests are legacy. They should be placed in TestPolicyRules. Please do not add * any similar tests here; use TestPolicyRules instead. It contains better 'assume' methods for policies. * TODO move these ones as well * =============================================================================================== * * Checking approval policy rules. * Visitor has a generic metarole that has associated policy rule (approve-any-corp-role). * Generic metarole also induces metarole-sod-notifications that has "notify-exclusion-violations" rule. */ @Test public void test200AssignVisitor() throws Exception { final String TEST_NAME = "test200AssignVisitor"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); PrismObject<UserType> user = getUser(USER_JACK_OID); AssignmentType assignmentType = new AssignmentType(prismContext); assignmentType.setTargetRef(ObjectTypeUtil.createObjectRef(ROLE_CORP_VISITOR_OID, ObjectTypes.ROLE)); fillContextWithFocus(context, user); addFocusDeltaToContext(context, (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(assignmentType) .asObjectDelta(USER_JACK_OID)); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN //DebugUtil.setDetailedDebugDump(true); display("Output context", context); display("outbound processor result", result); //assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple(); assertEquals("Wrong # of added assignments", 1, evaluatedAssignmentTriple.getPlusSet().size()); display("Policy rules", context.dumpPolicyRules(3)); EvaluatedAssignmentImpl evaluatedAssignment = evaluatedAssignmentTriple.getPlusSet().iterator().next(); assertEquals("Wrong # of focus policy rules", 0, evaluatedAssignment.getFocusPolicyRules().size()); Collection<EvaluatedPolicyRule> targetPolicyRules = evaluatedAssignment.getAllTargetsPolicyRules(); assertEquals("Wrong # of target policy rules", 2, targetPolicyRules.size()); } /** * Checking approval policy rules. (See note above.) * Engineer has a generic metarole that provides these policy rules: approve-any-corp-rule, notify-exclusion-violations. * However, it induces an Employee role that has also this generic metarole. Moreover, it has "employee-excludes-contractor" * rule. * * First occurrence of the approval rule should have a trigger. Second one should be without a trigger. */ @Test public void test210AssignEngineer() throws Exception { final String TEST_NAME = "test210AssignEngineer"; TestUtil.displayTestTile(this, TEST_NAME); // GIVEN Task task = taskManager.createTaskInstance(TestAssignmentProcessor.class.getName() + "." + TEST_NAME); OperationResult result = task.getResult(); LensContext<UserType> context = createUserLensContext(); PrismObject<UserType> user = getUser(USER_JACK_OID); AssignmentType assignmentType = new AssignmentType(prismContext); assignmentType.setTargetRef(ObjectTypeUtil.createObjectRef(ROLE_CORP_ENGINEER_OID, ObjectTypes.ROLE)); fillContextWithFocus(context, user); addFocusDeltaToContext(context, (ObjectDelta) DeltaBuilder.deltaFor(UserType.class, prismContext) .item(UserType.F_ASSIGNMENT).add(assignmentType) .asObjectDelta(USER_JACK_OID)); context.recompute(); display("Input context", context); assertFocusModificationSanity(context); // WHEN assignmentProcessor.processAssignmentsProjections(context, getNow(), task, result); // THEN //DebugUtil.setDetailedDebugDump(true); display("Output context", context); display("outbound processor result", result); //assertSuccess("Outbound processor failed (result)", result); assertTrue(context.getFocusContext().getPrimaryDelta().getChangeType() == ChangeType.MODIFY); assertNull("Unexpected user changes", context.getFocusContext().getSecondaryDelta()); assertFalse("No account changes", context.getProjectionContexts().isEmpty()); DeltaSetTriple<EvaluatedAssignmentImpl<?>> evaluatedAssignmentTriple = context.getEvaluatedAssignmentTriple(); assertEquals("Wrong # of added assignments", 1, evaluatedAssignmentTriple.getPlusSet().size()); display("Policy rules", context.dumpPolicyRules(3)); EvaluatedAssignmentImpl evaluatedAssignment = evaluatedAssignmentTriple.getPlusSet().iterator().next(); assertEquals("Wrong # of focus policy rules", 0, evaluatedAssignment.getFocusPolicyRules().size()); assertEquals("Wrong # of this target policy rules", 2, evaluatedAssignment.getThisTargetPolicyRules().size()); Collection<EvaluatedPolicyRule> policyRules = evaluatedAssignment.getAllTargetsPolicyRules(); assertEquals("Wrong # of target policy rules", 5, policyRules.size()); } private <T> void assertAttributeValues(Collection<PrismPropertyValue<Construction>> accountConstructions, QName attrName, PlusMinusZero attrSet, T... expectedValue) { Set<T> realValues = getAttributeValues(accountConstructions, attrName, attrSet); assertEquals("Unexpected attributes", new HashSet(Arrays.asList(expectedValue)), realValues); } private <T> Set<T> getAttributeValues(Collection<PrismPropertyValue<Construction>> accountConstructions, QName attrName, PlusMinusZero attributeSet) { Set<T> retval = new HashSet<>(); for (PrismPropertyValue<Construction> constructionPropVal : accountConstructions) { Mapping<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> mapping = constructionPropVal.getValue().getAttributeMapping(attrName); if (mapping != null && mapping.getOutputTriple() != null) { Collection<PrismPropertyValue<T>> values = (Collection) mapping.getOutputTriple().getSet(attributeSet); if (values != null) { for (PrismPropertyValue<T> value : values) { retval.add(value.getValue()); } } } } return retval; } private <T> void assertPlusAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in plus set", vc); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); Collection<T> actual = getMultiValueFromDeltaSetTriple(triple, triple.getPlusSet()); TestUtil.assertSetEquals("Attribute "+attrName+" value in plus set", actual, expectedValue); } private <T> void assertZeroAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in zero set", vc); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); Collection<T> actual = getMultiValueFromDeltaSetTriple(triple, triple.getZeroSet()); TestUtil.assertSetEquals("Attribute "+attrName+" value in zero set", actual, expectedValue); } private <T> void assertMinusAttributeValues(Construction accountConstruction, QName attrName, T... expectedValue) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); assertNotNull("No value construction for attribute "+attrName+" in minus set", vc); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); Collection<T> actual = getMultiValueFromDeltaSetTriple(triple, triple.getMinusSet()); TestUtil.assertSetEquals("Attribute "+attrName+" value in minus set", actual, expectedValue); } private void assertNoPlusAttributeValues(Construction accountConstruction, QName attrName) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoPlus(triple); } private void assertNoZeroAttributeValues(Construction accountConstruction, QName attrName) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoZero(triple); } private void assertNoMinusAttributeValues(Construction accountConstruction, QName attrName) { PrismValueDeltaSetTripleProducer<? extends PrismPropertyValue<?>, ? extends PrismPropertyDefinition<?>> vc = accountConstruction.getAttributeMapping(attrName); PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple = vc.getOutputTriple(); PrismAsserts.assertTripleNoMinus(triple); } private Object getSingleValueFromDeltaSetTriple(PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple, Collection<? extends PrismPropertyValue<?>> set) { Collection<?> values = getMultiValueFromDeltaSetTriple(triple,set); assertEquals(1,values.size()); return values.iterator().next(); } private <T> Collection<T> getMultiValueFromDeltaSetTriple(PrismValueDeltaSetTriple<? extends PrismPropertyValue<?>> triple, Collection<? extends PrismPropertyValue<?>> set) { Collection<T> vals = new ArrayList<T>(set.size()); for (PrismPropertyValue<?> pval: set) { vals.add((T)pval.getValue()); } return vals; } private void assertSetSize(String setName, Collection<PrismPropertyValue<Construction>> set, int expectedSize) { assertEquals("Unexpected number of value in "+setName+" set", expectedSize, set.size()); } private Construction getZeroAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple) { return getZeroAccountConstruction(accountConstructionDeltaSetTriple, null); } private Construction getZeroAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple, String description) { Collection<PrismPropertyValue<Construction>> set = accountConstructionDeltaSetTriple.getZeroSet(); return getAccountConstruction(accountConstructionDeltaSetTriple, description, set, "zero"); } private Construction getPlusAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple) { return getPlusAccountConstruction(accountConstructionDeltaSetTriple, null); } private Construction getPlusAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple, String description) { Collection<PrismPropertyValue<Construction>> set = accountConstructionDeltaSetTriple.getPlusSet(); return getAccountConstruction(accountConstructionDeltaSetTriple, description, set, "plus"); } private Construction getMinusAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple) { return getMinusAccountConstruction(accountConstructionDeltaSetTriple, null); } private Construction getMinusAccountConstruction( PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple, String description) { Collection<PrismPropertyValue<Construction>> set = accountConstructionDeltaSetTriple.getMinusSet(); return getAccountConstruction(accountConstructionDeltaSetTriple, description, set, "minus"); } private Construction getAccountConstruction(PrismValueDeltaSetTriple<PrismPropertyValue<Construction>> accountConstructionDeltaSetTriple, String description, Collection<PrismPropertyValue<Construction>> set, String setName) { for (PrismPropertyValue<Construction> constructionPVal: set) { Construction accountConstruction = constructionPVal.getValue(); if (description == null || description.equals(accountConstruction.getDescription())) { assertNotNull("Null accountConstruction in "+setName+" set (description: '"+description+"')", accountConstruction); return accountConstruction; } } return null; } private void assertLegal(LensProjectionContext accContext) { assertEquals("Expected projection "+accContext+" not legal", Boolean.TRUE, accContext.isLegal()); } private void assertIllegal(LensProjectionContext accContext) { assertEquals("Expected projection "+accContext+" not illegal", Boolean.FALSE, accContext.isLegal()); } private void assertNoDecision(LensProjectionContext accContext) { assertNull("Projection "+accContext+" has decision "+accContext.getSynchronizationPolicyDecision()+" while not expecting any", accContext.getSynchronizationPolicyDecision()); } private XMLGregorianCalendar getNow() { return clock.currentTimeXMLGregorianCalendar(); } }