Introduction

  • Any operations that can be performed on orders, workflows, jobs and related objects such as cancelling, suspending and resuming orders are performed by the JS7 - REST Web Service API.
  • In addition, a PowerShell module is available for simplified access to the REST Web Service API. This is described in the JS7 - PowerShell Module article.
  • The REST Web Service API can also be accessed from Shell utilities such as curl. 

Usage

  • The REST Web Service API is called by using a HTTP client that sends JSON based requests and receives JSON based responses.
  • The following REST Web Service API requests are available:
  • Requirements
    • REST Web Service API requests should use HTTP POST or GET operations as indicated.
    • Should the idle timeout between two web service requests exceed the JOC Cockpit session timeout then a login has to be performed, see the JS7 - Settings article for more information.

Examples for Curl

  • Example: Get the list of orders scheduled until a given date.
    • The attached example order_list_sample.sh is for use with curl. We do not consider curl to be perfect for handling web service requests. However, it shows the building blocks:
      • Example for use with curl to get list of orders scheduled until a given date
        #!/bin/sh
        # ----------------------------------------
        # Protocol, host and port of JOC Cockpit
        JS7_URL="http://localhost:7446"
        
        # Identification of JS7 instance
        JS7_CONTROLLER_ID="testsuite"
        
        # Date up to that scheduled orders are returned
        JS7_DATETO="+1d"
        
        # Base64 encoded string "user:password" for authentication. The below string represents "root:root"
        JS7_BASIC_AUTHENTICATION="`echo "root:root" | base64`"
        JS7_BASIC_AUTHENTICATION="${JS7_BASIC_AUTHENTICATION:0:${#JS7_BASIC_AUTHENTICATION}-4}"
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Perform login
        echo ""
        echo "PERFORMING LOGIN"
        JS7_JSON="`curl -k -s -S -X POST -i -m 15 -H "Authorization: Basic $JS7_BASIC_AUTHENTICATION" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/login`"
        JS7_ACCESS_TOKEN=$(echo $JS7_JSON | grep -Po '"accessToken":.*?[^\\]"' | awk -F ':' '{print $2}' | tr -d \" )
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Get the list of orders for a date range
        echo ""
        echo "Get the list of orders for date range: $JS7_DATETO"
        # Execute web service request
        JS7_REST_BODY="{ \"controllerId\": \"$JS7_CONTROLLER_ID\", \"compact\": true, \"dateTo\": \"$JS7_DATETO\" }"
        JS7_JSON="`curl -k -s -S -X POST -d "$JS7_REST_BODY" -i -m 15 -H "X-Access-Token: $JS7_ACCESS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/xml" $JS7_URL/joc/api/orders`"
        echo $JS7_JSON
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Perform logout
        echo ""
        echo "PERFORMING LOGOUT"
        curl -k -s -S -X POST -i -m 15 -H "X-Access-Token: $JS7_ACCESS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/logout
        # -----------------------------------------
        echo ""
        
      • Explanations

        • Line 4: Depending on your JOC Cockpit installation the protocol will be http or https. The default port is 4446 but might have been modified during setup.
        • Line 7: The Controller ID is specified during installation of the Controller and identifies a Controller standalone instance or a Controller cluster.
        • Line 10: Specify the relative date up to which you want the list of scheduled orders to be returned.
        • Line 13, 14: Default credentials after installation include the account "root" and password "root". The credentials might have been changed after setup of the JOC Cockpit.
        • Line 22: Note the use of Basic HTTP authentication
        • Line 23: The request to the /authentication/login web service returns an access token which is used with further requests.
        • Line 32, 33: Note the JSON body created for the request and the URL including the path /joc/api/orders used to return order information.
        • Line 42: Always perform a logout and consider the session idle timeout.


  • Example: Suspend an order.
    • The attached example order_suspend_sample.sh is for use with curl. We do not consider curl to be perfectly prepared to handle web service requests, however, it shows the building blocks:
      • Example for use with curl to suspend an order
        #!/bin/sh
        # ----------------------------------------
        # Protocol, host and port of JOC Cockpit
        JS7_URL="http://localhost:7446"
        
        # Identification of JS7 instance
        JS7_CONTROLLER_ID="testsuite"
        
        # ID of order that should be suspended
        JS7_ORDER_ID="#2021-03-20#T6232717382-root"
        
        # Base64 encoded string "user:password" for authentication. The below string represents "root:root"
        JS7_BASIC_AUTHENTICATION="`echo "root:root" | base64`"
        JS7_BASIC_AUTHENTICATION="${JS7_BASIC_AUTHENTICATION:0:${#JS7_BASIC_AUTHENTICATION}-4}"
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Perform login
        echo ""
        echo "PERFORMING LOGIN"
        JS7_JSON="`curl -k -s -S -X POST -i -m 15 -H "Authorization: Basic $JS7_BASIC_AUTHENTICATION" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/login`"
        JS7_ACCESS_TOKEN=$(echo $JS7_JSON | grep -Po '"accessToken":.*?[^\\]"' | awk -F ':' '{print $2}' | tr -d \" )
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Suspend a specific order identified by its ID
        echo ""
        echo "SUSPENDING ORDER WITH ID: $JS7_ORDER_ID"
        JS7_REST_BODY="{ \"controllerId\": \"$JS7_CONTROLLER_ID\", \"orderIds\": [ \"$JS7_ORDER_ID\" ] }"
        echo "Request Body: $JS7_REST_BODY"
        # Execute web service request
        curl -k -s -S -X POST -d "$JS7_REST_BODY" -i -m 15 -H "X-Access-Token: $JS7_ACCESS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/orders/suspend
        echo ""
        echo ""
        echo "... sleep 3 seconds to check results"
        sleep 3
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Get order state information
        echo ""
        echo "GETTING STATE INFORMATION FOR ORDER WITH ID: $JS7_ORDER_ID"
        # Execute web service request
        JS7_REST_BODY="{ \"controllerId\": \"$JS7_CONTROLLER_ID\", \"compact\": true, \"orderIds\": [ \"$JS7_ORDER_ID\" ] }"
        JS7_JSON="`curl -k -s -S -X POST -d "$JS7_REST_BODY" -i -m 15 -H "X-Access-Token: $JS7_ACCESS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/xml" $JS7_URL/joc/api/orders`"
        echo "Request Body: $JS7_REST_BODY"
        echo $JS7_JSON
        # -----------------------------------------
        
        
        # -----------------------------------------
        # Perform logout
        echo ""
        echo "PERFORMING LOGOUT"
        curl -k -s -S -X POST -i -m 15 -H "X-Access-Token: $JS7_ACCESS_TOKEN" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/logout
        # -----------------------------------------
        echo ""
        
    • Explanations
      • Line 31: Suspending an order includes specifying the Controller ID and an array of order IDs..
      • Line 38: The operation to suspend an order works asynchronously as the request is forwarded to the Controller and from the Controller to the Agent that holds the order. More elaborate solutions to wait for completion of an suspend operation than just waiting a few seconds include repeated checking the order state.
      • Line 47: The request to retrieve the order state information is sent to the /joc/api/orders URL.
      • Line 58: Always perform a logout and consider the session idle timeout.
  • Example: Run test cases for a number of orders.
    • The attached example invoke_testrun.sh is for use with curl. We do not consider curl to be perfectly prepared to handle web service requests, however, it shows the building blocks.
    • The script can be parameterized to run a number of orders for a given set of workflows.
      • Example for use with curl to run a number of orders for a given set of workflows
        #!/bin/bash
        
        # ----------------------------------------
        # JS7 Test Test Case Invocation
        # ----------------------------------------
        
        # Examples
        #   ./invoke_testrun.sh --url=http://joc-2-0-primary:7446 --id=testsuite --time-zone=Europe/Berlin --count=1 --workflows=/TestRuns/Test0000000070/tcpForkBalanced_001,/TestRuns/Test0000000070/tcpForkNestedLevel1_001
        #   ./invoke_testrun.sh --url=https://joc-2-0-primary:7443 --cacert=./certs/root-ca.crt --account=root --password=root --id=testsuite --time-zone=Europe/Berlin --workflows=/TestRuns/Test0000000070/tcpForkBalanced_001,/TestRuns/Test0000000070/tcpForkNestedLevel1_001 --batch-size=10 --count=1
        
        # Protocol, host and port of JOC Cockpit
        JS7_URL="http://localhost:4446"
        
        # CA certificate for TLS/SSL connection
        JS7_CACERT=""
        
        # Account and password if no client authentication certificate is used
        JS7_ACCOUNT="root"
        JS7_PASSWORD="root"
        
        # Identification of JS7 Controller
        JS7_CONTROLLER_ID=""
        
        # Number of test runs, number of orders per batch in a test run, test case directory and workflow paths
        JS7_TEST_COUNT=1
        JS7_TEST_BATCH_SIZE=100
        JS7_TEST_CASE_WORKFLOWS=()
        
        JS7_TEST_CASE_SCHEDULED_FOR="now"
        JS7_TEST_CASE_TIME_ZONE="Etc/UTC"
        
        JS7_VERBOSE=0
        
        # ----------------------------------------
        for option in "$@"
        do
          case "$option" in
                 -v)                 JS7_VERBOSE=1
                                     ;;
                 --url=*)            JS7_URL=`echo "$option" | sed 's/--url=//'`
                                     ;;
                 --cacert=*)         JS7_CACERT=`echo "$option" | sed 's/--cacert=//'`
                                     ;;
                 --account=*)        JS7_ACCOUNT=`echo "$option" | sed 's/--account=//'`
                                     ;;
                 --password=*)       JS7_PASSWORD=`echo "$option" | sed 's/--password=//'`
                                     ;;
                 --id=*)             JS7_CONTROLLER_ID=`echo "$option" | sed 's/--id=//'`
                                     ;;
                 --count=*)          JS7_TEST_COUNT=`echo "$option" | sed 's/--count=//'`
                                     ;;
                 --batch-size=*)     JS7_TEST_BATCH_SIZE=`echo "$option" | sed 's/--batch-size=//'`
                                     ;;
                 --workflows=*)      JS7_TEST_CASE_WORKFLOWS=(`echo "$option" | sed 's/--workflows=//' | sed -r 's/[,]+/ /g'`)
                                     ;;
                 --scheduled-for=*)  JS7_TEST_CASE_SCHEDULED_FOR=`echo "$option" | sed 's/--scheduled-for=//'`
                                     ;;
                 --time-zone=*)      JS7_TEST_CASE_TIME_ZONE=`echo "$option" | sed 's/--time-zone=//'`
                                     ;;
                 *)                  echo "unknown argument: $option"
                                     exit 1
                                     ;;
          esac
        done
        
        # -----------------------------------------
        JS7_Login()
        {
            echo -e "\n"
            echo "PERFORMING LOGIN"
        
            # Base64 encoded string "user:password" for authentication. The below string represents "root:root"
            js7_basic_authentication="`echo "$JS7_ACCOUNT:$JS7_PASSWORD" | base64`"
            js7_basic_authentication="${js7_basic_authentication:0:${#js7_basic_authentication}-4}"
        
            js7_curl_options=(-k -s -S -X POST -i -m 15)
            if [ "$JS7_CACERT" != "" ]
            then
                js7_curl_options+=(--cacert $JS7_CACERT)
            fi
        
            if [ $JS7_VERBOSE -ne 0 ]
            then
                echo "curl ${js7_curl_options[@]} -H \"Authorization: Basic $js7_basic_authentication\" -H \"Accept: application/json\" -H \"Content-Type: application/json\" $JS7_URL/joc/api/authentication/login"
            fi
        
            js7_json="`curl ${js7_curl_options[@]} -H "Authorization: Basic $js7_basic_authentication" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/login`"
            rc=$?
        
            if [ $rc -eq 0 ]
            then
                js7_access_token=$(echo $js7_json | grep -Po '"accessToken":.*?[^\\]"' | awk -F ':' '{print $2}' | tr -d \" )
                if [ $JS7_VERBOSE -ne 0 ]
                then
                    echo -e "Response:\n$js7_json"
                fi
            else
                echo "ERROR OCCURRED: $rc"
                echo $js7_json
                exit $rc
            fi
        
            js7_access_token=$(echo $js7_json | grep -Po '"accessToken":.*?[^\\]"' | awk -F ':' '{print $2}' | tr -d \" )
        }
        
        # -----------------------------------------
        JS7_Logout()
        {
            rc=$?
            echo -e "\n"
        
            if [ "$js7_access_token" != "" ]
            then
                echo "PERFORMING LOGOUT"
                js7_curl_options=(-k -s -S -X POST -i -m 15)
                if [ "$JS7_CACERT" != "" ]
                then
                    js7_curl_otions+=(--cacert $JS7_CACERT)
                fi
        
                js7_json="`curl ${js7_curl_options[@]} -H "X-Access-Token: $js7_access_token" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/authentication/logout`"
                exit_code=$?
        
                if [ $exit_code -eq 0 ]
                then
                    js7_access_token=""
                    if [ $JS7_VERBOSE -ne 0 ]
                    then
                        echo -e "Response:\n$js7_json"
                    fi
                else
                    echo "ERROR OCCURRED: $exit_code"
                    echo $js7_json
                fi
                echo -e "\n"
            fi
        
            exit $rc
        }
        
        # -----------------------------------------
        JS7_AddOrder()
        {
            echo -e "\n"
            js7_order_count=0
        
            for i in $(seq 1 $JS7_TEST_COUNT)
            do
                for workflow in ${JS7_TEST_CASE_WORKFLOWS[@]}
                do
                    echo "ADDING ORDERS TO WORKFLOW: count=$i batch-size=$JS7_TEST_BATCH_SIZE workflow=$workflow"
                    js7_rest_body="{ \"controllerId\": \"$JS7_CONTROLLER_ID\", \"orders\": [ "
        
                    for j in $(seq 1 $JS7_TEST_BATCH_SIZE)
                    do
                        js7_order_count=$((js7_order_count+1))
                        js7_rest_body="$js7_rest_body { \"workflowPath\":\"$workflow\", \"orderName\":\"$RANDOM\", \"scheduledFor\":\"$JS7_TEST_CASE_SCHEDULED_FOR\", \"timeZone\":\"$JS7_TEST_CASE_TIME_ZONE\" } "
                        if [ $j -lt $JS7_TEST_BATCH_SIZE ]
                        then
                            js7_rest_body="$js7_rest_body,"
                        fi
                    done
        
                    js7_rest_body="$js7_rest_body ] }"
        
                    if [ $JS7_VERBOSE -ne 0 ]
                    then
                        echo "Request Body:\n$js7_rest_body"
                    fi
        
                    # Execute web service request
                    js7_curl_options=(-k -s -S -X POST -i -m 15)
                    if [ "$JS7_CACERT" != "" ]
                    then
                        js7_curl_options+=(--cacert $JS7_CACERT)
                    fi
        
                    js7_json="`curl ${js7_curl_options[@]} -d "$js7_rest_body" -H "X-Access-Token: $js7_access_token" -H "Accept: application/json" -H "Content-Type: application/json" $JS7_URL/joc/api/orders/add`"
                    rc=$?
        
                    if [ $rc -eq 0 ]
                    then
                        if [ $JS7_VERBOSE -ne 0 ]
                        then
                            echo -e "Response:\n$js7_json"
                        fi
                    else
                        echo "ERROR OCCURRED: exit code $rc"
                        echo -e "Response:\n$js7_json"
                        exit $rc
                    fi
        
                    echo -e "orders added: $js7_order_count"
                done
            done
        }
        
        # -----------------------------------------
        
        trap 'JS7_Logout EXIT' EXIT
        trap 'JS7_Logout SIGTERM' SIGTERM
        trap 'JS7_Logout SIGINT' SIGINT
        
        JS7_Login
        JS7_AddOrder
        JS7_Logout
        
        # -----------------------------------------
  • Find a more elaborate example from the JS7 - How to update a Job Resource using the REST Web Service API from the Shell article.