Skip to content

Commit

Permalink
Fix assignment deletion notifications (MID-4588)
Browse files Browse the repository at this point in the history
We now try to resolve values for id-only PCV deletions.
  • Loading branch information
mederly committed Apr 16, 2018
1 parent 178b2ac commit 15ca28d
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 8 deletions.
Expand Up @@ -23,6 +23,7 @@
import com.evolveum.midpoint.prism.crypto.EncryptionException;
import com.evolveum.midpoint.prism.delta.ObjectDelta;
import com.evolveum.midpoint.prism.delta.ReferenceDelta;
import com.evolveum.midpoint.prism.delta.builder.DeltaBuilder;
import com.evolveum.midpoint.prism.util.PrismTestUtil;
import com.evolveum.midpoint.schema.constants.SchemaConstants;
import com.evolveum.midpoint.schema.internals.InternalCounters;
Expand Down Expand Up @@ -365,7 +366,7 @@ public void test131ModifyUserJackAssignAccount() throws Exception {
}

@Test
public void test135ModifyUserJackAssignRole() throws Exception {
public void test140ModifyUserJackAssignRole() throws Exception {
final String TEST_NAME = "test135ModifyUserJackAssignRole";
TestUtil.displayTestTitle(this, TEST_NAME);

Expand Down Expand Up @@ -415,7 +416,127 @@ public void test135ModifyUserJackAssignRole() throws Exception {
+ "\n"
+ "Channel: ";
assertEquals("Wrong message body", expected, dummyTransport.getMessages("dummy:simpleUserNotifier").get(0).getBody());
}

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

// GIVEN
Task task = taskManager.createTaskInstance(TestNotifications.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
preTestCleanup(AssignmentPolicyEnforcementType.FULL);

// WHEN
TestUtil.displayWhen(TEST_NAME);
PrismObject<UserType> jack = getUser(USER_JACK_OID);
AssignmentType assignment = findAssignmentByTargetRequired(jack, ROLE_SUPERUSER_OID);
Long id = assignment.getId();
executeChanges(
DeltaBuilder.deltaFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT, id, AssignmentType.F_DESCRIPTION)
.replace("hi")
.asObjectDeltaCast(jack.getOid()), null, task, result);

// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess("executeChanges result", result);

PrismObject<UserType> jackAfter = getUser(USER_JACK_OID);
display("User after change execution", jackAfter);
assertUserJack(jackAfter);

// Check notifications
display("Notifications", dummyTransport);

notificationManager.setDisabled(true);
checkDummyTransportMessages("accountPasswordNotifier", 0);
checkDummyTransportMessages("userPasswordNotifier", 0);
checkDummyTransportMessages("simpleAccountNotifier-SUCCESS", 0);
checkDummyTransportMessages("simpleAccountNotifier-FAILURE", 0);
checkDummyTransportMessages("simpleAccountNotifier-ADD-SUCCESS", 0);
checkDummyTransportMessages("simpleAccountNotifier-DELETE-SUCCESS", 0);
checkDummyTransportMessages("simpleUserNotifier", 1);
checkDummyTransportMessages("simpleUserNotifier-ADD", 0);

assertSteadyResources();

String expected = "Notification about user-related operation (status: SUCCESS)\n"
+ "\n"
+ "User: Jack Sparrow (jack, oid c0c010c0-d34d-b33f-f00d-111111111111)\n"
+ "\n"
+ "The user record was modified. Modified attributes are:\n"
+ " - Assignment["+id+"]/Description:\n"
+ " - REPLACE: hi\n"
+ "\n"
+ "Notes:\n"
+ " - Assignment["+id+"]:\n"
+ " - Description: hi\n"
+ " - Target: Superuser (role) [default]\n"
+ "\n"
+ "Channel: ";
assertEquals("Wrong message body", expected, dummyTransport.getMessages("dummy:simpleUserNotifier").get(0).getBody());
}

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

// GIVEN
Task task = taskManager.createTaskInstance(TestNotifications.class.getName() + "." + TEST_NAME);
OperationResult result = task.getResult();
preTestCleanup(AssignmentPolicyEnforcementType.FULL);

// WHEN
TestUtil.displayWhen(TEST_NAME);
PrismObject<UserType> jack = getUser(USER_JACK_OID);
AssignmentType assignment = findAssignmentByTargetRequired(jack, ROLE_SUPERUSER_OID);
Long id = assignment.getId();
executeChanges(
DeltaBuilder.deltaFor(UserType.class, prismContext)
.item(UserType.F_ASSIGNMENT)
.delete(new AssignmentType(prismContext).id(id))
.asObjectDeltaCast(jack.getOid()), null, task, result);

// THEN
TestUtil.displayThen(TEST_NAME);
result.computeStatus();
TestUtil.assertSuccess("executeChanges result", result);

PrismObject<UserType> jackAfter = getUser(USER_JACK_OID);
display("User after change execution", jackAfter);
assertUserJack(jackAfter);

// Check notifications
display("Notifications", dummyTransport);

notificationManager.setDisabled(true);
checkDummyTransportMessages("accountPasswordNotifier", 0);
checkDummyTransportMessages("userPasswordNotifier", 0);
checkDummyTransportMessages("simpleAccountNotifier-SUCCESS", 0);
checkDummyTransportMessages("simpleAccountNotifier-FAILURE", 0);
checkDummyTransportMessages("simpleAccountNotifier-ADD-SUCCESS", 0);
checkDummyTransportMessages("simpleAccountNotifier-DELETE-SUCCESS", 0);
checkDummyTransportMessages("simpleUserNotifier", 1);
checkDummyTransportMessages("simpleUserNotifier-ADD", 0);

assertSteadyResources();

String expected = "Notification about user-related operation (status: SUCCESS)\n"
+ "\n"
+ "User: Jack Sparrow (jack, oid c0c010c0-d34d-b33f-f00d-111111111111)\n"
+ "\n"
+ "The user record was modified. Modified attributes are:\n"
+ " - Assignment:\n"
+ " - DELETE: \n"
+ " - Description: hi\n"
+ " - Target: Superuser (role) [default]\n"
+ "\n"
+ "Channel: ";
assertEquals("Wrong message body", expected, dummyTransport.getMessages("dummy:simpleUserNotifier").get(0).getBody());
}

@Test
Expand Down
Expand Up @@ -42,6 +42,7 @@
import com.evolveum.midpoint.util.logging.TraceManager;
import com.evolveum.midpoint.xml.ns._public.common.common_3.*;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.Validate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
Expand Down Expand Up @@ -100,7 +101,7 @@ public String formatObjectModificationDelta(ObjectDelta<? extends Objectable> ob
retval.append(" - ");
retval.append(getItemDeltaLabel(itemDelta, objectDefinition));
retval.append(":\n");
formatItemDeltaContent(retval, itemDelta, hiddenPaths, showOperationalAttributes);
formatItemDeltaContent(retval, itemDelta, objectOld, hiddenPaths, showOperationalAttributes);
}

explainPaths(retval, toBeDisplayed, objectDefinition, objectOld, objectNew, hiddenPaths, showOperationalAttributes);
Expand Down Expand Up @@ -158,25 +159,43 @@ private void explainPaths(StringBuilder sb, List<ItemDelta> deltas, PrismObjectD
}
}

private void formatItemDeltaContent(StringBuilder sb, ItemDelta itemDelta, List<ItemPath> hiddenPaths, boolean showOperationalAttributes) {
formatItemDeltaValues(sb, "ADD", itemDelta.getValuesToAdd(), false, hiddenPaths, showOperationalAttributes);
formatItemDeltaValues(sb, "DELETE", itemDelta.getValuesToDelete(), true, hiddenPaths, showOperationalAttributes);
formatItemDeltaValues(sb, "REPLACE", itemDelta.getValuesToReplace(), false, hiddenPaths, showOperationalAttributes);
private void formatItemDeltaContent(StringBuilder sb, ItemDelta itemDelta, PrismObject objectOld,
List<ItemPath> hiddenPaths, boolean showOperationalAttributes) {
formatItemDeltaValues(sb, "ADD", itemDelta.getValuesToAdd(), false, itemDelta.getPath(), objectOld, hiddenPaths, showOperationalAttributes);
formatItemDeltaValues(sb, "DELETE", itemDelta.getValuesToDelete(), true, itemDelta.getPath(), objectOld, hiddenPaths, showOperationalAttributes);
formatItemDeltaValues(sb, "REPLACE", itemDelta.getValuesToReplace(), false, itemDelta.getPath(), objectOld, hiddenPaths, showOperationalAttributes);
}

private void formatItemDeltaValues(StringBuilder sb, String type, Collection<? extends PrismValue> values, boolean mightBeRemoved, List<ItemPath> hiddenPaths, boolean showOperationalAttributes) {
private void formatItemDeltaValues(StringBuilder sb, String type, Collection<? extends PrismValue> values,
boolean isDelete, ItemPath path, PrismObject objectOld,
List<ItemPath> hiddenPaths, boolean showOperationalAttributes) {
if (values != null) {
for (PrismValue prismValue : values) {
sb.append(" - ").append(type).append(": ");
String prefix = " ";
formatPrismValue(sb, prefix, prismValue, mightBeRemoved, hiddenPaths, showOperationalAttributes);
if (isDelete && prismValue instanceof PrismContainerValue) {
prismValue = fixEmptyContainerValue((PrismContainerValue) prismValue, path, objectOld);
}
formatPrismValue(sb, prefix, prismValue, isDelete, hiddenPaths, showOperationalAttributes);
if (!(prismValue instanceof PrismContainerValue)) { // container values already end with newline
sb.append("\n");
}
}
}
}

private PrismValue fixEmptyContainerValue(PrismContainerValue pcv, ItemPath path, PrismObject objectOld) {
if (pcv.getId() == null || CollectionUtils.isNotEmpty(pcv.getItems())) {
return pcv;
}
PrismContainer oldContainer = objectOld.findContainer(path);
if (oldContainer == null) {
return pcv;
}
PrismContainerValue oldValue = oldContainer.getValue(pcv.getId());
return oldValue != null ? oldValue : pcv;
}

// todo - should each hiddenAttribute be prefixed with something like F_ATTRIBUTE? Currently it should not be.
public String formatAccountAttributes(ShadowType shadowType, List<ItemPath> hiddenAttributes, boolean showOperationalAttributes) {
Validate.notNull(shadowType, "shadowType is null");
Expand Down

0 comments on commit 15ca28d

Please sign in to comment.