VRO: Workflow Design

3 minute read

Description:

Inside vRealize Orchestrator when you build a workflow, there are a couple of things I have learned that make the job easier:

  1. Keep a consistent name for variables and their respective Inventory hosts and operations

  2. Add default error handler elements and have them catch errors that your workflow throws:

    • So on the workflow schema, instead of your regular Start => Scriptable Taks => End, you will now have two rows:
    • Start => Scriptable Taks => End
    • Default error handler => Scriptable Taks => End
    • Pic:

    trap-error

To Resolve

  1. On the scripting element, add an output variable of “strError”

  2. Then drag and drop a “Default error handler” element and choose “strError” as the default ‘Output exception binding’

  3. Drag and drop a new scriptable task and insert it between the error handler and the automatically placed ‘end’ element.

    • Make sure to bind “strError” to its input parameters.

    • In the scriptable task Scripting pane, type out:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    //System.log("error is: " + strError)
    var strVerbiage = "Currently there are no requests in the queue"
    var strSplit = strError.split("(")
    var strErrorVerbiage = strSplit[0].trim();
    if (strErrorVerbiage == strVerbiage) {
       System.log("this error was trapped successfully")
    }
    else
    {
       System.log("this error was NOT trapped successfully: " + strErrorVerbiage)
    }
    
    • Make sure you have what you want strVerbiage to be in your main script as a thow statement. For example:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    try {
       // This will cause the workflow to error when there are 0 tickets.
       var requestNumber = openRequests["result"][0]["number"]
       System.log("Request Number: " + requestNumber)
    }
    catch (e) {
       strError = "Currently there are no requests in the queue"
       throw "Currently there are no requests in the queue"
    }
    
  4. Run the workflow again and you will see that it will throw an error, and then this element will still allow the workflow to complete successfully.

  5. For making sure variables are consistent, I add keep a variables.md file that I reference and copy what is needed to the top of my workflows in a multiline comment:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    
    /*
    
    Purpose: This workflow will connect to Service Now and parse new requests of a certain type, extract information, and send the information to software for approval. It then records this information for another workflow to pick up.
    
    Add Variables to workflow:
    { 
       "variable-name": "snGetRequest", 
       "type": "REST:RESTOperation", 
       "value": "SERVICE_NOW - getRequest: GET api/now/table/",
       "rest-host": "SERVICE_NOW: https://test.service-now.com/"
    }
    { 
       "variable-name": "snPutRequest", 
       "type": "REST:RESTOperation", 
       "value": "SERVICE_NOW - putRequest: PUT api/now/table/sc_request/", 
       "data-type": "application/json",
       "rest-host": "SERVICE_NOW: https://test.service-now.com/"
    }
    { 
       "variable-name": "softwareGetUserInfo", 
       "type": "REST:RESTOperation", 
       "value": "SOME_SOFTWARE - getSpecificUser: GET api/users?q={id}",
       "rest-host": "SOME_SOFTWARE: https://somehost.domain.com/"
    }
    { 
       "variable-name": "softwareGetRequests", 
       "type": "REST:RESTOperation", 
       "value": "SOME_SOFTWARE - getUserRequests: GET api/requests",
       "rest-host": "SOME_SOFTWARE: https://somehost.domain.com/"
    }
    { 
       "variable-name": "softwarePostToken", 
       "type": "REST:RESTOperation", 
       "value": "SOME_SOFTWARE - postToken: POST /api/oauth2/token", 
       "data-type": "application/x-www-form-urlencoded",
       "rest-host": "SOME_SOFTWARE: https://somehost.domain.com/"
    }
    { 
       "variable-name": "softwarePostRequest", 
       "type": "REST:RESTOperation", 
       "value": "SOME_SOFTWARE - postRequest: POST api/request", 
       "data-type": "application/json",
       "rest-host": "SOME_SOFTWARE: https://somehost.domain.com/"
    }
    { 
       "variable-name": "rscTask", 
       "type": "ResourceElement", 
       "value": "my-json-file.txt",
       "rest-host": "VRO_RESOURCE_ELEMENTS"
    }
    { 
       "variable-name": "softwarePostTokenRevoke", 
       "type": "REST:RESTOperation", 
       "value": "SOME_SOFTWARE - postTokenRevoke: POST /api/oauth2/revoke", 
       "data-type": "application/x-www-form-urlencoded",
       "rest-host": "SOME_SOFTWARE: https://somehost.domain.com/"
    }
    */
    
    • Each of these variables are added to the workflows variables tab and again in the scriptable tasks as input variables. They are then called in my javascript code to perform operations (REST API calls). Responses are usually stored and recorded in its own json file and passed between workflows.

Comments