Step 3: Define a task in the workflow
After you create a form, you can proceed to define how it will be employed by the workflow. The workflow that will serve as
an example consists in a simple action: checking applicant age using the guided task feature and then rejecting or accepting
an application based on the provided input. In the workflow definition, let's start by setting up the events parameter with
the data of the form we created.
"events": [
{
"kind": "consumed",
"name": "cwm.forms.Check_applicant_age",
"type": "cwm.forms.Check_applicant_age",
"source": "system.internal.cwm"
}
],
The key values here are:
-
kind
: The event is consumed
, since the input provided in the task is treated as external and will be consumed by the workflow.
-
name
: It's the Form ID which you can find in the form details when selecting it from the Forms list.
-
type
: It takes the same value as the name
key.
-
source
: It needs to be system.internal.cwm
as the source
Next, we want to enter a callback
state into the workflow and refer to the event (the form ID) that it will use to invoke the task.
"states": [
{
"name": "start",
"type": "callback",
"action": {
"name": "no operation",
"functionRef": {
"refName": "noop",
"arguments": {}
}
},
"eventRef": "cwm.forms.Check_applicant_age",
"metadata": {
"formData": "${ {user : .user} }",
"taskName": "Provide applicant age"
},
"timeouts": {
"eventTimeout": "PT15S",
"stateExecTimeout": "PT15M",
"actionExecTimeout": "PT15S"
},
"transition": "evaluate"
},
...
]
The callback state requires the action
parameter to be stated. The name
and functionRef
keys need to have values provided even if no action is expected to happen during this state. Therefore, a mock action needs
to be provided. For this, you can use a utility function, like noOp
, or any activity of your custom adapter, but keep in mind that the action needs to complete successfully for the workflow
to pass to another step.
The key values here are:
The next state in the example workflow is a switch state. It is where you provide conditions for the task input. If the age of the applicant is stated to be under 18, the application
is rejected. If it is 18 or more, the application is approved.
{
"name": "evaluate",
"type": "switch",
"dataConditions": [
{
"name": "adult",
"condition": "${ .provideApplicantAge = 18 }",
"transition": "approve"
},
{
"name": "underage",
"condition": "${ .provideApplicantAge 18 }",
"transition": "reject"
}
],
"defaultCondition": {
"transition": "reject"
}
},
The key value here is condition
. Here is where you refer to the Property name of the component that you can find under the API tab inside the component. The component property name needs to be referred to inside a jq expression that starts with $
. The condition is stated in form of an inequality: .provideApplicantAge = 18
.
The last two states would be the inject states where the workflow either accepts or rejects the application and prints the
result in the job execution logs.
{
"end": true,
"data": {
"application": "approved"
},
"name": "approve",
"type": "inject"
},
{
"end": true,
"data": {
"application": "rejected"
},
"name": "reject",
"type": "inject"
}