# Variables in bulk actions

 Since 3.7 This functionality is available since version 3.7.
 Some parts (namely, defining variables using expressions other than path-based) are, however, considered experimental.

## Introduction

Bulk actions (midPoint scripts) work in so called pipes and filters model, just like e.g. traditional UNIX shell scripts. They consist of a number of primitive activities chained together into a sequence or sometimes into a more complex structure. Input from each activity is fed into the activity that immediately follows.

However, sometimes it is useful to keep a global context for execution of these activities. It is available in each activity execution. It is split when execution is split, for example when a search is executed and an execution "branch" is created for each object found.

Currently this context contains a set of variables. For the time being, these variables are initialized when the midPoint script starts, and are considered read-only during the execution of the whole script. In the future we might consider allowing additions or modifications into these variables, making the processing much more flexible (at the cost of deviation from pure pipes and filters model).

The main use of the current implementation is easy parameterization of bulk actions: for example if we want to find all users of employeeType X and set their employeeType to Y, values for X and Y can be stored in bulk action variables.

## Default variables

There are the following variables available by default:

Variable name Type Meaning Availability

The current task (transient for synchronous execution or persistent for asynchronous one).

Always.

ruleEvaluationContext

PolicyRuleEvaluationContext

Context for policy rule evaluation.

When using bulk action in to evaluate object state constraint.

It is possible to define additional variables within the `<executeScript>` element.

### Example 1: Apply some action on user whose name is configurable

``````<s:executeScript 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:q="http://prism.evolveum.com/xml/ns/public/query-3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<s:pipeline>
<s:search>
<s:type>c:UserType</s:type>
<s:query>
<q:filter>
<q:equal>
<q:path>name</q:path>
<c:expression>
<c:path>$userName</c:path> </c:expression> </q:equal> </q:filter> </s:query> </s:search> <s:action> ... </s:action> </s:pipeline> <s:variables> <s:variable> <s:name>userName</s:name> <s:expression> <c:path>$task/extension/userName</c:path>
</s:expression>
</s:variable>
</s:variables>
</s:executeScript>``````

The `<variables>` section defines a single variable (userName). Its value is taken from task’s extension. It is then used in the search filter.

### Example 2: Define variables as constants or expressions

In the `<variables>` section we can use not only path expressions but any other suitable ones. However, this feature is considered to be an experimental one.

Note that this sample is artificial one, used for testing this mechanism. We define 5 variables. Some of them are path-based (userName, groups); some are defined as literal values (academicYear, calendarYear) and one is computed by an expression (deadline).

For expression-based variables it is necessary to specify their type. For value-based the type is derived from the literal value xsi:type (if present).

Various mechanisms for defining bulk action variables
``````<s:executeScript 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:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<s:action>
<s:type>execute-script</s:type>
<s:parameter>
<s:name>script</s:name>
<c:value xsi:type="c:ScriptExpressionEvaluatorType">
<c:code>
log.info('=== Variables ===')
this.binding.variables.each {k,v -> log.info('{} = {}', k, v)}

}
if (new java.util.HashSet(groups) != ['group1', 'group2', 'group3'] as Set) {
return 'Wrong groups: ' + groups
}
}
if (calendarYear != 2017) {
return 'Wrong calendar year: ' + calendarYear
}
}
return 'ok'
</c:code>
</c:value>
</s:parameter>
<s:parameter>
<s:name>forWholeInput</s:name>
<c:value>true</c:value>
</s:parameter>
<s:parameter>
<s:name>outputItem</s:name>	<!-- for testing purposes: for the calling Java code to be able to check the result of the bulk action -->
<c:value>http://midpoint.evolveum.com/xml/ns/public/common/common-3#description</c:value>       <!-- just a plain string -->
</s:parameter>
</s:action>
<s:variables>
<s:variable>
<s:expression>
<c:path>$task/extension/userName</c:path> </s:expression> </s:variable> <s:variable> <s:name>groups</s:name> <s:expression> <c:path>$task/extension/studyGroup</c:path>
</s:expression>
</s:variable>
<s:variable>
<s:expression>
<c:value>2017/2018</c:value>
</s:expression>
</s:variable>
<s:variable>
<s:name>calendarYear</s:name>
<s:expression>
<c:value xsi:type="xsd:int">2017</c:value>
</s:expression>
</s:variable>
<s:variable>
<s:type>xsd:dateTime</s:type>
<s:expression>
<c:script>
<c:code>
basic.fromNow("P3D")
</c:code>
</c:script>
</s:expression>
</s:variable>
</s:variables>
</s:executeScript>``````

Available since v3.7devel-714-ga4ad63b (October 20th, 2017).