Skip to content

Commit

Permalink
Added "forWholeInput" parameter of execute-script bulk action. Fixed …
Browse files Browse the repository at this point in the history
…TestPolicyRules2.
  • Loading branch information
mederly committed Sep 20, 2017
1 parent 429c515 commit f173e89
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 73 deletions.
Expand Up @@ -435,6 +435,7 @@ private void parsePrismSchema(SchemaDescription schemaDescription, boolean allow
detectExtensionSchema(schema);
}

// see https://stackoverflow.com/questions/14837293/xsd-circular-import
private void parsePrismSchemas(List<SchemaDescription> schemaDescriptions, boolean allowDelayedItemDefinitions) throws SchemaException {
List<SchemaDescription> prismSchemaDescriptions = schemaDescriptions.stream()
.filter(sd -> sd.isPrismSchema())
Expand Down
Expand Up @@ -73,7 +73,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input,
PARAM_STATUS, input, context, EventStatusType.class, globalResult);
EventOperationType operation = expressionHelper.getSingleArgumentValue(expression.getParameter(), PARAM_OPERATION, false, false,
PARAM_OPERATION, input, context, EventOperationType.class, globalResult);
boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_SUBTYPE, globalResult);
boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult);

if (handler != null) {
checkRootAuthorization(globalResult, NAME); // TODO explain that the reason is that handler is not null
Expand Down
Expand Up @@ -60,6 +60,7 @@ public class ScriptExecutor extends BaseActionExecutor {
private static final String NAME = "execute-script";
private static final String PARAM_SCRIPT = "script";
private static final String PARAM_OUTPUT_ITEM = "outputItem"; // item name or type (as URI!) -- EXPERIMENTAL
private static final String PARAM_FOR_WHOLE_INPUT = "forWholeInput";

@PostConstruct
public void init() {
Expand All @@ -75,6 +76,7 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input,
NAME, input, context, ScriptExpressionEvaluatorType.class, globalResult);
String outputItem = expressionHelper.getSingleArgumentValue(expression.getParameter(), PARAM_OUTPUT_ITEM, false, false,
NAME, input, context, String.class, globalResult);
boolean forWholeInput = expressionHelper.getArgumentAsBoolean(expression.getParameter(), PARAM_FOR_WHOLE_INPUT, input, context, false, PARAM_FOR_WHOLE_INPUT, globalResult);

ItemDefinition<?> outputDefinition = getItemDefinition(outputItem);

Expand All @@ -86,45 +88,69 @@ public PipelineData execute(ActionExpressionType expression, PipelineData input,
}

PipelineData output = PipelineData.createEmpty();
for (PipelineItem item: input.getData()) {
PrismValue value = item.getValue();
OperationResult result = operationsHelper.createActionResult(item, this, context, globalResult);

if (forWholeInput) {
OperationResult result = operationsHelper.createActionResult(null, this, context, globalResult);
context.checkTaskStop();
String valueDescription;
long started;
if (value instanceof PrismObjectValue) {
started = operationsHelper.recordStart(context, asObjectType(value));
valueDescription = asObjectType(value).asPrismObject().toString();
} else {
started = 0;
valueDescription = value.toHumanReadableString();
}
Throwable exception = null;
try {
Object outObject = executeScript(scriptExpression, value, context, result);
Object outObject = executeScript(scriptExpression, input, context, result);
if (outObject != null) {
addToData(outObject, item.getResult(), output);
addToData(outObject, PipelineData.newOperationResult(), output);
} else {
// no definition means we don't plan to provide any output - so let's just copy the input item to the output
// (actually, null definition with non-null outObject should not occur)
if (outputDefinition == null) {
output.add(item);
output.addAllFrom(input);
}
}
if (value instanceof PrismObjectValue) {
operationsHelper.recordEnd(context, asObjectType(value), started, null);
}
} catch (Throwable ex) {
if (value instanceof PrismObjectValue) {
operationsHelper.recordEnd(context, asObjectType(value), started, ex);
}
exception = processActionException(ex, NAME, value, context);
exception = processActionException(ex, NAME, null, context); // TODO value for error reporting (3rd parameter)
}
context.println((exception != null ? "Attempted to execute " : "Executed ")
+ "script on " + valueDescription + exceptionSuffix(exception));
+ "script on the pipeline" + exceptionSuffix(exception));
operationsHelper.trimAndCloneResult(result, globalResult, context);
}
} else {
for (PipelineItem item : input.getData()) {
PrismValue value = item.getValue();
OperationResult result = operationsHelper.createActionResult(item, this, context, globalResult);

context.checkTaskStop();
String valueDescription;
long started;
if (value instanceof PrismObjectValue) {
started = operationsHelper.recordStart(context, asObjectType(value));
valueDescription = asObjectType(value).asPrismObject().toString();
} else {
started = 0;
valueDescription = value.toHumanReadableString();
}
Throwable exception = null;
try {
Object outObject = executeScript(scriptExpression, value, context, result);
if (outObject != null) {
addToData(outObject, item.getResult(), output);
} else {
// no definition means we don't plan to provide any output - so let's just copy the input item to the output
// (actually, null definition with non-null outObject should not occur)
if (outputDefinition == null) {
output.add(item);
}
}
if (value instanceof PrismObjectValue) {
operationsHelper.recordEnd(context, asObjectType(value), started, null);
}
} catch (Throwable ex) {
if (value instanceof PrismObjectValue) {
operationsHelper.recordEnd(context, asObjectType(value), started, ex);
}
exception = processActionException(ex, NAME, value, context);
}
context.println((exception != null ? "Attempted to execute " : "Executed ")
+ "script on " + valueDescription + exceptionSuffix(exception));
operationsHelper.trimAndCloneResult(result, globalResult, context);
}
}
return output;
}

Expand Down Expand Up @@ -165,10 +191,10 @@ private ItemDefinition<?> getItemDefinition(String itemUri) throws ScriptExecuti
throw new ScriptExecutionException("Supplied item identification " + itemUri + " corresponds neither to item name nor type name");
}

private Object executeScript(ScriptExpression scriptExpression, PrismValue prismValue, ExecutionContext context, OperationResult result)
private Object executeScript(ScriptExpression scriptExpression, Object input, ExecutionContext context, OperationResult result)
throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
ExpressionVariables variables = new ExpressionVariables();
variables.addVariableDefinition(ExpressionConstants.VAR_INPUT, prismValue);
variables.addVariableDefinition(ExpressionConstants.VAR_INPUT, input);
variables.addVariableDefinition(ExpressionConstants.VAR_PRISM_CONTEXT, prismContext);
ExpressionUtil.addActorVariable(variables, securityEnforcer);

Expand Down
Expand Up @@ -154,8 +154,10 @@ public void recordEnd(ExecutionContext context, ObjectType objectType, long star
public OperationResult createActionResult(PipelineItem item, ActionExecutor executor, ExecutionContext context,
OperationResult globalResult) {
OperationResult result = new OperationResult(executor.getClass().getName() + "." + "execute");
result.addParam("value", String.valueOf(item.getValue()));
item.getResult().addSubresult(result);
if (item != null) {
result.addParam("value", String.valueOf(item.getValue()));
item.getResult().addSubresult(result);
}
return result;
}

Expand Down
Expand Up @@ -72,7 +72,7 @@ public class TestPolicyRules2 extends AbstractLensTest {
protected static final File ROLE_AMBIGUOUS_REFERENCE_FILE = new File(TEST_DIR, "role-ambiguous-reference.xml");

private static final int STUDENT_TARGET_RULES = 5; // one is global
private static final int STUDENT_FOCUS_RULES = 20;
private static final int STUDENT_FOCUS_RULES = 21;

private static final String ACTIVITY_DESCRIPTION = "PROJECTOR (test)";

Expand Down
Expand Up @@ -26,7 +26,9 @@
<name>rule-A</name>
<policyConstraints>
<name>constraint-A</name>
<ref>constraint-B</ref>
<ref>
<name>constraint-B</name>
</ref>
</policyConstraints>
<policyActions>
<!-- none -->
Expand Down
Expand Up @@ -25,7 +25,9 @@
<policyRule>
<name>rule1</name>
<policyConstraints>
<ref>mod-description-and-riskLevel-and-inducement</ref>
<ref>
<name>mod-description-and-riskLevel-and-inducement</name>
</ref>
</policyConstraints>
<policyActions>
<!-- none -->
Expand All @@ -40,7 +42,9 @@
<modification>
<item>description</item>
</modification>
<ref>mod-riskLevel-and-inducement</ref>
<ref>
<name>mod-riskLevel-and-inducement</name>
</ref>
</policyConstraints>
<policyActions>
<!-- none -->
Expand All @@ -55,7 +59,9 @@
<modification>
<item>riskLevel</item>
</modification>
<ref>mod-inducement</ref>
<ref>
<name>mod-inducement</name>
</ref>
</policyConstraints>
<policyActions>
<!-- none -->
Expand Down
Expand Up @@ -20,13 +20,15 @@
xmlns:ri="http://midpoint.evolveum.com/xml/ns/public/resource/instance-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name>Cyclic references</name>
<name>Cyclic references</name>
<assignment>
<policyRule>
<name>rule-A</name>
<policyConstraints>
<name>constraint-A</name>
<ref>constraint-B</ref>
<ref>
<name>constraint-B</name>
</ref>
</policyConstraints>
<policyActions>
<!-- none -->
Expand All @@ -48,7 +50,9 @@
<stateBefore>false</stateBefore>
<stateAfter>true</stateAfter>
<constraints>
<ref>constraint-A</ref>
<ref>
<name>constraint-A</name>
</ref>
</constraints>
</transition>
</and>
Expand Down

0 comments on commit f173e89

Please sign in to comment.