Common business process modeling situations in WebSphere Lombardi Edition V7.2, Part 2: Integrating a business process application with an external system using the REST API

Part 2 of this 3-part series will discuss integrating external activities with an external system using the REST API.

Ricardo Olivieri (roliv@us.ibm.com), Software Engineer, IBM

Ricardo OlivieriRicardo Olivieri is a Software Engineer in IBM Software Services for WebSphere. His areas of expertise include architecting, designing, and developing software applications (mainly web and database centric applications), administrating and configuring WebSphere Application Server, and distributed software architectures. Ricardo has several years of experience in Java development as well as in Groovy, Perl, and Python development, with a strong background in backend development (server side, business logic, databases, SQL) and frontend development. Ricardo has recently added BPM development to his bag of tricks using Business Process Manager. Through his years at IBM, Ricardo has learned and used many open source frameworks, libraries, and projects such as Drools, Spring, Struts, Restlet, Hibernate, Dojo, and JasperReports. He has a B.S. degree in Computer Engineering from the University of Puerto Rico, Mayagüez Campus.



13 July 2011

Introduction

In WebSphere® Lombardi Edition (hereafter called Lombardi Edition), you define and implement the activities, such as steps, that must be carried out to complete a business process. Part 1 of this series discussed routing of those activities, with a focus on how to dynamically compute the list of users that execute an activity in a business process. Part 2 discusses integrating external activities with an external system using the REST API. A future article in this series will cover execution of multiple instances of a single activity in parallel. The last part of this series, Part 3, will cover execution of multiple instances of a single activity in parallel.

Assumptions

A deep and thorough understanding of WebSphere Lombardi Edition V7.2 is not required to understand the topics discussed in this article. However, you should be familiar with the product’s basic function and with general concepts of business process management. Also, knowledge of Java™, JEE, WebSphere Application Server, web application security, single sign-on, REST architecture, integrated development environments (such as Eclipse), and programming languages in general are assumed.


Integrating a business process with an external user interface

It is common to integrate a business process with an external user interface. For instance, a team has invested significant time and effort developing a web interface that uses the Dojo framework. After most of this user interface has been implemented, the team decides to use Lombardi Edition to implement the business workflow instead of hardcoding this logic using the Java programming language. Though the management team is completely on board with using Lombardi Edition to implement the business process, they prefer to keep the new Dojo user interface instead of re-creating the interface pages using Lombardi Edition coaches. In such a case, the steps in the process to collect data from users are implemented as external activities instead of implementing them as human services using coaches.

A basic sample business process with external activities is used throughout this article to show how integration with an external system is achieved. This business process is included in the Download section of this article so you can import it into Lombardi Edition. We will start by describing this sample business process and then discuss how to use a Java application to execute it. Figure 1 shows the implementation diagram for the business process.

Figure 1. Business process with external activities
Business process with external activities

The Process With External Steps business process shown in Figure 1 contains two steps that are implemented as external activities: External Activity 1 and External Activity 2.

Figure 1 shows that the External Activity 1 step is implemented as an external activity. Opening the implementation for the External Activity 1 step (External Activity 1 Impl), shows the inputs and outputs that have been specified for this step (see Figure 2). The inputs are the values that are passed from the process implemented in Lombardi Edition to the external system, and the outputs are the values to be sent from the external system to the process in Lombardi Edition.

Figure 2. Inputs and outputs for External Activity 1
Inputs and outputs for External Activity 1

For External Activity 1, there are no input values specified while the output consists of one variable of the User data type. Figure 3 shows the definition of the User data type. You can see that this data type is made up of simple, primitive data types.

Figure 3. Definition of the User data type
Definition of the User data type

Inputs and outputs for an external activity are mapped to variables defined at the process level as shown in Figure 4.

Figure 4. Data mapping for External Activity 1
Data mapping for External Activity

Figure 5 shows the inputs and outputs for External Activity 2. For this step, the inputs consist of a rating value and a quote value. These are values that the system computes (in System Step 1) based on the values collected during the execution of External Activity 1. The output is a Boolean value that specifies whether or not the user accepts the quote and rating values the system generated for him/her.

Figure 5. Inputs and outputs for External Activity 2
Inputs and outputs for External Activity 2

Figure 6 shows the data mapping for the input and output variables of External Activity 2. As it was the case with External Activity 1, these variables are also mapped to variables defined at the business process level.

Figure 6. Data mapping for External Activity 2
Data mapping for External Activity 2

When a step that is implemented as an external activity is reached during the execution of a business process, the execution stops and Lombardi Edition waits for an external system to complete the activity. To move the business process forward, an external system programmatically connects to Lombardi Edition and completes the activity. The next section discusses how to integrate the Process With External Steps business process with an external system using the REST API.

System steps

Besides the two steps that are implemented as external activities in the Process With External Steps business process, there are two more steps: System Step 1 and System Step 2. These two steps are system activities that are simply implemented as JavaScript code.

Note that external activities appear in a user’s inbox in Lombardi Edition Portal, but there is no option to execute such activities from the Portal interface, as shown in Figure 7. For activities implemented as human services using coaches, Portal provides an option to execute them.

Figure 7. External activity in WebSphere Lombardi Edition Process Portal
External activity in WebSphere Lombardi Edition Process Portal

Using the REST API

The REST API makes integration with an external system quite simple. This is an optional package (not officially supported in Lombardi Edition V7.2) that you can install on your Lombardi Edition server. See REST API for Teamworks for more information about downloading and installing this optional package.

Web API An alternative to the REST

API is the Web API (see Teamworks Web API for more details), which also provides a set of operations to access Lombardi Edition functionality from an external client application. The Web API is officially supported and has been around for quite some time. When the Web API is used, you basically end up with a traditional web services client or server implementation. The Web API is beyond the scope of this article.

Using the REST API, you can execute and complete external activities programmatically. You can implement, for instance, a Java Swing or an SWT user interface for users to enter the required data to complete a step in a process. The Java application sends via the REST API the values needed to move forward to the next step in a business process. Not only can you complete an external activity with the REST API, but you can also execute a service or start a business process, among other functions.

Note that you can write a REST client in the language of your choice to access the Lombardi Edition server via the REST API.

REST API clients

In the Lombardi Edition community site, you can find a JavaScript client that you can use to invoke the REST API. See Using REST API for Teamworks in your program for details on the JavaScript client. However, there is a limitation to note if you are thinking of using the JavaScript client. This client makes AJAX calls to connect to the Lombardi Edition server and because of the same-origin policy (see the same-origin policy documentation on Wikipedia and on W3C), you cannot call the Lombardi Edition server from your web application unless your web application is served from the same server (same hostname and port number) that also hosts the Lombardi Edition business process. The browser is only allowed to establish new network connections back to the machine, which served up the request in the first place. Hence, from a browser's perspective, your web application and Lombardi Edition need to appear to be on the same server to overcome the same-origin policy restrictions. It is true that you can make the browser believe that this is the case, for instance, by using proxy gateways. However, depending on the network infrastructure where the web client application and Lombardi Edition will be deployed, or the cost to add such components to the network, this may not be a feasible solution.

Therefore, because of the same-origin policy limitation, you may need to consider using a different type of client to invoke the REST API. For example, if you had an external web user interface that needs to be integrated with Lombardi Edition, you can invoke the REST API from the application server that hosts the web application. Also, there may be other technical reasons, depending on the requirements for the solution, for not wanting to invoke the Lombardi Edition server directly from the browser.

Having said that, the JavaScript client is useful for learning and getting familiar with the capabilities and functions provided by the REST API. A sample web application that uses the JavaScript client (see Using REST API to start and run through an entire BPD for details on using the sample web application) is installed on the Lombardi Edition server when the REST API is installed. Using this web application, you can learn about the actual HTTP calls that are made. Getting familiar with these HTTP calls is useful for writing your own REST client implementation in the language of your choice.

A sample Java client

A sample REST client written in Java is provided with this article. This client allows you to perform the following basic tasks in Lombardi Edition:

  • Start a business process.
  • Run a service.
  • Finish a task.
  • Get task details.
  • Reassign a task to a specific user.
  • Reassign a task to the user submitting the REST call.
  • Basic searching.

Depending on the requirements, the above methods are enough to integrate an external system with a business process in Lombardi Edition. However, depending on the specific needs of a project, additional methods and functions are needed. Note that this sample client is provided “as is”, but you can change or improve the code in any way you would like.

A sample Java standalone application that uses the sample Java REST client to execute the Process With External Steps business process diagram (introduced earlier) is also provided with this article.

To use the sample Java REST client in a Java standalone application, first create an instance of the LombardiClientImpl class, as shown in Listing 1.

Listing 1. REST client instance in a Java standalone application
// The userid to connect to Lombardi Edition, such as tw_admin
String userid = "userid";
// The password that corresponds to the specified userid
String password = "password";
// Create WASAuthenticationTokenHandler instance
AuthenticationTokenHandler handler =
   new WASAuthenticationTokenHandler(userid, password);
// Hostname of the WebSphere Lombardi Edition server
String hostname = "localhost";
// WebSphere Lombardi Edition server port number
int port = 19086;
// Create REST client
LombardiClient client = new LombardiClientImpl(hostname, port, handler);

REST method calls made through the LombardiClientImpl instance are all executed under the context of the same user’s account. The user’s account is identified by the credentials used to create an instance of the WASAuthenticationTokenHandler class (see Listing 1).

REST Client running on WebSphere Application Server: If instead of developing a Java standalone program, you were developing a web application to be deployed on WebSphere Application Server and single sign-on was set up for Application Server and the Lombardi Edition server, use the no-argument constructor of the WASAuthenticationTokenHandler class. In such cases, the REST method invocations are automatically made under the identity of the authenticated user who is accessing the web application. If single sign-on is not set between Application Server that is hosting the web application and Lombardi Edition, then the constructor of the WASAuthenticationTokenHandler class shown in Listing 1 is used. For further details, see the Javadoc comments in the code.

Once an instance of the LombardiClientImpl class is created, you can start making REST invocations. The pseudocode in Listing 2 shows how the sample Java application uses the Java REST API client to execute the Process With External Steps business process.

Listing 2. Making REST calls
JSONObject results; 

// Start a business process: [Process App Acronym]@[BPD name] 
results = client.runBPD(ACRONYM + "@" + BPD_NAME); 
int processID = results.getInt("ID");

// Get details about a given process
results = client.getBPDInstanceDetails(processID); 

// Retrieve the inbox for the user
results = client.search("portal.savedsearch.inbox", null, null, null); 

// Get reference to first external task in process
JSONObject externalTask_1 = . . . 
int externalTaskID_1 = externalTask_1.getInt("taskId");

// Get details for external task 1
results = client.getTaskDetails(externalTaskID_1); 
parseTaskDetails(results); 

// Claim external task 1
results = client.reassignTask(externalTaskID_1); 

// Complete the external activity 1
JSONObject outputTask_1 = new JSONObject();
JSONObject user = new JSONObject();
user.put("name", "John");
user.put("age", "25");
user.put("numberOfClaims", "10");
user.put("zipCode", "78758");
outputTask_1.put("user", user); 
results = client.finishTask(externalTaskID_1, outputTask_1); 

// Retrieve the inbox for the user
results = client.search("portal.savedsearch.inbox", null, null, null); 

// Get reference to second external task in process
JSONObject externalTask_2 = . . . 
int externalTaskID_2 = externalTask_2.getInt("taskId");

// Get details for external task 2
results = client.getTaskDetails(externalTaskID_2); 
parseTaskDetails(results); 

// Process input values... 
...

// Claim external task 2
results = client.reassignTask(externalTaskID_2); 

// Complete the external activity 2
JSONObject outputTask_2 = new JSONObject();
outputTask_2.put("accepted", true); 
results = client.finishTask(externalTaskID_2, outputTask_2); 

// Run a service
JSONObject servArgs = new JSONObject();
servArgs.put("orderNumber", 1234);
results = client.runService(ACRONYM +"@Sample Service", servArgs);
// Process data returned from service invocation
...

The pseudocode in Listing 2 starts by kicking off the business process in Lombardi Edition using the runBPD() method. Note that to identify the business process to start, the process application acronym and the name of the business process must be provided in the following form:

[Process App Acronym]@[BPD name]

Once the business process is started in Lombardi Edition, the sample application retrieves the inbox (list of tasks) for the user by invoking the search() method. The items in the inbox are then parsed on the client side to obtain a reference to the first external activity (External Activity 1) in the business process. Once a reference to this activity is obtained, its details, such as the data types for the inputs and outputs, are obtained by invoking the getTaskDetails() method. The sample code then claims and completes the first external activity by invoking the reassign() and finishTask() methods, respectively.

To complete the first external activity, a JSON object that matches the structure of the User data type (see Figure 3) is created. As you may recall from Figure 2, an object of the User data type is the output for External Activity 1. Hence, this JSON object is sent to the Lombardi Edition server as part of the response data from the Java application.

After executing the first external activity, the sample code then also searches, claims, and completes the second external activity. As shown earlier in Figure 5, External Activity 2 has two input and one output variables. To obtain the input values (quote and rating), the task details returned from Lombardi Edition server are queried. Looking at the code in Listing 2, you can see that the Java REST client always returns a JSON object. Therefore, to query the returned data is simply a matter of calling the getter methods available on the JSON object. Listing 3 shows the code for two methods in the sample Java application that use the getter methods on the JSON object to read the data returned from the Lombardi Edition server.

Listing 3. Parsing data returned from Lombardi Edition server
private void parseTaskDetails(JSONObject taskDetails) throws JSONException {
   String types[] = { "inputs", "outputs" };
   JSONObject model = taskDetails.getJSONObject("model");
   for (String type : types) {
      JSONObject ios = model.getJSONObject(type); 
      @SuppressWarnings("rawtypes")
      Iterator params = ios.keys();
      System.out.println("-------- " + type + " (start) -------- ");
      while (params.hasNext()) {
         String variableName = (String) params.next();
         JSONObject param = ios.getJSONObject(variableName); 
         String variableType = param.getString("name");
         boolean isList = param.getBoolean("isList");
         System.out.println(variableName + " : " + param); 
      }
      System.out.println("-------- " + type + " (end) -------- ");
   }
 // Parse input values...
}

private void parseInputValues(JSONObject taskDetails) throws JSONException {
   JSONObject data = taskDetails.getJSONObject("data");
   @SuppressWarnings("rawtypes")
   Iterator keys = data.keys();
      while (keys.hasNext()) {
      String key = (String) keys.next();
      Object value = data.get(key);
      System.out.println("-------- " + key + " (start) -------- ");
      System.out.println(value); 
      System.out.println("-------- " + key + " (end) -------- ");
   }
}

The first method, parseTaskDetails(), reads the names and data types for the inputs and outputs of an external activity. The second method, parseInputValues(), reads the values assigned to the input variables of an external activity. The outputs that result from executing these two methods for External Activity 2 are shown in Listing 4 and Listing 5.

Listing 4. Task details for External Activity 2
-------- inputs (start) -------- 
quote : {"isList":false,"name":"Integer"}
rating : {"isList":false,"name":"Integer"}
-------- inputs (end) -------- 
-------- outputs (start) -------- 
accepted : {"isList":false,"name":"Boolean"}
-------- outputs (end) --------
Listing 5. Input variables values for External Activity 2
-------- quote (start) -------- 
740
-------- quote (end) -------- 
-------- rating (start) -------- 
5
-------- rating (end) --------

As expected, Listing 4 shows that there are two input variables for External Activity 2, quote, and rating, and that the data type for both of these variables is an integer. You can also see that there is only one output variable for this external activity, accepted, which is of a Boolean type.

In Listing 5, you can see the values assigned to the input values (quote and rating). Since this is a sample application, no business logic was built around the quote and rating values retuned from the Lombardi Edition server to compute the value for the accepted output variable. Instead, the value for the accepted Boolean output variable was simply hardcoded to true (as shown in Listing 2). Also, note that once the sample client application completes External Activity 2, System Step 2 is executed and the business process ends.

Finally, the last section of the pseudocode in Listing 2 shows how to invoke a service implemented in Lombardi Edition named Sample Service. This service receives one argument, an order number, and returns one value, a customer number, as shown in Figure 8.

Figure 8. Inputs and outputs for Sample Service
Inputs and outputs for Sample Service

The implementation for Sample service simply generates a random number and multiplies it by the input number that was provided as an argument as shown in Figure 9. To read the returned value from the service is simply a matter of querying the JSON object returned from the service invocation.

Figure 9. Sample Service implementation
Sample Service implementation

Companion files

The complete source code for the sample Java application that executes the Process With External Steps business process is provided with this article. The sample application (source and binary) is contained in the lombardi-rest-client-demo-app.jar file. This jar file contains only one Java class named demo.SampleLombardiClientApp (which corresponds to the code described earlier in Listing 1 and Listing 2). The sample Java REST client code is packaged in the lombardi-rest-client.jar file.

Note that before running the demo.SampleLombardiClientApp program, you must perform the following steps:

  1. Import the Common_Modeling_Situations_-_Part_2 - CMS_2_62711_936_AM.twx file. This twx file is also included with this article. It contains the Process with External Steps business process diagram.
  2. Install the REST API on Lombardi Edition (see REST API for Teamworks for installation instructions).
  3. Update the demo.SampleLombardiClientApp class to specify the user ID and password that are used to connect to the Lombardi Edition server.
  4. Update the demo.SampleLombardiClientApp class to specify the hostname and port number for the Lombardi Edition server.

The Java REST client has a dependency on a Lombardi Edition toolkit, BPD Utilities Toolkit, which is also included with this article. This toolkit is used to work around a problem in the REST API implementation that occurs when assigning a task to another user. The acronym for this toolkit is UTILS. If needed, you can change this acronym to another. If changed, you need to update the lombardi-client.properties file accordingly (see Listing 6).

Listing 6. Default acronym name for the companion toolkit
toolkit=UTILS

The lombardi-client.properties file is found in the lombardi.rest.client package of the Java REST client. As mentioned earlier, it is packaged in the lombardi-rest-client.jar file.

Note that when you import the Common_Modeling_Situations_-_Part_2 - CMS_2_62711_936_AM.twx file, the BPD Utilities Toolkit is imported along with the Process With External Steps business process diagram.

The Java REST client code is also dependent on the open source libraries that are also included with this article:

  • Restlet JARs:
    • org.restlet.ext.json.jar (v 2.0.7)
    • org.restlet (v 2.0.7)
  • JSON classes:
    • org.json.jar

Make sure all the JAR files provided with this article are included in the classpath of the JVM when running the demo.SampleLombardiClientApp program. Otherwise, you will get ClassNotFoundException errors.


Runtime environment

The sample Java REST client was successfully tested in a JEE application running on WebSphere Application Server V7 and also in a Java standalone program. For both scenarios, the Lombardi Edition configuration was as follows:

  • WebSphere Lombardi Edition V7.2
  • RESTAPI7.2.0.20-WLE7.2.0.zip

Also, single sign-on was set up for WebSphere Application Server hosting the JEE application and the Lombardi Edition server.


Seeing the REST API in action

The best way to see in action how the sample Java application moves the Process With External Steps business process forward is to run the Java code in an integrated development environment, such as Eclipse or Rational® Application Developer. Using an integrated development environment allows you to set breakpoints in the code. For instance, you can set a breakpoint right at the beginning of the code, and then execute the code step-by-step. You can see then in the Inspector perspective of the Lombardi Edition Authoring Environment how the business process moves forward as the Java code executes. Figure 10 shows the Inspector perspective for the Process With External Steps business process while the sample Java code is running.

Figure 10. Inspector perspective
Inspector perspective

Conclusion

The REST API can easily integrate an external system with WebSphere Lombardi Edition. By using the REST API, an external application can, among other functions, start a business process, complete an activity or step in a business process, get details about an activity (for example, inputs and outputs), and execute a service. If you have to integrate an external application, such as Java standalone program with a business process implemented in Lombardi Edition, consider using the REST API.

The last part of this series, Part 3, will cover execution of multiple instances of a single activity in parallel.

Acknowledgments

The author would like to thank Owen Cline for reviewing the technical content of this article.


Download

DescriptionNameSize
Sample codePart_2_code_samples.zip1.18MB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Business process management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Business process management, WebSphere
ArticleID=731848
ArticleTitle=Common business process modeling situations in WebSphere Lombardi Edition V7.2, Part 2: Integrating a business process application with an external system using the REST API
publish-date=07132011