Switch States Conditionally in a Flow
This procedure demonstrates how to implement a multi-state flow.
This sample code shows how to design a flow that checks for a resource and
updates it. If the resource doesn't exist, the flow creates a new resource.
- Open the adapter definition document in Visual Studio Code.
- In the
flows
code section of the document, add code for a flow with GET call to a specific resource.In the following code sample, the
httpInvoke
function implements the GET call."flows": { "EventRegisterFlow": { "id": "EventRegisterFlow", "description": "EventRegisterFlow", "specVersion": "0.8", "version": "0.1", "start": "startState", "functions": [ { "name": "httpInvoke", "type": "custom", "operation": "connectivity::rest" } ], "states": [ { "name": "startState", "type": "operation", "actions": [ { "name": "httpInvoke", "functionRef": { "refName": "retriveListOfSubscriptionFunc", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks\"}", "method": "GET", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" } } }, "actionDataFilter": { "results": "${ .body}", "toStateData": "${ .subscriptions }" } } ], "end": true } }
- Add actions to the flow to evaluate if a specific resource exists.
Sample code:
"functions": [ ... { "name": "SubscriptionExistsFunction", "operation": "[.integrationProperties.INTEGRATION_FLOW_URL==.subscriptions[].config.url]|any", "type": "expression" }, { "name": "getSubscriptionId", "type": "expression", "operation": "[{subscription:.subscriptions[], INTEGRATION_FLOW_URL:.integrationProperties.INTEGRATION_FLOW_URL}] | map(select(.subscription.config.url==.INTEGRATION_FLOW_URL))[0].subscription.id | tostring" } ], "states": [ { "name": "startState", "type": "operation", "actions": [ ... { "functionRef": "SubscriptionExistsFunction", "actionDataFilter": { "toStateData": "${ .subscriptionExists }" } }, { "functionRef": "getSubscriptionId", "actionDataFilter": { "toStateData": "${ .subscriptionId }" } } ], end: true }
- Add a switch state to transition to another state that can create or register a
resource.
Sample code:
"flows": { "EventRegisterFlow": { "id": "EventRegisterFlow", "description": "EventRegisterFlow", "specVersion": "0.8", "version": "0.1", "start": "startState", "functions": [ ... ], "states": [ { "name": "startState", "type": "operation", "actions": [ ... ], "transition": "SwitchBasedOnSubscription" }, { "name": "SwitchBasedOnSubscription", "type": "switch", "dataConditions": [ { "condition": "${ .subscriptionExists == true }", "transition": "UpdateRepositoryEndpoint" }, { "condition": "${ .subscriptionExists == false }", "transition": "RegisterRepositoryEvent" } ], "defaultCondition": { "transition": "RegisterRepositoryEvent" } }, }
- Add termination states that branch from a switch.
The termination states contain the required actions.
Sample code:
"flows": { "EventRegisterFlow": { "id": "EventRegisterFlow", "description": "EventRegisterFlow", "specVersion": "0.8", "version": "0.1", "start": "startState", "functions": [ ... ], "states": [ { "name": "startState", "type": "operation", "actions": [ ... ], "transition": "SwitchBasedOnSubscription" }, { "name": "SwitchBasedOnSubscription", "type": "switch", "dataConditions": [ { "condition": "${ .subscriptionExists == true }", "transition": "UpdateRepositoryEndpoint" }, { "condition": "${ .subscriptionExists == false }", "transition": "RegisterRepositoryEvent" } ], "defaultCondition": { "transition": "RegisterRepositoryEvent" } }, { "name": "UpdateRepositoryEndpoint", "type": "operation", "actions": [ { "name": "UpdateRepositoryEnpointAction", "functionRef": { "refName": "httpInvoke", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks/{subscriptionId}\"}", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" "subscriptionId": "${ .subscriptionId }" }, "method": "POST", "body": "${ { \"name\": \"web\", \"active\": true, \"events\": [.configuration.eventName] } }" } }, "actionDataFilter": { "results": "${.body}", "toStateData": "${ .output }" }, "condition": "${ .subscriptionExists==true }" } ], "end": true }, { "name": "RegisterRepositoryEvent", "type": "operation", "actions": [ { "name": "RepositoryEventRegisterAction", "functionRef": { "refName": "httpInvoke", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks\"}", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" "subscriptionId": "${ .subscriptionId }" }, "method": "POST", "body": "${ { \"name\": \"web\", \"active\": true, \"events\": [.configuration.eventName], \"config\": { \"content_type\": \"json\", \"secret\": .connectionProperties.\"trigger.secret\", \"url\": .integrationProperties.INTEGRATION_FLOW_URL } } }" } }, "actionDataFilter": { "results": "${.body}", "toStateData": "${ .output }" }, "condition": "${ .subscriptionExists==false }" } ], "end": true } ] }, }
Complete sample code:
"flows": { "EventRegisterFlow": { "id": "EventRegisterFlow", "description": "EventRegisterFlow", "specVersion": "0.8", "version": "0.1", "start": "startState", "functions": [ { "name": "httpInvoke", "type": "custom", "operation": "connectivity::rest" }, { "name": "SubscriptionExistsFunction", "operation": "[.integrationProperties.INTEGRATION_FLOW_URL==.subscriptions[].config.url]|any", "type": "expression" }, { "name": "getSubscriptionId", "type": "expression", "operation": "[{subscription:.subscriptions[], INTEGRATION_FLOW_URL:.integrationProperties.INTEGRATION_FLOW_URL}] | map(select(.subscription.config.url==.INTEGRATION_FLOW_URL))[0].subscription.id | tostring" } ], "states": [ { "name": "startState", "type": "operation", "actions": [ { "name": "httpInvoke", "functionRef": { "refName": "retriveListOfSubscriptionFunc", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks\"}", "method": "GET", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" } } }, "actionDataFilter": { "results": "${ .body}", "toStateData": "${ .subscriptions }" } }, { "functionRef": "SubscriptionExistsFunction", "actionDataFilter": { "toStateData": "${ .subscriptionExists }" } }, { "functionRef": "getSubscriptionId", "actionDataFilter": { "toStateData": "${ .subscriptionId }" } } ], "transition": "SwitchBasedOnSubscription" }, { "name": "SwitchBasedOnSubscription", "type": "switch", "dataConditions": [ { "condition": "${ .subscriptionExists == true }", "transition": "UpdateRepositoryEndpoint" }, { "condition": "${ .subscriptionExists == false }", "transition": "RegisterRepositoryEvent" } ], "defaultCondition": { "transition": "RegisterRepositoryEvent" } }, { "name": "UpdateRepositoryEndpoint", "type": "operation", "actions": [ { "name": "UpdateRepositoryEnpointAction", "functionRef": { "refName": "httpInvoke", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks/{subscriptionId}\"}", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" "subscriptionId": "${ .subscriptionId }" }, "method": "POST", "body": "${ { \"name\": \"web\", \"active\": true, \"events\": [.configuration.eventName] } }" } }, "actionDataFilter": { "results": "${.body}", "toStateData": "${ .output }" }, "condition": "${ .subscriptionExists==true }" } ], "end": true }, { "name": "RegisterRepositoryEvent", "type": "operation", "actions": [ { "name": "RepositoryEventRegisterAction", "functionRef": { "refName": "httpInvoke", "arguments": { "uri": "${\"https:/\"+\"/\"+.connectionProperties.hostNameTrigger+\"/repos/{owner}/{repo}/hooks\"}", "parameters": { "owner": "${ .configuration.orgId }", "repo": "${ .configuration.repositoryId }" "subscriptionId": "${ .subscriptionId }" }, "method": "POST", "body": "${ { \"name\": \"web\", \"active\": true, \"events\": [.configuration.eventName], \"config\": { \"content_type\": \"json\", \"secret\": .connectionProperties.\"trigger.secret\", \"url\": .integrationProperties.INTEGRATION_FLOW_URL } } }" } }, "actionDataFilter": { "results": "${.body}", "toStateData": "${ .output }" }, "condition": "${ .subscriptionExists==false }" } ], "end": true } ] }, }