Expressions
Action Parameters allow the inputs to an action to be formed from different parts of the flow run-time state. However, the reference approach requires that the exact value must be present in the flow’s state. If the required value is somehow to be derived from multiple values in the flow state, reference parameters are not sufficient. Thus, we introduce expression type parameters which may evaluate multiple parts of the state to compute a single, required value.
The syntax of an expression parameter takes the following form:
{
"computed_param.=": "<state_val1> <op> <state_val2> <op> ..."
}
The syntax for the expression largely follows what is expected in common expression languages.
This includes common arithmetic operators on numeric values
as well as operations on strings (e.g. string concatenation via a +
operation)
and on lists (similarly the +
operator will concatenate lists).
The values in the state of the flow may be used in the expression and are denoted as <state_valN>
above.
For the following description, assume that the input to (or current state of) a flow run is as follows:
{
"foo": "bar",
"object_val": {
"sub_val1": "embedded",
"sub_val2": "also_embedded"
}
}
The state_val
values can be specified as the simple names of the properties in the state of the running flow and allows for indexing into lists and into embedded objects similar to Python.
Thus, the following would be a valid expression: foo + ' ' + object_val.sub_val1
which would yield the string bar embedded
.
Note the use of +
to mean string concatenation and the dot-separated naming of the field of the object.
Constants may also be used between operators, it is important to remember that within an expression, a string type value must be enclosed in quotes (either single quote characters as above which is often easier because they do not need to be escaped within a JSON string or double quotes).
Using Functions in Expressions
In addition to basic arithmetic operations, a few functions may be used.
Functions are invoked with the general form: function_name(param1, param2)
.
Thus, an expression may, for example, take the form val1 + function(param1)
.
The functions currently supported are:
-
len
: Calculate the length of something countable.The
len
function can be passed a string, a JSON object, a JSON array, or a Python tuple or set. Its behavior matches the behavior of the Pythonlen()
function. An error will occur if it is not called with exactly 1 argument or if it is called with something that cannot be counted (such as a number).-
len("string")
returns6
(the length of the string) -
len({"a": 5, "c": True})
returns2
(the number of properties in the object) -
len(["mine", "yours", "theirs"])
returns3
(the number of items in the array) -
len(set([1, 2, 3]).intersect(set([3, 4, 5])))
returns1
(the number of items shared between both sets)
-
-
pathsplit
: This function may be used to break apart a "path" type string value. Paths are a series of path element names separated by/
characters. The return value from thepathsplit
function is an array of two elements: the first element is the path prior to the last element. This is also aware of the string/~/
, which is defined by Globus as the Default Directory of a Collection. This string will be preserved as a path component. Examples:-
pathsplit("/foo/bar/blech")
returns["/foo/bar", "blech"]
-
pathsplit("/~/path")
returns["/~/", "path"]
-
-
is_present
: This function checks for the existence of a value in the state of the input Parameters. It is similar to the IsPresent operator in the Amazon States Language. It takes in a reference to a value in the state, as a string, and returnstrue
if the value exists, andfalse
if not. This can be used to ensure that a value is present before using it in a further expression such as:x if is_present('x') else 10
which would use the conditional expression to check for presence of the propertyx
and sets a constant if it is not present. This helps to avoid accessing properties that are not defined which would cause an error. -
getattr
: This function will return a value from the state of the input if it is present, and, optionally, a default value if it is not present. Examples:-
getattr('x', 10)
: returns the value of propertyx
if it is present, and the constant 10 if not (equivalent to theis_present
example above. -
getattr('missing_property')
: Would return anull
value if themissing_property
value is not present in the state.
-
ExpressionEval
State type
The Action
state type provides a method of evaluating expressions to create Parameter values for passing to the action, and the Pass
state, defined in the States Language, provides a means of moving or re-arranging the flow’s run-time state by specifying input Parameters and new locations via the ResultPath
.
In some cases, the combination of the two capabilities is desired: the ability to compute results for Parameters as in the Action
state and the simple storage of the new values, as in the Pass
state.
This is the role of the ExpressionEval
state type.
It can be thought of as an Action
without the action invocation, or a Pass
where Parameters
may contain expressions.
A primary situation in which this state type will be used is when determining a value to be tested in a Choice
state type.
The Choice
state type can only read single values from the run-time state of the flow, so if, for example, a value on which a Choice
condition needs to be applied must be combined from separate parts of the flow run-time state.
The computed value can then be referenced in the Variable
property of the Choice.
Another use is to compute a "final" for the flow to be stored in the state of the flow and therefore seen in the output of the flow upon completion.
An example structure for an ExpressionEval
state is as follows:
{
"Type": "ExpressionEval",
"Parameters": {
"constant_val": 10,
"reference_value.$": "$.Path.To.Value",
"expression_value.=": "'Constant string ' + `$.Path.To.SuffixString`",
"nested_value": {
"child_const_val": true,
"child_ref_val.$": "$.Child.Val.Path"
},
"secret_value": "MyPassword",
"__Private_Parameters": [
"secret_value"
]
},
"ResultPath": "$.final_result",
"End": true
}
All properties of the ExpressionEval
state have the same meaning as described in the Action
state.
The ExpressionEval
state cannot use the InputPath
property (Pass
is appropriate if moving state from an InputPath
to a ResultPath
is needed), so Parameters
must always be present.
Just like in Action
the Parameters
may have constant, reference or expression types and portions of the state can be protected using a __Private_Parameters
list.
Like Action
, this state must have either a Next
or an End: true
.