New State - ForEach (#143)
* New State - ForEach * updating documentation about foreach state * foreach state - parallel execution
This commit is contained in:
parent
1e2b41636d
commit
a7af88b477
|
@ -94,6 +94,10 @@
|
|||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -379,6 +383,10 @@
|
|||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -428,9 +436,6 @@
|
|||
"type": "string",
|
||||
"description": "Amount of time (ISO 8601 format) to delay"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "OnError Definition",
|
||||
|
@ -504,9 +509,6 @@
|
|||
"$ref": "#/definitions/eventactions"
|
||||
}
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States runtime error handling definitions",
|
||||
|
@ -567,9 +569,6 @@
|
|||
"$ref": "#/definitions/action"
|
||||
}
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "OnError Definition",
|
||||
|
@ -644,9 +643,6 @@
|
|||
"$ref": "#/definitions/branch"
|
||||
}
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "OnError Definition",
|
||||
|
@ -711,9 +707,6 @@
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"choices": {
|
||||
"type": "array",
|
||||
"description": "Defines an ordered set of Match Rules against the input data to this state",
|
||||
|
@ -812,9 +805,6 @@
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "OnError Definition",
|
||||
|
@ -898,6 +888,120 @@
|
|||
"required": ["name", "type", "transition"]
|
||||
}
|
||||
},
|
||||
"foreachstate": {
|
||||
"type": "object",
|
||||
"description": "Execute a set of defined states for each element of the data input array",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique State id",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "State name"
|
||||
},
|
||||
"type": {
|
||||
"type" : "string",
|
||||
"enum": ["FOREACH"],
|
||||
"description": "State type"
|
||||
},
|
||||
"end": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Is this state an end state"
|
||||
},
|
||||
"inputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath expression selecting an JSON array element of the states data input"
|
||||
},
|
||||
"outputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath expression specifying where in the states data output to place the final data output of each iteration of the executed states"
|
||||
},
|
||||
"inputParameter": {
|
||||
"type": "object",
|
||||
"description": "JSONPath expression specifying an JSON object field of the states data input. For each parallel iteration, this field will get populated with a unique element of the inputCollection array"
|
||||
},
|
||||
"max": {
|
||||
"type": "integer",
|
||||
"default": "0",
|
||||
"minimum": 0,
|
||||
"description": "Specifies how upper bound on how many iterations may run in parallel"
|
||||
},
|
||||
"timeDelay": {
|
||||
"type": "string",
|
||||
"description": "|Amount of time (ISO 8601 format) to wait between each iteration "
|
||||
},
|
||||
"startsAt": {
|
||||
"type": "string",
|
||||
"description": "Unique name of a states in the states array representing the starting state to be executed"
|
||||
},
|
||||
"states": {
|
||||
"type": "array",
|
||||
"description": "States to be executed for each of the elements of inputCollection",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{
|
||||
"title": "Delay State",
|
||||
"$ref": "#/definitions/delaystate"
|
||||
},
|
||||
{
|
||||
"title": "Event State",
|
||||
"$ref": "#/definitions/eventstate"
|
||||
},
|
||||
{
|
||||
"title": "Operation State",
|
||||
"$ref": "#/definitions/operationstate"
|
||||
},
|
||||
{
|
||||
"title": "Switch State",
|
||||
"$ref": "#/definitions/switchstate"
|
||||
},
|
||||
{
|
||||
"title": "SubFlow State",
|
||||
"$ref": "#/definitions/subflowstate"
|
||||
},
|
||||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
},
|
||||
"transition": {
|
||||
"description": "Next transition of the workflow after subflow has completed",
|
||||
"$ref": "#/definitions/transition"
|
||||
}
|
||||
},
|
||||
"if": {
|
||||
"properties": {
|
||||
"end": { "const": true }
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"required": ["name", "type", "inputCollection", "inputParameter", "startsAt", "states"]
|
||||
},
|
||||
"else": {
|
||||
"required": ["name", "type", "transition", "inputCollection", "inputParameter", "startsAt", "states"]
|
||||
}
|
||||
},
|
||||
"defaultchoice": {
|
||||
"type": "object",
|
||||
"description": "Default Choice",
|
||||
|
@ -1024,31 +1128,6 @@
|
|||
"required": [
|
||||
"body"
|
||||
]
|
||||
},
|
||||
"loop": {
|
||||
"type": "object",
|
||||
"description": "Defines state Looping Information",
|
||||
"properties": {
|
||||
"inputCollection": {
|
||||
"type": "string",
|
||||
"description": "Selects a collection of the states inputPath"
|
||||
},
|
||||
"outputCollection": {
|
||||
"type": "string",
|
||||
"description": "Selects a collection of the states outputPath"
|
||||
},
|
||||
"completionCondition": {
|
||||
"type": "string",
|
||||
"description": "Boolean expression (evaluated after each iteration) that controls the loop. If this expression is true looping stops even if not all collection elements are processesd."
|
||||
},
|
||||
"timeDelay": {
|
||||
"type": "string",
|
||||
"description": "Amount of time (ISO 8601 format) to wait between each loop"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"inputCollection"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
- [Hello World](#Hello-World-Example)
|
||||
- [Greeting](#Greeting-Example)
|
||||
- [Solving Math Problems (Looping)](#Solving-Math-Problems-Example)
|
||||
- [Solving Math Problems (ForEach)](#Solving-Math-Problems-Example)
|
||||
- [Parallel Execution](#Parallel-Execution-Example)
|
||||
- [Applicant Request Decision (Switch + SubFlow)](#Applicant-Request-Decision-Example)
|
||||
- [Provision Orders (Error Handling)](#Provision-Orders-Example)
|
||||
|
@ -149,7 +149,8 @@ output, which then becomes the data output of the workflow itself (as it is the
|
|||
|
||||
#### Description
|
||||
|
||||
In this example we show off looping in an Operation state. The state will loop over a collection of simple math expressions which are
|
||||
In this example we show how to iterate over some data input using the ForEach state.
|
||||
The state will iterate over a collection of simple math expressions which are
|
||||
passed in as the workflow data input:
|
||||
|
||||
```json
|
||||
|
@ -157,21 +158,12 @@ passed in as the workflow data input:
|
|||
"expressions": ["2+2", "4-1", "10x3", "20/2"]
|
||||
}
|
||||
```
|
||||
The ForEach state will execute a single defined operation state for each math expression. The operation
|
||||
state contains an action which calls a serverless function which actually solves the expression
|
||||
and returns its result.
|
||||
|
||||
The operation state contains an action which calls the serverless function that solves the math expression and returns its answer.
|
||||
|
||||
The results of the action is assumed to be the answer, for example for the first expression:
|
||||
|
||||
```
|
||||
"4"
|
||||
```
|
||||
|
||||
The state filter is then used to only return the results of the solved math expressions which becomes the workflow data output:
|
||||
|
||||
|
||||
```json
|
||||
["4", "3", "30", "10"]
|
||||
```
|
||||
Results of all mathe expressions are accumulated into the data output of the ForEach state which become the final
|
||||
result of the workflow execution.
|
||||
|
||||
#### Workflow JSON
|
||||
|
||||
|
@ -187,26 +179,33 @@ The state filter is then used to only return the results of the solved math expr
|
|||
}
|
||||
],
|
||||
"states":[
|
||||
{
|
||||
{
|
||||
"name":"Solve",
|
||||
"type":"OPERATION",
|
||||
"actionMode":"SEQUENTIAL",
|
||||
"actions":[
|
||||
"type":"FOREACH",
|
||||
"inputCollection": "$.expressions",
|
||||
"inputParameter": "$.singleexpression",
|
||||
"outputCollection": "$.results",
|
||||
"startsAt": "GetResults",
|
||||
"states": [
|
||||
{
|
||||
"functionref": {
|
||||
"refname": "solveMathExpressionFunction",
|
||||
"parameters": {
|
||||
"expression": "$."
|
||||
}
|
||||
}
|
||||
"name":"GetResults",
|
||||
"type":"OPERATION",
|
||||
"actionMode":"SEQUENTIAL",
|
||||
"actions":[
|
||||
{
|
||||
"functionref": {
|
||||
"refname": "solveMathExpressionFunction",
|
||||
"parameters": {
|
||||
"expression": "$.singleexpression"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": true
|
||||
}
|
||||
],
|
||||
"loop": {
|
||||
"inputCollection": "$.expressions",
|
||||
"outputCollection": "$.answers"
|
||||
},
|
||||
"filter": {
|
||||
"outputPath": "$.answers"
|
||||
"outputPath": "$.results"
|
||||
},
|
||||
"end": true
|
||||
}
|
||||
|
|
|
@ -192,13 +192,38 @@ Here we define details of the Serverless Workflow definitions:
|
|||
"items": {
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{ "$ref": "#definitions/delaystate" },
|
||||
{ "$ref": "#definitions/eventstate" },
|
||||
{ "$ref": "#definitions/operationstate" },
|
||||
{ "$ref": "#definitions/parallelstate" },
|
||||
{ "$ref": "#definitions/switchstate" },
|
||||
{ "$ref": "#definitions/subflowstate" },
|
||||
{ "$ref": "#definitions/relaystate" }
|
||||
{
|
||||
"title": "Delay State",
|
||||
"$ref": "#/definitions/delaystate"
|
||||
},
|
||||
{
|
||||
"title": "Event State",
|
||||
"$ref": "#/definitions/eventstate"
|
||||
},
|
||||
{
|
||||
"title": "Operation State",
|
||||
"$ref": "#/definitions/operationstate"
|
||||
},
|
||||
{
|
||||
"title": "Parallel State",
|
||||
"$ref": "#/definitions/parallelstate"
|
||||
},
|
||||
{
|
||||
"title": "Switch State",
|
||||
"$ref": "#/definitions/switchstate"
|
||||
},
|
||||
{
|
||||
"title": "SubFlow State",
|
||||
"$ref": "#/definitions/subflowstate"
|
||||
},
|
||||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -412,7 +437,10 @@ States define building blocks of the Serverless Workflow. The specification defi
|
|||
- **[SubFlow State](#SubFlow-State)**: Allows execution of a sub-workflow.
|
||||
|
||||
- **[Relay State](#Relay-State)**: Used to relay state's data input to output without executing any actions. State's data input can be filtered.
|
||||
|
||||
|
||||
- **[ForEach State](#ForEach-State)**: Allows a set of defined states to be executed for each element of a data input array.
|
||||
|
||||
|
||||
We will start defining each individual state:
|
||||
|
||||
### Event State
|
||||
|
@ -425,7 +453,6 @@ We will start defining each individual state:
|
|||
| end |Is this state an end state | boolean | no |
|
||||
| [eventActions](#eventstate-eventactions) | Define what events trigger one or more actions to be performed | array | yes |
|
||||
| [filter](#Filter-Definition) | State data filter | object | yes |
|
||||
| [loop](#Loop-Definition) | State loop information | object | yes |
|
||||
| [onError](#Workflow-Error-Handling) |States error handling definitions | array | no |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
@ -466,9 +493,6 @@ We will start defining each individual state:
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
|
@ -795,9 +819,6 @@ Defines a transition from point A to point B in the serverless workflow. For mor
|
|||
},
|
||||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
|
@ -836,14 +857,13 @@ Once all actions have been performed, a transition to another state can occur.
|
|||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| id | Unique state id | string | no |
|
||||
| name | State name | string | yes |
|
||||
| type | State type | string | yes |
|
||||
| end | Is this state an end start | boolean | no |
|
||||
| [choices](#switch-state-choices) | Ordered set of matching rules to determine which state to trigger next | array | yes |
|
||||
| [filter](#Filter-Definition) | State data filter | object | yes |
|
||||
| [loop](#Loop-Definition) | State loop information | object | no |
|
||||
| [onError](#Workflow-Error-Handling) | States error handling definitions | array | no |
|
||||
| default | Next transition of the workflow if there is no match for any choices | object | yes (if end is set to false) |
|
||||
| name |State name | string | yes |
|
||||
| type |State type | string | yes |
|
||||
| end |Is this state an end start | boolean | no |
|
||||
| [choices](#switch-state-choices) |Ordered set of matching rules to determine which state to trigger next | array | yes |
|
||||
| [filter](#Filter-Definition) |State data filter | object | yes |
|
||||
| [onError](#Workflow-Error-Handling) |States error handling definitions | array | no |
|
||||
| default |Next transition of the workflow if there is no match for any choices | object | yes (if end is set to false) |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
|
@ -886,9 +906,6 @@ Once all actions have been performed, a transition to another state can occur.
|
|||
},
|
||||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
|
@ -1115,14 +1132,13 @@ There are four types of choices defined:
|
|||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| id | Unique state id | string | no |
|
||||
| name | State name | string | yes |
|
||||
| type | State type | string | yes |
|
||||
| end | If this state an end state | boolean | no |
|
||||
| timeDelay | Amount of time (ISO 8601 format) to delay when in this state. For example: "PT15M" (delay 15 minutes), or "P2DT3H4M" (delay 2 days, 3 hours and 4 minutes) | integer | yes |
|
||||
| [filter](#Filter-Definition) | State data filter | object | yes |
|
||||
| [loop](#Loop-Definition) | State loop information | object | no |
|
||||
| [onError](#Error-Handling) | States error handling definitions | array | no |
|
||||
| [transition](#Transitions) | Next transition of the workflow after the delay | string | yes (if end is set to false) |
|
||||
| name |State name | string | yes |
|
||||
| type |State type | string | yes |
|
||||
| end |If this state an end state | boolean | no |
|
||||
| timeDelay |Amount of time (ISO 8601 format) to delay when in this state. For example: "PT15M" (delay 15 minutes), or "P2DT3H4M" (delay 2 days, 3 hours and 4 minutes) | integer | yes |
|
||||
| [filter](#Filter-Definition) |State data filter | object | yes |
|
||||
| [onError](#Error-Handling) |States error handling definitions | array | no |
|
||||
| [transition](#Transitions) |Next transition of the workflow after the delay | string | yes (if end is set to false) |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
|
@ -1157,9 +1173,6 @@ There are four types of choices defined:
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
|
@ -1196,14 +1209,13 @@ Delay state waits for a certain amount of time before transitioning to a next st
|
|||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| id | Unique state id | string | no |
|
||||
| name | State name | string | yes |
|
||||
| type | State type | string | yes |
|
||||
| end | If this state and end state | boolean | no |
|
||||
| [branches](#parallel-state-branch) | List of branches for this parallel state| array | yes |
|
||||
| [filter](#Filter-Definition) | State data filter | object | yes |
|
||||
| [loop](#Loop-Definition) | State loop behavior | object | no |
|
||||
| [onError](#Error-Handling) | States error handling definitions | array | no |
|
||||
| [transition](#Transitions) | Next transition of the workflow after all branches have completed execution | string | yes (if end is set to false) |
|
||||
| name |State name | string | yes |
|
||||
| type |State type | string | yes |
|
||||
| end |If this state and end state | boolean | no |
|
||||
| [branches](#parallel-state-branch) |List of branches for this parallel state| array | yes |
|
||||
| [filter](#Filter-Definition) |State data filter | object | yes |
|
||||
| [onError](#Error-Handling) |States error handling definitions | array | no |
|
||||
| [transition](#Transitions) |Next transition of the workflow after all branches have completed execution | string | yes (if end is set to false) |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
|
@ -1242,9 +1254,6 @@ Delay state waits for a certain amount of time before transitioning to a next st
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
|
@ -1308,13 +1317,34 @@ Branches contain one or more states. Each branch must define a starting state vi
|
|||
"items": {
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{ "$ref": "#definitions/delaystate" },
|
||||
{ "$ref": "#definitions/eventstate" },
|
||||
{ "$ref": "#definitions/operationstate" },
|
||||
{ "$ref": "#definitions/parallelstate" },
|
||||
{ "$ref": "#definitions/switchstate" },
|
||||
{ "$ref": "#definitions/subflowstate" },
|
||||
{ "$ref": "#definitions/relaystate" }
|
||||
{
|
||||
"title": "Delay State",
|
||||
"$ref": "#/definitions/delaystate"
|
||||
},
|
||||
{
|
||||
"title": "Event State",
|
||||
"$ref": "#/definitions/eventstate"
|
||||
},
|
||||
{
|
||||
"title": "Operation State",
|
||||
"$ref": "#/definitions/operationstate"
|
||||
},
|
||||
{
|
||||
"title": "Switch State",
|
||||
"$ref": "#/definitions/switchstate"
|
||||
},
|
||||
{
|
||||
"title": "SubFlow State",
|
||||
"$ref": "#/definitions/subflowstate"
|
||||
},
|
||||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -1345,15 +1375,14 @@ Parallel state must wait for all branches which have this property set to "true"
|
|||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| id | Unique state id | string | no |
|
||||
| name | State name | string | yes |
|
||||
| type | State type | string | yes |
|
||||
| end | If this state and end state | boolean | no |
|
||||
| waitForCompletion | If workflow execution must wait for sub-workflow to finish before continuing | boolean | yes |
|
||||
| workflowId | Sub-workflow unique id | boolean | no |
|
||||
| [filter](#Filter-Definition) | State data filter | object | yes |
|
||||
| [loop](#Loop-Definition) | State loop information | object | no |
|
||||
| [onError](#State-Exception-Handling) | States error handling definitions | array | no |
|
||||
| [transition](#Transitions) | Next transition of the workflow after subflow has completed | string | yes (if end is set to false) |
|
||||
| name |State name | string | yes |
|
||||
| type |State type | string | yes |
|
||||
| end |If this state and end state | boolean | no |
|
||||
| waitForCompletion |If workflow execution must wait for sub-workflow to finish before continuing | boolean | yes |
|
||||
| workflowId |Sub-workflow unique id | boolean | no |
|
||||
| [filter](#Filter-Definition) |State data filter | object | yes |
|
||||
| [onError](#State-Exception-Handling) |States error handling definitions | array | no |
|
||||
| [transition](#Transitions) |Next transition of the workflow after subflow has completed | string | yes (if end is set to false) |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
|
@ -1393,9 +1422,6 @@ Parallel state must wait for all branches which have this property set to "true"
|
|||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"loop": {
|
||||
"$ref": "#/definitions/loop"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
|
@ -1603,14 +1629,306 @@ $.people[?(@.age >= 40)]
|
|||
to test if your workflow behaves properly for the case when there are people who's age is greater or equal 40.
|
||||
|
||||
|
||||
### ForEach State
|
||||
|
||||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| id | Unique state id | string | no |
|
||||
| name | State name | string | yes |
|
||||
| type | State type | string | yes |
|
||||
| end |Is this state an end state | boolean | no |
|
||||
| inputCollection | JSONPath expression selecting an JSON array element of the states data input | string | yes |
|
||||
| outputCollection | JSONPath expression specifying where in the states data output to place the final data output of each iteration of the executed states | string | no |
|
||||
| inputParameter | JSONPath expression specifying an JSON object field of the states data input. For each parallel iteration, this field will get populated with an unique element of the inputCollection array. | string | yes |
|
||||
| max | Specifies how upper bound on how many iterations may run in parallel | integer | no |
|
||||
| timeDelay | Amount of time (ISO 8601 format) to wait between each iteration | string | no |
|
||||
| startsAt | Unique name of a states in the states array representing the starting state to be executed | string |yes |
|
||||
| [states](#State-Definition) | States to be executed for each of the elements of inputCollection | array | yes |
|
||||
| [filter](#Filter-Definition) | State data filter | object | no |
|
||||
| [onError](#Error-Handling) | States error handling definitions | array | no |
|
||||
| [transition](#Transitions) | Next transition of the workflow after state has completed | string | yes (if end is set to false) |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Execute a set of defined states for each element of the data input array",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"description": "Unique State id",
|
||||
"minLength": 1
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description": "State name"
|
||||
},
|
||||
"type": {
|
||||
"type" : "string",
|
||||
"enum": ["FOREACH"],
|
||||
"description": "State type"
|
||||
},
|
||||
"end": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Is this state an end state"
|
||||
},
|
||||
"inputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath expression selecting an JSON array element of the states data input"
|
||||
},
|
||||
"outputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath expression specifying where in the states data output to place the final data output of each iteration of the executed states"
|
||||
},
|
||||
"inputParameter": {
|
||||
"type": "object",
|
||||
"description": "JSONPath expression specifying an JSON object field of the states data input. For each parallel iteration, this field will get populated with a unique element of the inputCollection array"
|
||||
},
|
||||
"max": {
|
||||
"type": "integer",
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
"description": "Specifies how upper bound on how many iterations may run in parallel"
|
||||
},
|
||||
"timeDelay": {
|
||||
"type": "string",
|
||||
"description": "|Amount of time (ISO 8601 format) to wait between each iteration "
|
||||
},
|
||||
"startsAt": {
|
||||
"type": "string",
|
||||
"description": "Unique name of a states in the states array representing the starting state to be executed"
|
||||
},
|
||||
"states": {
|
||||
"type": "array",
|
||||
"description": "States to be executed for each of the elements of inputCollection",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"anyOf": [
|
||||
{
|
||||
"title": "Delay State",
|
||||
"$ref": "#/definitions/delaystate"
|
||||
},
|
||||
{
|
||||
"title": "Event State",
|
||||
"$ref": "#/definitions/eventstate"
|
||||
},
|
||||
{
|
||||
"title": "Operation State",
|
||||
"$ref": "#/definitions/operationstate"
|
||||
},
|
||||
{
|
||||
"title": "Switch State",
|
||||
"$ref": "#/definitions/switchstate"
|
||||
},
|
||||
{
|
||||
"title": "SubFlow State",
|
||||
"$ref": "#/definitions/subflowstate"
|
||||
},
|
||||
{
|
||||
"title": "Relay State",
|
||||
"$ref": "#/definitions/relaystate"
|
||||
},
|
||||
{
|
||||
"title": "ForEach State",
|
||||
"$ref": "#/definitions/foreachstate"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"filter": {
|
||||
"$ref": "#/definitions/filter"
|
||||
},
|
||||
"onError": {
|
||||
"type": "array",
|
||||
"description": "States error handling definitions",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
},
|
||||
"transition": {
|
||||
"description": "Next transition of the workflow after subflow has completed",
|
||||
"$ref": "#/definitions/transition"
|
||||
}
|
||||
},
|
||||
"if": {
|
||||
"properties": {
|
||||
"end": { "const": true }
|
||||
}
|
||||
},
|
||||
"then": {
|
||||
"required": ["name", "type", "inputCollection", "inputParameter", "startsAt", "states"]
|
||||
},
|
||||
"else": {
|
||||
"required": ["name", "type", "transition", "inputCollection", "inputParameter", "startsAt", "states"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
The ForEach state can be used to execute a defined set of states for each element of an array (defined in the states data input).
|
||||
While the [Parallel state](#Parallel-State) performs multiple branches of states using the
|
||||
same data input, the ForEach state performs the defined steps for multiple entries of an array in the states data input.
|
||||
|
||||
Note that each iteration of the ForEach state should be executed in parallel.
|
||||
You can use the "max" property to set the upper bound on how many iterations may run in parallel. The default
|
||||
of the "max" property is zero, which places no limit on number of parallel executions.
|
||||
|
||||
States defined in the "states" property of the ForEach state can only transition to each other and
|
||||
cannot transition to states outside of this state.
|
||||
Similarly other workflow states cannot transition to one of the states defined within the ForEach state.
|
||||
|
||||
States defined in the "states" property must contain at least one state which is an end state (has the end property set to true).
|
||||
|
||||
Let's take a look at a simple ForEach state example through which we can explain this state:
|
||||
|
||||
In this example the data input to our ForEach state is an array of orders:
|
||||
|
||||
```json
|
||||
{
|
||||
"orders": [
|
||||
{
|
||||
"orderNumber": "1234",
|
||||
"completed": true,
|
||||
"email": "firstBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "5678",
|
||||
"completed": true,
|
||||
"email": "secondBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "9910",
|
||||
"completed": false,
|
||||
"email": "thirdBuyer@buyer.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
and the state is defined as:
|
||||
|
||||
```json
|
||||
{
|
||||
"functions": [
|
||||
{
|
||||
"name": "sendConfirmationFunction",
|
||||
"resource": "functionResourse"
|
||||
}
|
||||
],
|
||||
"states": [
|
||||
{
|
||||
"name":"SendConfirmationForEachCompletedhOrder",
|
||||
"type":"FOREACH",
|
||||
"inputCollection": "$.orders[?(@.completed == true)]",
|
||||
"inputParameter": "$.completedorder",
|
||||
"startsAt": "SendConfirmation",
|
||||
"states": [
|
||||
{
|
||||
"name":"SendConfirmation",
|
||||
"type":"OPERATION",
|
||||
"actionMode":"SEQUENTIAL",
|
||||
"actions":[
|
||||
{
|
||||
"functionref": {
|
||||
"refname": "sendConfirmationFunction",
|
||||
"parameters": {
|
||||
"orderNumber": "$.completedorder.orderNumber",
|
||||
"email": "$.completedorder.email"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": true
|
||||
}
|
||||
],
|
||||
"end": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
This ForEach state will first look at its inputCollection path to determine which array in the states data input
|
||||
to iterate over.
|
||||
In this case it will be "orders" array which contains orders information. The states inputCollection property
|
||||
then further filters this array, only selecting elements of the orders array which have the completed property
|
||||
set to true.
|
||||
|
||||
For each of the completed order the state will then execute the defined set of states in parallel.
|
||||
|
||||
For this example, the data inputs of staring states for the two itererations would be:
|
||||
|
||||
```json
|
||||
{
|
||||
"orders": [
|
||||
{
|
||||
"orderNumber": "1234",
|
||||
"completed": true,
|
||||
"email": "firstBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "5678",
|
||||
"completed": true,
|
||||
"email": "secondBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "9910",
|
||||
"completed": false,
|
||||
"email": "thirdBuyer@buyer.com"
|
||||
}
|
||||
],
|
||||
"completedorder": {
|
||||
"orderNumber": "1234",
|
||||
"completed": true,
|
||||
"email": "firstBuyer@buyer.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
and:
|
||||
|
||||
```json
|
||||
{
|
||||
"orders": [
|
||||
{
|
||||
"orderNumber": "1234",
|
||||
"completed": true,
|
||||
"email": "firstBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "5678",
|
||||
"completed": true,
|
||||
"email": "secondBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "9910",
|
||||
"completed": false,
|
||||
"email": "thirdBuyer@buyer.com"
|
||||
}
|
||||
],
|
||||
"completedorder": {
|
||||
"orderNumber": "5678",
|
||||
"completed": true,
|
||||
"email": "secondBuyer@buyer.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Once iterations over the completed orders complete, workflow execution finishes as our ForEach state is an end state (has the end property set to true).
|
||||
|
||||
So in this example, our ForEach state will send two confirmation emails, one for each of the completed orders
|
||||
defined in the orders array of its data input.
|
||||
|
||||
### Filter Definition
|
||||
|
||||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| inputPath | Input path (JSONPath) | string | yes |
|
||||
| resultPath | Result Path (JSONPath) | string | no |
|
||||
| outputPath | Output Path (JSONPath) | string | no |
|
||||
|
||||
| inputPath |Input path (JSONPath) | string | yes |
|
||||
| resultPath |Result Path (JSONPath) | string | no |
|
||||
| outputPath |Output Path (JSONPath) | string | no |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
|
@ -1637,121 +1955,7 @@ to test if your workflow behaves properly for the case when there are people who
|
|||
|
||||
</details>
|
||||
|
||||
Filters are used for managing workflow data flow.
|
||||
This is described in detail in the [Information Passing](#Information-Passing) section.
|
||||
|
||||
### Loop Definition
|
||||
|
||||
| Parameter | Description | Type | Required |
|
||||
| --- | --- | --- | --- |
|
||||
| inputCollection | Selects a collection of the states inputPath | string | yes |
|
||||
| outputCollection | Selects a collection of the states outputPath | string | no |
|
||||
| completionCondition | Boolean expression (evaluated after each iteration) that controls the loop. If this expression is true looping stops even if not all collection elements are processesd | string | no |
|
||||
| timeDelay | Amount of time (ISO 8601 format) to wait between each loop | string | no |
|
||||
|
||||
<details><summary><strong>Click to view JSON Schema</strong></summary>
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Defines state Looping Information",
|
||||
"properties": {
|
||||
"inputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath, selects a collection of the states inputPath"
|
||||
},
|
||||
"outputCollection": {
|
||||
"type": "string",
|
||||
"description": "JSONPath, selects a collection of the states outputPath"
|
||||
},
|
||||
"completionCondition": {
|
||||
"type": "string",
|
||||
"description": "Boolean expression (evaluated after each iteration) that controls the loop. If this expression is true looping stops even if not all collection elements are processesd."
|
||||
},
|
||||
"timeDelay": {
|
||||
"type": "string",
|
||||
"description": "|Amount of time (ISO 8601 format) to wait between each loop "
|
||||
}
|
||||
},
|
||||
"required": ["inputCollection"]
|
||||
}
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
Loop definition allows states to be executed in a loop until a completion condition becomes true.
|
||||
|
||||
Looping happens over each element of the inputCollection parameter. This parameter must evaluate to a collection
|
||||
of the states input data.
|
||||
|
||||
If the completionCondition expression is defined, this expression must be checked after each loop iteration.
|
||||
If it evaluates to true, looping must stop even if looping over all elements of the inputCollection have not finished.
|
||||
In addtion, the time delay property defines a wait period betwen each loop iteration.
|
||||
|
||||
If the state defines a result, the outputCollection parameter must resolve to a collection element of the states
|
||||
output data. After each iteration the state data result is added to the collection evaluated by this expression.
|
||||
|
||||
Once looping has completed the state may transition to the next state defined, or end the workflow in case of an end state.
|
||||
|
||||
Here is an example of an Operation state which sends a confirmation email for each completed sales order
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "Send order confirmation email",
|
||||
"description": "Send email for each confirmed order",
|
||||
"startsAt": "sendConfirmationEmail",
|
||||
"functions": [
|
||||
{
|
||||
"name": "sendConfirmationEmailFunction",
|
||||
"resource": "functionResourse"
|
||||
}
|
||||
],
|
||||
"states":[
|
||||
{
|
||||
"name":"sendConfirmationEmail",
|
||||
"type":"OPERATION",
|
||||
"actionMode":"SEQUENTIAL",
|
||||
"actions": [
|
||||
{
|
||||
"functionref": {
|
||||
"refname": "sendConfirmationEmailFunction"
|
||||
}
|
||||
}
|
||||
],
|
||||
"end": true,
|
||||
"loop": {
|
||||
"inputCollection": "$.orders[?(@.completed == true)]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The data input to the "sendConfirmationEmail" state could be for example:
|
||||
|
||||
```json
|
||||
{
|
||||
"orders": [
|
||||
{
|
||||
"orderNumber": "1234",
|
||||
"completed": true,
|
||||
"email": "firstBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "5678",
|
||||
"completed": true,
|
||||
"email": "secondBuyer@buyer.com"
|
||||
},
|
||||
{
|
||||
"orderNumber": "9910",
|
||||
"completed": false,
|
||||
"email": "thirdBuyer@buyer.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
in which case this state will loop two times for each of the completed orders.
|
||||
Filters are used for data flow through the workflow. This is described in detail in the [Information Passing](#Information-Passing) section.
|
||||
|
||||
### Transitions
|
||||
|
||||
|
|
Loading…
Reference in New Issue