Using Process Cloud Service REST API Part 1

The Process Cloud Service (PCS) REST API provides an avenue to build UI components for workflow applications based on PCS. The versatility that comes with REST enables modern web application frameworks and just as easily, mobile applications. The API documentation is available here. Notice the endpoints are organized into eight categories. We’ll be focusing on the process and task categories.API-categories

Exploring the API

The API documentation contains samples using cURL which is useful for ad hoc command line calls. More comprehensive and easier to use tools like Postman and SoapUI are recommended. The PCS REST API WADL (Web Application Description Language) is available and can be imported into a Postman collection or SoapUI project. Most modern browsers such as Chrome, Firefox, Microsoft Internet Explorer and Edge have developer tools that can be useful when debugging web applications with REST calls.

A Simple PCS Application

In order to explore the API we will need a simple PCS application with a basic workflow and task form. We’ll build a workflow with a message start which means it will have a SOAP Web Service binding. We’ll create a string parameter on the binding and pass that incoming string to a submit task, then to an approve task and end the flow.

simple-workflow

PCS Composer

Login to PCS and select Develop Processes from the row of buttons on the welcome page.

PCS-welcome

that will take you to PCS Composer where you can select Create New Application

CreateApplication name the application APItest1 ApplicationName Create a new “message start” process MessageStart name the process APItestProc ProcessName The process modeler opens where you can drop activities in swimlanes, route flow lines and set data associations. We need a simple process data object to contain the string value passed in the starting message. Click the Data Objects button

CreateDataObject and add a new process data object named doSimpleString of type string.

doSimpleString

Open the property sheet for the Start event

StartProperties

and select Define Interface to add the string parameter.

DefineInterface

Name the argument argInputString and click OK.

ArgInputString

Next change the End event to None since there is no need for asynchronous call back when the process completes.

EndNone

We need a Submit task for the Submitter role and Approve task for the Approver role. They are in the Human section of the palette on the right hand side of Composer.

SubmitandApprove

 

Drag and drop the tasks onto the flow line as shown

TasksAdded

add a second swimlane using the large plus button

AddLane

create new Approver and Submitter roles and assign them to the swimlanes

AddRole

re-arrange the Approve Task and End event in the Approver swimlane

SwimlaneAssign

One simple form with a textbox to hold the string value will be used for both tasks. Open the property sheet for the Submit Task and click the plus sign to create a New Web Form. The Basic Form (frevvo) will be phased out so it is a good idea to use New Web Forms for new development.

NewWebForm

name the form wfSimple and select Open Immediately and then the Create button.

FormOpenImmediately

Add the textbox control to the form by dragging and dropping from the palette on the right of the form designer.

DropTextBox

Enter nString for the control name and String for the label.

TextBoxNameandLabel

That’s all we need, save the form and return to the process model. Open the property sheet for the Approve Task and assign the wfSimple form by clicking on the lookup button and selecting the wfSimple form.

ApproveFormAssign

Finally, do the data association for the Start event and both tasks. Click the stack icon next to the Start event and select Open Data Association.

StartDataAssociation

Associate the argInputString from the Start event with the doSimpleString process data object.

DAStart

On the Submit Task Input, associate the doSimpleString process data object with the wfSimple textbox (wfSimple.string). Also remove the default association of the form data object with the form (wfSimpleDataObject->wfSimple)

DASubmitInput

On the Submit Task Output, associate the wdSimple textbox with the doSimpleString process data object. Also remove the default association (for the form but leave the task outcome association).

DASubmitOutput

Repeat essentially the same as above for the Approve Task Input

DAApproveInput

and Approve Task Output

DAApproveOutput

The APItest1 application is now complete and ready to Validate, Publish and Deploy.

ValidateProcess

-Publish

PublishProcess

-Deploy – choose either the menu or the Deploy button on the top right

DeployProject

the Deployment tab opens, click the big Deploy new version button in the middle

DeployProjectTab

select Last Published Version

DeployLastPublished

leave the Customize step as is

DeployNoCustomize

reValidate

DeployRevalidate

enter a version number, say 1.0

DeployDeploy

and done.

DeploySuccess

In order to make the Web Service call to invoke a message start process the WSDL URL is needed. To quickly find and copy it, go to the Composer Management page.

ComposerManagement

select Web Services from the Actions drop down list for APItest1

ApplicationWebServices

and copy the link address.

ApplicationCopyLinkAddress

Save the link somewhere, we’ll need the WSDL to define the service call.

The last step in the deployment is to assign user(s) to the application roles for APItest1. Open the Administration page in PCS Workspace (must be logged in with a privileged user account)

WorkspaceAssignRoles

Add one or more users or groups to each of the APItest1 roles, in particular APItest1.Approver and APItest1.Submitter.

RoleAssignment-tuser1

Run the Workflow

The process is now active and the endpoint available to send the message start. Using the WSDL URL copied earlier, create a SOAP project in SoapUI and setup the request as shown. Use the same user in Basic Auth that you assigned the application roles above.

SoapUI-ProcessStart

Go into PCS Workspace using the same user login and select Work on Tasks.

WorkOnTasks-tuser1

There will be a task assigned, waiting at the Submit Task activity in the process flow.

TaskAssigned

Open the task and you will see the task form with the single textbox with the String label and containing the string value that was passed in from the SoapUI call.

SubmitTaskwithSoapUIstartmessage

Edit the contents of the text box changing the string value and click the Submit button on the form.

SubmitTaskwithNewString

The process flow will move to the Approve Task and the new string value displayed in the textbox.

ApproveTaskwithNewString

Click the Approve button and the flow will move to the end activity and the completed process will be listed in the tracking view in Workspace.

CompletedProcessTracking

Instance 10002 of the process shows as complete. During execution when the workflow is waiting at the Submit Task or the Approve Task it will be listed as In Progress in the tracking view.

Using the REST API

REST has exploded in popularity for a very good reason, ease of use. Compared to XML Web Services, REST API’s are simpler, more direct, versatile and easier to consume on the client side. Since using a REST API just involves http methods GET, PUT and POST to URL endpoints any http enabled environment can be used. The command line tool cURL with the associated library libcurl is a great tool for adhoc access to a REST API. SoapUI, a popular application for testing SOAP Web Services also supports REST projects. Recently Postman, which is a Chrome application has become popular for working with REST. For our exploration we’ll mainly use Postman and SoapUI when we’re doing XML Web Services. To leverage the PCS REST API WADL, we’ll import it into SoapUI, export a Swagger version and then import that into a Postman collection. Normally Postman should be able to import WADL directly but there seems to be some problem doing that hence the workaround.

The Import WADL button is on the SoapUI New REST Project dialog.

ImportWADL

the WADL URL will normally be http://<your PCS Server>/bpm/api/4.0/application.wadl , enter it in the location and click OK.

WADL_URL

Now right click the project (will be named application) and select Export Swagger from the menu.

SoapUIexportSwagger

 

In the Export Swagger dialog, select application, set the folder to store the export and set your server as the URL base.

SwaggerBase

Open Postman and import the Swagger file into a collection. Let’s start by getting a list of process definitions. Select the GET process-definitions call, set the parameters interfaceFilter to ‘all’ and the showProcessInstancesCount to ‘false’. Also set Basic Auth username and password.

Postman-get-process-defintions

click Send, the response will look something like below, notice the processDefId

Postman-process-defintions-result

Let’s start a new process instance, send a start message from the SoapUI SOAP project with the string “Process tracking test”.

SoapUI-start-process-tracking

Note the instance number in PCS Workspace.

process-tracking-number

Send a request from Postman with processId set to that instance number.

process-tracking-number-postman-send

The response will look like

process-tracking-postman-result

Notice the Submit Task has been assigned to the user in the task list.

TaskAssigned-tracking

Let’s make a general task query for all assigned tasks.

task-query-postman

the result looks like

task-query-postman-result

Note the task number for the assigned Submit Task, 200007. Let’s get the payload with a tasks/id/payload call.

task-query-payload

Note the payload shows the string value we set in the start message for this instance in SoapUI.

Let’s change the payload, the REST call is a POST. The body is JSON constructed from the XML payload above. Copy the payload and put it together to create the JSON body shown below. Note that the double quotes inside the payload string need backslash escape. Change the payload string to something new so the update can be tracked in PCS Workspace.

task-payload-update-post

you should get a 200 response

task-payload-update-response

 

Check the string has changed by viewing the task in PCS Workspace.

task-payload-update-validate

Now let’s take action on the task by “pressing” the Submit button via REST call. Use the PUT call shown below with the JSON body containing the SUBMIT action and your user identity.

submit-approve-task

The response shows the outcome of the SUBMIT action.

submit-approve-task-response

Looking at the audit diagram in the task history we see the workflow has moved from the Submit Task to the Approve Task and the flow state is In Progress.

submit-approve-task-new-state

The audit diagram is of course available via a REST call. Use the processId, 10006 in this example, and the GET processes/processId/audit call as shown below.

process-get-audit

A nice feature of Postman is honoring the MIME type of response data, image/png, and displaying it accordingly.

process-get-audit-response

The REST API in Web Applications

The simplest web application is an HTML page. We’ll look at the mechanics of calling the API from a basic page here and in Part 2 go deeper into using modern UI frameworks for web applications and mobile applications.

Start with the basic HTML shown below, copy it to a file called APITest1.html.

<!DOCTYPE html>
<html>
  <body>
    <h1>PCS REST API Test</h1>
   <p>Part 1, use process-definitions call to get the list of process</p>
    <input type="button" value="Get Process List">
    <br><br>
    <div id="response"></div>
    <br><br>
   <p>Part 2, Retrieve a Process Instance</p>
    <input type="button" value="Get Process Instance">
    <br><br>
    <div id="resptwo"></div>
    <br><br>
   <p>Part 3, Retrieve Task List</p>
    <input type="button" value="Get Task List">
    <br><br>
    <div id="respthree"></div>
    <br><br>
   <p>Part 4, Retrieve Task Payload</p>
    <input type="button" value="Get Task Payload">
    <br><br>
    <div id="respfour"></div>
    <br><br>
   <p>Part 5, Retrieve the Audit Diagram</p>
    <input type="button" value="Get Audit Diagram">
    <br><br>
    <img src="">
    <br><br>
  </body>
</html>

Opening the page in a browser

APITest-base-page

We’ll use jQuery (https://jquery.com) to make AJAX calls and access elements of the page. Add the following head section to load the jQuery library.

  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  </head>

also add a bit of style with

  <style>
   input {width:300px;}
   h1    {color: blue;}
  </style>

Next add javascript function calls to the button clicks and use AJAX to make the REST calls and return the response to the document. Most responses will be JSON objects which we’ll just stringify and stuff the text into the document for now. The process definitions call looks just like it did in Postman, http GET on the bpm/api/4.0/process-definitions URL. Set an authorization header for Basic Auth using base64 encoding of “username:password”. Insert the following in the head section of your HTML.

  <script type="text/javascript">
    function getProcessList()
    {
      $.ajax(
      {
        type: "GET",
        url: "http://pcshost:7003/bpm/api/4.0/process-definitions",
        headers: {'Authorization': "Basic dHVzZXIxOndlbGNvbWUx"},
        contentType: "application/json",
        dataType: "json",
        success: function(json){$("#response").html(JSON.stringify(json));},
        failure: function(errMsg) {
          alert(errMsg);
        },
        error: function(xhr){
          alert("An error occured: " + xhr.status + " " + xhr.statusTextt);
        }
      });
    }
  </script>

and add the onClick call to getProcessList() on the first button

    <input type="button" value="Get Process List" onClick="getProcessList()">

Load the HTML file into Chrome (or any other browser) and also open developer tools for the browser. Click on the Get Process List button.

ajax-process-list-response

The JSON response is loaded into the document at the <div> below the button. Notice there are two http method calls, OPTIONS (not shown) and GET. This is CORS preflight which is a topic for another day.

Add the four javascript functions shown below to the script section just after getProcessList(). Remember to fix the server name in the URL’s and username:password in the Authorization headers. Notice that for the last function, getAuditDiagram, we forgo AJAX and use xhr (XMLHttpRequest) directly.

    function getProcessInstance()
    {
      $.ajax(
      {
        type: "GET",
        url: "http://pcshost:7003/bpm/api/4.0/processes/10006",
        headers: {'Authorization': "Basic dHVzZXIxOndlbGNvbWUx"},
        contentType: "application/json",
        dataType: "json",
        success: function(json){$("#resptwo").html(JSON.stringify(json));},
        failure: function(errMsg) {
          alert(errMsg);
        },
        error: function(xhr){
          alert("An error occured: " + xhr.status + " " + xhr.statusText);
        }
      });
    }

    function getTaskList()
    {
      $.ajax(
      {
        type: "GET",
        url: "http://pcshost:7003/bpm/api/4.0/tasks?status=ASSIGNED&assignment=MY_AND_GROUP",
        headers: {'Authorization': "Basic dHVzZXIxOndlbGNvbWUx"},
        contentType: "application/json",
        dataType: "json",
        success: function(json){$("#respthree").html(JSON.stringify(json));},
        failure: function(errMsg) {
          alert(errMsg);
        },
        error: function(xhr){
          alert("An error occured: " + xhr.status + " " + xhr.statusText);
        }
      });
    }

    function getTaskPayload()
    {
      $.ajax(
      {
        type: "GET",
        url: "http://pcshost:7003/bpm/api/4.0/tasks/200008/payload",
        headers: {'Authorization': "Basic dHVzZXIxOndlbGNvbWUx"},
        contentType: "application/xml",
        dataType: "xml",
        success: function(xml){$("#respfour").html($(xml).text());},
        failure: function(errMsg) {
          alert(errMsg);
        },
        error: function(xhr){
          alert("An error occured: " + xhr.status + " " + xhr.statusText);
        }
      });
    }

    function getAuditDiagram()
    {
      var image = document.images[0];
      var oReq = new XMLHttpRequest();
      oReq.open("GET", "http://pcshost:7003/bpm/api/4.0/processes/10006/audit", true);
      oReq.responseType = "blob";
      oReq.setRequestHeader("Authorization", "Basic dHVzZXIxOndlbGNvbWUx");
      oReq.onreadystatechange = function () {
                                  if (oReq.readyState == oReq.DONE) {
                                    image.src = window.URL.createObjectURL(oReq.response);
                                  }
                                }
      oReq.send();
    }

Last of all, add the onClick calls to the four remaing buttons

<input type="button" value="Get Process Instance" onClick="getProcessInstance()">

<input type="button" value="Get Task List" onClick="getTaskList()">

<input type="button" value="Get Task Payload" onClick="getTaskPayload()">

<input type="button" value="Get Audit Diagram" onClick="getAuditDiagram()">

Reload the HTML file in your browser and test all the buttons.

ajax-all-functions

Summary

Access to Process Cloud Service is fast and easy using the REST API. We’ve only scratched the surface here but the mechanics and tools remain the same for exploring the full API. In Part 2 we’ll take a look at the next step beyond a simple HTML page, modern UI frameworks and mobile applications.

Add Your Comment