Pre and Post Processing Expressions and Multiple Outbound Requests

This procedure shows how to implement a flow with pre or post processing expressions, and multiple outbound requests.

The sample code shows how to:

  • Pre-processes a task and build tenant information.
  • Makes multiple outbound requests.
  • Pre-processes the output to make a final request.
  • Merges the output of two requests as a post-processing operation.
  1. Open the adapter definition document in Visual Studio Code.
  2. Locate the flows code section of the document.
  3. Define a flow with a single state of type operation. For outbound calls, add function of type custom, operation connectivity::rest, and a unique name.
    Sample code:
    "flows": {   
        "compartmentIdFlow" :      {
          "id": "compartmentIdFlow",
          "description": "compartmentIdFlow",
          "specVersion": "0.8",
          "version": "0.1",
          "start": "startState",
          "functions": [
             {
              "name": "generalRestFunc",
              "type": "custom",
              "operation": "connectivity::rest"
            }
             
          ],
          "states": [
            {
              "actions": [
                
              ],
              "name": "startState",
              "type": "operation",
              "end": true
            }
          ]
        }
    }
  4. Add a function definition in the flow and refer the function defined from first action in state.

    The pre-processing operation involves extraction of the tenantId from the configuration or connection properties based on a condition.

    Sample code:

    "functions": [
            {
              "name": "generalRestFunc",
              "type": "custom",
              "operation": "connectivity::rest"
            },
            {
              "name": "getTenantId",
              "type": "expression",
              "operation": "if .configuration.tenantId then .configuration.tenantId else .connectionProperties.TenancyOCID end"
            }
    ]
    ...
     "states":[
            {
              "name":"startState",
              "type":"operation",
              "actions":[
                {
                  "functionRef": "getTenantId",
                  "actionDataFilter": {
                    "toStateData": "${ .configuration.tenantId }"
                  }
                }
            ]
  5. For outbound invokes, add two more actions to the outbound invocation. The first invoke retrieves the resourceId for the identified tenant. The second invoke retrieves the sub-reources id from the identified tenant.

    Sample code:

    "actions":[
               {
                 "functionRef": "getTenantId",
                 "actionDataFilter": {
                   "toStateData": "${ .configuration.tenantId }"
                 }
               },
               {
                 "functionRef": {
                   "refName": "generalRestFunc",
                   "arguments": {
                     "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments/\" + .configuration.tenantId }",
                     "method": "GET"
                   }
                 },
                 "actionDataFilter": {
                   "results": "${ {keyName:.body.id, displayName:.body.name} }",
                   "toStateData": "${ .rootCompartment }"
                 }
               },
               {
                 "functionRef": {
                   "refName": "generalRestFunc",
                   "arguments": {
                     "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments\" }",
                     "method": "GET",
                     "parameters": {
                       "compartmentId": "${ .configuration.tenantId }",
                       "lifecycleState": "ACTIVE",
                       "compartmentIdInSubtree": true
                     }
                   }
                 },
                 "actionDataFilter": {
                   "results": "${ .body | map({keyName:.id, displayName:.name}) }",
                   "toStateData": "${ .childCompartments }"
                 }
               }
      ]
  6. As part of post- processing operation, merge the output of the two invokes.

    Sample code:

    "functions": [
            {
              "name": "generalRestFunc",
              "type": "custom",
              "operation": "connectivity::rest"
            },
            {
              "name": "getTenantId",
              "type": "expression",
              "operation": "if .configuration.tenantId then .configuration.tenantId else .connectionProperties.TenancyOCID end"
            },
            {
              "name": "mergeTenantsList",
              "type": "expression",
              "operation": "[.rootCompartment] + .childCompartments"
            }
          ]
    ...
     "states":[
            {
              "name":"startState",
              "type":"operation",
              "actions":[
                {
                  "functionRef": "getTenantId",
                  "actionDataFilter": {
                    "toStateData": "${ .configuration.tenantId }"
                  }
                },
                {
                  "functionRef": {
                    "refName": "generalRestFunc",
                    "arguments": {
                      "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments/\" + .configuration.tenantId }",
                      "method": "GET"
                    }
                  },
                  "actionDataFilter": {
                    "results": "${ {keyName:.body.id, displayName:.body.name} }",
                    "toStateData": "${ .rootCompartment }"
                  }
                },
                {
                  "functionRef": {
                    "refName": "generalRestFunc",
                    "arguments": {
                      "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments\" }",
                      "method": "GET",
                      "parameters": {
                        "compartmentId": "${ .configuration.tenantId }",
                        "lifecycleState": "ACTIVE",
                        "compartmentIdInSubtree": true
                      }
                    }
                  },
                  "actionDataFilter": {
                    "results": "${ .body | map({keyName:.id, displayName:.name}) }",
                    "toStateData": "${ .childCompartments }"
                  }
                },
                {
                  "functionRef": "mergeTenantsList",
                  "actionDataFilter": {
                    "toStateData": "${ .output }"
                  }
                }
              ],
              "end": true
            }
          ]
        }
    }

Complete sample code:

"flows": {   
   "compartmentIdFlow" :      {
      "id": "compartmentIdFlow",
      "description": "compartmentIdFlow",
      "specVersion": "0.8",
      "version": "0.1",
      "start": "startState",
      "functions": [
        {
          "name": "generalRestFunc",
          "type": "custom",
          "operation": "connectivity::rest"
        },
        {
          "name": "getTenantId",
          "type": "expression",
          "operation": "if .configuration.tenantId then .configuration.tenantId else .connectionProperties.TenancyOCID end"
        },
        {
          "name": "mergeTenantsList",
          "type": "expression",
          "operation": "[.rootCompartment] + .childCompartments"
        }
      ],
      "states":[
        {
          "name":"startState",
          "type":"operation",
          "actions":[
            {
              "functionRef": "getTenantId",
              "actionDataFilter": {
                "toStateData": "${ .configuration.tenantId }"
              }
            },
            {
              "functionRef": {
                "refName": "generalRestFunc",
                "arguments": {
                  "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments/\" + .configuration.tenantId }",
                  "method": "GET"
                }
              },
              "actionDataFilter": {
                "results": "${ {keyName:.body.id, displayName:.body.name} }",
                "toStateData": "${ .rootCompartment }"
              }
            },
            {
              "functionRef": {
                "refName": "generalRestFunc",
                "arguments": {
                  "uri": "${ \"https://identity.\" + .connectionProperties.region + \".oraclecloud.com/20160918/compartments\" }",
                  "method": "GET",
                  "parameters": {
                    "compartmentId": "${ .configuration.tenantId }",
                    "lifecycleState": "ACTIVE",
                    "compartmentIdInSubtree": true
                  }
                }
              },
              "actionDataFilter": {
                "results": "${ .body | map({keyName:.id, displayName:.name}) }",
                "toStateData": "${ .childCompartments }"
              }
            },
            {
              "functionRef": "mergeTenantsList",
              "actionDataFilter": {
                "toStateData": "${ .output }"
              }
            }
          ],
          "end": true
        }
      ]
    }
}