Contents


Manage and recover IBM Business Process Manager processes efficiently with the REST API

Comments

IBM BPM provides a set of APIs that are based on the REST protocol as a tool to query and access data for process instances, tasks, and business applications. The REST API provides access to data that relates to business process definitions (BPD), Business Process Execution Language (BPEL) modules, and federated resources, for both external clients and internal processes. The list of REST APIs provided can be viewed through the REST API Tester portal that is available with IBM BPM.

You might find situations that benefit from starting REST APIs programmatically, from a BPD or from a Service Component Architecture (SCA) application (such as a BPEL flow or a mediation). For example, an exception governance process might need to access the business and process data of stopped process instances so that it can either restart or recover a process instance. REST APIs can retrieve process variables, input/output parameters, business objects, transaction states, and other details, directly from IBM BPM databases. The APIs are lightweight and can be programmatically started from various devices, such as desktops, tablets, and mobile devices.

This tutorial shows an approach for using the IBM BPM REST API to access process instance data programmatically from a BPD by using Java™. The example implementation shows how process administrators can manage stopped processes from a coach that uses a REST API-based process application. The example included with this tutorial was implemented on IBM BPM V8.5.5, but it should work without any changes with all IBM BPM V8.x versions.

To gain the most out of this tutorial, you should be familiar with the basic capabilities and features of IBM BPM. In addition, knowledge of REST, JavaScript, JSON, Java, and programming in general is helpful.

Designing the solution

In an environment that predominantly uses a headless IBM BPM process pattern, it is essential to get visibility to processes that are stopped (failed or suspended) due to exceptions, so that you can recover or stop the processes. In a headless pattern for IBM BPM workflows, for example, an entire process is completed with a series of steps as an automated workflow with no human intervention, but a human interface is used only for exception processing or process governance. To manage this type of exception governance process efficiently, it is very helpful for users and administrators of your application to use a portal to query the stopped processes and manage them in bulk.

For example, imagine that you need a simple exception governance process to query the state of stopped process instances of headless IBM BPM processes so that you can restart or recover them. Typically they are SCA processes, such as long-running BPEL processes.

Figure 1 shows an example of how to implement a query of the state of the stopped processes.

Figure 1. Implementation example: query process instance state that uses REST API
Implementation example:                 query process instance state using REST API
Implementation example: query process instance state using REST API

This example implementation consists of a BPD called Process Query that contains a simple coach (user interface) where users of the application can query processes that are in exception state, based on process type (IBM BPM or SCA) and the stopped state (failed or suspended). To keep the design simple, assume that users want to either restart or end the stopped process instances.

Searching of failed or suspended process instances are handled by using an IBM BPM Integration Service component, which uses a custom Java Archive file called RESTQuery.jar to run the IBM BPM REST API queries. The RESTQuery Java class, which is contained in the RESTQuery.jar, returns a list of retrieved process instance data as a JSON (JavaScript Object Notation) object to the integration service. To parse the returned JSON object, the example uses the json2.js utility library to extract stopped process instance IDs, which are then displayed to the users in the coach. As stated earlier, IBM BPM REST API supports JSON, JSONP, and XML return formats as set in the HTTP Accept header. (JSONP return format is supported in IBM BPM Standard only and is not enabled by default. For details, see Content types that are supported by the IBM BPM REST APIs in the IBM BPM 8.5.5 documentation on IBM Knowledge Center).

Based on the returned list, users can then choose to restart or terminate one or more process instances. Selected process IDs are passed to another Integration Service component, which starts the REST API through the RESTQuery Java class to restart or terminate the selected process instances.

The scope of this example implementation is a simple user interface that is backed by the REST API, but this design approach also can be used to build a more automated governance process.

Now review each of the components in detail.

Implementing the solution

Figure 2 shows the ProcessQuery_BPD that contains a human service called Process Query HS.

Figure 2. Process Query BPD example
Process Query BPD                 example
Process Query BPD example

As shown in Figure 3, this human service contains a coach that is called Query Process HT where users of the application query the stopped process instances. Figure 4 shows the coach layout.

Figure 3. Process Query HS implementation example
Process Query HS implementation                     example
Process Query HS implementation example
Figure 4. Query Process HT coach layout example
Query Process HT coach                 layout example
Query Process HT coach layout example

The Process Query HS service contains three service components (Retrieve Instance GS, Parse Result GS, and Act on Instance GS services) that complete the implementation. When users enter the search criteria on the process or instance and click Get Process IDs, the Retrieve Process GS service starts the getStoppedInstances() method of the RESTQuery java class by using a Java Integration component. This class builds the REST service URL based on the parameters that are passed and runs the query against IBM BPM server. The requested response type is set as JSON in the HTTP Accept header. Alternatively the requested response type can also be sent as part of the URL query string.

Figure 5 shows the Java integration step that starts the getStoppedInstances() method of the RESTQuery Java class, and Listing 1 shows a section of the getStoppedInstances() method. It constructs and starts the REST API URL, based on user-specified parameters in the coach. The method accepts three arguments of String type: IBM BPM server (host and port), type of the query, and process state. The IBM BPM server value is stored as an environment variable.

Figure 5. Get Process Id integration service example
Get Process Id integration                 service example
Get Process Id integration service example
Listing 1. Java code to build and invoke the REST URL
/* Map state values */
if (state.equalsIgnoreCase("FAILED"))
      iState = "5";
else if (state.equalsIgnoreCase("SUSPENDED"))
      iState = "2";

/* Set the URI based on the resource type */
if (processType.equalsIgnoreCase("BPD")) {
  restURI = "rest/bpm/wle/v1/";
} else if (processType.equalsIgnoreCase("SCA")) {
  restURI = "rest/bpm/bfm/v1/processes/";
  /* Set default query parameters: for BPD (process), default is all
  * detail; for SCA (service) default is blank (GET) */
   parameters = parameters.concat("filter?whereClause=PROCESS_INSTANCE.STATE=").concat(iState);
}

urlStr = buildURL(bpmServer, restURI, parameters);
logger.info("REST URL: " + urlStr);

try {
  /* open connection, set method and headers */
 conn = createConnection(urlStr, method);  	 	 logger.info("Connection created...");
       /* Invoke REST service over HTTP and get response */
  StringBuffer response = readResponse(conn);

  result = response.toString();
  logger.info("Result: " + result);
} catch (MalformedURLException me) {
	 String msg = "IOException thrown... " + me.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
       logger.severe(msg);
       throw new Exception(msg);
} catch (IOException io) {
       String msg = "IOException thrown... " + io.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
       logger.severe(msg);
       throw new Exception(msg);

} catch (Exception e) {
       String msg = "Exception thrown... " + e.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
       logger.severe(msg);
       throw new Exception(msg);
}

return (Object) result;

The Java code in Code Listing 1 builds REST URLs based on process type, as shown in Table 1.

Table 1. REST URLs built by the getStoppedInstances() method
Process TypeURL Built By JavaMethod
IBM BPM Process Type - Failed Instances http://bpm_server:port/rest/bpm/wle/v1/search/query?condition=instanceStatus %7CFailed&organization=byInstance&run=true &shared=false&filterByCurrentUser=false PUT
IBM BPM Process Type - Suspended Instances http://bpm_server:port/rest/bpm/wle/v1/search/query?condition=instanceStatus%7CSuspended&organization=byInstance&run= true&shared=false&filterByCurrentUser=false PUT
SCA Process Type - Failed / Suspended Instances http://bpm_server:port/rest/bpm/bfm/v1/processes/filter?whereClause=PROCESS_INSTANCE.STATE= state_integer_code (where state_integer_code can be 5 or 11) GET

The RESTQuery.java is packaged as a Java archive file and imported into the process application as a file resource (by clicking the + symbol next to the File menu option of the Library navigation pane), so that it is available for use in the Java integration component. From the Download section of this tutorial, download the code_sample.zip and extract for the example .jar file that contains the complete code.

Since the REST client is required to authenticate against the IBM BPM server, the RESTQuery class implements the Authenticator interface to supply the user ID and password for basic authentication. This unsophisticated authentication mechanism is simple. In real life, you might want to consider other more secure and single sign-on techniques.

The getStoppedInstances() method of the RESTQuery java class returns the JSON result object as a Java String object to the calling BPD. This object is then passed to the Parse Result GS service (shown in Figure 6), which uses a server-side Javascript step to convert the string result into a pure JSON object and parses the result elements to extract stopped process instance IDs and any other required elements.

Figure 6. Parse Result GS general service implementation
Parse Result GS general                 service implementation
Parse Result GS general service implementation

Listing 2 shows the Javascript that is contained in the Parse Result GS step.

Listing 2. Javascript to parse JSON result object
if (tw.local.response != null && tw.local.response != '') {
    log.info("Result: " + tw.local.response);
    var jsonObject = JSON.parse(tw.local.response);
    log.info("JSON Object: " + jsonObject);
    
    // Build process id list
    tw.local.processIds = new tw.object.listOf.String();
    
    if(tw.local.processType == "BPM") {
       
        for ( var pid=0; pid<jsonObject.data.data.length; pid++) {
            tw.local.processIds[pid] = jsonObject.data.data[pid].instanceId.toString();
            tw.local.state = jsonObject.data.data[pid].instanceStatus;
            
        }
        
    } else {
        
        for ( var pid=0; pid<jsonObject.items.length; pid++) {
            tw.local.processIds[pid] = jsonObject.items[pid].topLevelProcessInstanceName;
            tw.local.state = jsonObject.items[pid].executionState;
            
        }
    }
    
} else
    log.error("NULL Response returned!");

IBM BPM 8.5.x needs a utility library to handle JSON objects in server-side Javascript. This example demonstration uses json2.js (See the Resources section), which must be imported as a file resource into the BPD. Figure 7 shows the file resources that are required to implement this solution.

Figure 7. File resources
File resources
File resources

The retrieved process instance IDs are returned to the coach, which displays them as a multiple selection list. The users can then select one or more process instance IDs and decide to click either Restart or Terminate (see Figure 8). For simplicity, the example lists only the instance IDs of the stopped processes. In real life, you might want to list other details of the instance IDs such as the process name, the date started, and the date failed, to aid users in deciding what to do with the processes.

Figure 8. Query Process coach
Screen capture of                     the example Query Process                 coach
Screen capture of the example Query Process coach

When the user clicks Restart or Terminate, the coach passes control to the Act on Instance IS service (see Figure 9), which loops through each instance ID and starts the processAction() method of the RESTQuery.java class.

Figure 9. Act on Instance integration service
Screen capture of Act on Instance integration                 service example
Screen capture of Act on Instance integration service example

This class accepts four arguments of the String type: IBM BPM server, instance ID, action to perform, and process type. It builds the appropriate REST URL based on action and process type, and starts the API.

Listing 3 shows a section of this method (in the Downloads section, see the code_sample.zip for the complete code sample).

Listing 3. Partial listing of processAction() method
/* Set the URI based on the resource type */
if (processType.equalsIgnoreCase("BPM")) {
	restURI = "rest/bpm/wle/v1/process/";
	parameters = parameters.concat(instanceId).concat("?action=").concat(action).concat("&parts=all");
	
} else if (processType.equalsIgnoreCase("SCA")) {
	restURI = "rest/bpm/bfm/v1/process/";
	if (action.equalsIgnoreCase("restart") || action.equalsIgnoreCase("resume"))
		parameters = parameters.concat(instanceId).concat("?action=").concat(action);
	else if (action.equalsIgnoreCase("terminate")) {
		parameters = parameters.concat(instanceId).concat("?action=forceTerminateamp;invokeCompensation=false");
	} else if (action.equalsIgnoreCase("delete")) {
		parameters = parameters.concat(instanceId);
		method = "DELETE";    // can only delete a failed/suspended process
	}
}

urlStr = buildURL(bpmServer, restURI, parameters);

logger.info(urlStr);

try {
	/* open connection, set method and headers */
	conn = createConnection(urlStr, method);

	/* Invoke REST service over HTTP and get response */
	String response = readResponse(conn).toString();

	object = ((response==null || response.trim().equals(""))? (conn.getResponseCode() + " " + conn.getResponseMessage()):response).toString();
	logger.info( "Response object: " + (String)object);
}
}

Table 2 shows the URLs that the method builds and calls, based on process type and action to take.

Table 2. Restart / Terminate REST API URLs
Process TypeURL Built By JavaMethod
IBM BPM Process Type -
Restart Process
http:/bpm_server:port/rest/bpm/wle/v1/process/process_instance_ID?action=retry&parts=all PUT
IBM BPM Process Type -
Terminate Process
http://bpm_server:port/rest/bpm/wle/v1/process/process_instance_ID?action=terminate&parts=all PUT
SCA Process Type
- Restart process
http://bpm_server:port/rest/bpm/bfm/v1/process/process_instance_ID?action=restart PUT
SCA Process Type
- Resume process
http://bpm_server:port/rest/bpm/bfm/v1/process/process_instance_ID?action=resume PUT
SCA Process Type
- Delete process
http://bpm_server:port/rest/bpm/bfm/v1/process/process_instance_ID DELETE
SCA Process Type
- Terminate process
http://bpm_server:port/rest/bpm/bfm/v1/process/process_instance_ID?action=forceTerminate&invokeCompensation=false PUT

The status of the call is then displayed to the users at the bottom of the coach in the Results section, as shown in Figure 8.

Testing the application

To test the application, walk through the steps that the users would. Start by identifying a few failed or stopped instances from your environment. Look for both IBM BPM and BPEL process instances – use the Inspector in Process Designer for BPD instances and the Business Process Choreographer Explorer for BPEL instances. Note down the instance ID for each one. Run the ProcessQuery_BPD from Process Designer or from Process Portal and supply the following parameters in the Coach screen (see Figure 8):

Process Type: Select BPM from the list.

Process State: Select Failed from the list.

Click Get Process IDs.

The RESTQuery java class constructs and start the REST service and returns the results, which are displayed in the Process ID List field. Compare the list of displayed instance IDs from the manual list that you previously made.

Select one or more process IDs from the displayed list and click Restart. If the IBM BPM server is able to restart the processes, a brief result (for example, STATE_RUNNING) is displayed at the bottom of the coach in the Results section.

Repeat the steps for the SCA process type and the Suspended state. The SystemOut.log in WebSphere Application Server then displays the messages that are written in the code. Similarly, select one or more retrieved process IDs and click Terminate to terminate and delete the processes.

To compare and verify the results, you can run the same queries that are built by the RESTQuery Java class (you can copy the URLs written by the class from the SystemOut.log output) from the IBM BPM REST API Tester ( http://Your_IBM_BPM_Server:Your_http_port/bpmrest-ui) .

Conclusion

This tutorial described an approach to programmatically access the IBM BPM REST API from an IBM BPM process flow. It walked through a simple use case and an example implementation to demonstrate how a custom exception management process that needs access to IBM BPM process instance data at run time can be built quickly and easily by using the IBM BPM REST API.

Because the REST API provides a transparent layer to the IBM BPM databases, it makes access to process, service, and task data less complex and more maintainable than directly accessing the tables and views. The REST API simplifies access to process and instance data across BPD and SCA layers that are spread across two databases. You can extend this approach to build a more automated and operational exception process management workflow to manage large volume of process instances.

Acknowledgements

The author would like to thank Bobby Pham for the technical review of this tutorial.


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Middleware
ArticleID=1014469
ArticleTitle=Manage and recover IBM Business Process Manager processes efficiently with the REST API
publish-date=09232015