Skip to content

Commit

Permalink
Fix bulk modification of multiple objects
Browse files Browse the repository at this point in the history
The manipulation of delta bean was flawed.
(Thanks to Sven for the analysis.)

This resolves MID-7965.
  • Loading branch information
mederly committed Jul 26, 2022
1 parent 21bb7c3 commit 1b3817d
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public String dumpSingleLine() {
@Override
public String debugDump(int indent) {
StringBuilder sb = new StringBuilder();
DebugUtil.debugDumpMapMultiLine(sb, getAliasReducedMap(), 1);
DebugUtil.debugDumpMapMultiLine(sb, getAliasReducedMap(), indent);
return sb.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import javax.annotation.PostConstruct;

import com.evolveum.midpoint.prism.PrismObjectDefinition;
import com.evolveum.midpoint.util.exception.*;

import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -92,19 +93,21 @@ private void modify(PrismObject<? extends ObjectType> object, boolean dryRun, Mo

private ObjectDelta<? extends ObjectType> createDelta(ObjectType object, ObjectDeltaType deltaBean)
throws ScriptExecutionException, SchemaException {
if (deltaBean.getChangeType() == null) {
deltaBean.setChangeType(ChangeTypeType.MODIFY);
ObjectDeltaType deltaBeanClone = deltaBean.clone();
if (deltaBeanClone.getChangeType() == null) {
deltaBeanClone.setChangeType(ChangeTypeType.MODIFY);
}
if (deltaBean.getOid() == null && deltaBean.getChangeType() != ChangeTypeType.ADD) {
deltaBean.setOid(object.getOid());
if (deltaBeanClone.getOid() == null && deltaBeanClone.getChangeType() != ChangeTypeType.ADD) {
deltaBeanClone.setOid(object.getOid());
}
if (deltaBean.getObjectType() == null) {
if (object.asPrismObject().getDefinition() == null) {
if (deltaBeanClone.getObjectType() == null) {
PrismObjectDefinition<? extends ObjectType> definition = object.asPrismObject().getDefinition();
if (definition == null) {
throw new ScriptExecutionException("No definition for prism object " + object);
}
deltaBean.setObjectType(object.asPrismObject().getDefinition().getTypeName());
deltaBeanClone.setObjectType(definition.getTypeName());
}
return DeltaConvertor.createObjectDelta(deltaBean, prismContext);
return DeltaConvertor.createObjectDelta(deltaBeanClone, prismContext);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public abstract class AbstractBasicScriptingTest extends AbstractInitializedMode
private static final String DELETE_AND_ADD_JACK = "delete-and-add-jack";
private static final String MODIFY_JACK = "modify-jack";
private static final String MODIFY_JACK_BACK = "modify-jack-back";
private static final String MODIFY_BROTHERS = "modify-brothers";
private static final String RECOMPUTE_JACK = "recompute-jack";

// Tests 360-399
Expand Down Expand Up @@ -550,6 +551,46 @@ public void test340ModifyJackBack() throws Exception {
.assertLocality("Caribbean");
}

/**
* Tests modification of multiple users at once. MID-7965
*/
@Test
public void test345ModifyBrothers() throws Exception {
Task task = getTestTask();
OperationResult result = task.getResult();

given("there are two brothers");
String oid1 = addObject(
new UserType()
.name("brother-1")
.asPrismObject());
String oid2 = addObject(
new UserType()
.name("brother-2")
.asPrismObject());

when("they are modified");
ExecutionContext output =
evaluator.evaluateExpression(
parseScriptingExpression(MODIFY_BROTHERS),
task,
result);

then("they are really modified");
dumpOutput(output, result);
assertOutputData(output, 2, OperationResultStatus.SUCCESS);
assertSuccess(result);

assertUserAfterByUsername("brother-1")
.assertLocality("here");
assertUserAfterByUsername("brother-2")
.assertLocality("here");

and("brothers are deleted"); // to not disturb tests that check # of users
deleteObject(UserType.class, oid1);
deleteObject(UserType.class, oid2);
}

@Test
public void test350RecomputeJack() throws Exception {
given();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Copyright (c) 2020 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<s:pipeline xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
xmlns:c="http://midpoint.evolveum.com/xml/ns/public/common/common-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:search>
<s:type>UserType</s:type>
<s:searchFilter>
<substring xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<path>name</path>
<value>brother-</value>
<anchorStart>true</anchorStart>
</substring>
</s:searchFilter>
</s:search>
<s:action>
<s:type>modify</s:type>
<s:parameter>
<s:name>delta</s:name>
<c:value xsi:type="t:ObjectDeltaType">
<t:itemDelta> <!-- object type and oid will be filled-in from the input; change type is 'modify' by default -->
<t:modificationType>replace</t:modificationType>
<t:path>locality</t:path>
<t:value>here</t:value>
</t:itemDelta>
</c:value>
</s:parameter>
</s:action>
</s:pipeline>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
~ Copyright (c) 2010-2017 Evolveum and contributors
~
~ This work is dual-licensed under the Apache License 2.0
~ and European Union Public License. See LICENSE file for details.
-->

<s:search xmlns:s="http://midpoint.evolveum.com/xml/ns/public/model/scripting-3"
xmlns:t="http://prism.evolveum.com/xml/ns/public/types-3">
<s:type>UserType</s:type>
<s:searchFilter>
<substring xmlns="http://prism.evolveum.com/xml/ns/public/query-3">
<path>name</path>
<value>brother-</value>
<anchorStart>true</anchorStart>
</substring>
</s:searchFilter>
<s:modify>
<s:delta>
<t:itemDelta> <!-- object type and oid will be filled-in from the input; change type is 'modify' by default -->
<t:modificationType>replace</t:modificationType>
<t:path>locality</t:path>
<t:value>here</t:value>
</t:itemDelta>
</s:delta>
</s:modify>
</s:search>

0 comments on commit 1b3817d

Please sign in to comment.