Enterprise JBoss JBPM: Creating A Scalable, Standards-Compliant and Cost-Effective SOA Environment
This excerpt from the upcoming book, Open Source SOA, addresses the Service Component Architecture (SCA), and its sister technology, Service Data Objects (SDO), emerging standards used in service-oriented architecture for creating multi-protocol, multi-language services based on reusable components.
By Jeff Davis
The previous excerpt on jBPM from chapters 5 and 6 of the forthcoming Manning Publications book Open Source SOA introduced jBPM as the Business Process Management (BPM) product used for what we are calling the OpenSOA Platform. This platform of open source applications, when integrated, creates a powerful combination of products that can assist in creating a truly scalable, standards-compliant and cost-effective SOA environment.
This article expands on the previous jBPM excerpt to explore some of the advanced capabilities found in jBPM. Since it is just an excerpt, summary-level information is only provided, but it should give you a good flavor of the advanced features the product offers. Unlike the book, detailed code samples, descriptions, and annotations are not provided.
The final chapter on jBPM covers two mains topics: enterprise functionality and integration with Apache Tuscany’s Service Component Architecture (SCA) and Service Data Objects (SDO). The enterprise features of jBPM we’ll discuss are particularly relevant when building very complex business processes that have enterprise-ready exception handling and logging. The ability to decompose complex business processes into subprocesses is particularly relevant to SOA, as it enables you to construct higher-level composite services that can be reused by multiple processes. The integration with Apache Tuscany (SCA/SDO) discusses an approach for service-enabling jBPM, thus making it a first class citizen in your SOA environment.
Enterprise jBPM Features
The enterprise features of jBPM that are the focus of this section are beneficial when you begin developing complex business processes. In particularly, it is useful to be able to break down, or group, complex processes into more manageable pieces. We will discuss two means of accomplishing this within jBPM: superstates and subprocesses. Later, we will describe solutions for how to manage exceptions that may occur as a result of any custom code you developed as part of the process.
While not an “advanced” feature per se, our focus will turn to describing how you can use in-line code in the form of Beanshell scripts and monitor a given process instance through the extensive logging features that are provided. Lastly, we look into a concept called asynchronous continuations, which enable you to distribute processing to the jBPM server in which jBPM enterprise is running. Let’s begin by looking at jBPM superstates.
Superstates in jBPM are simply a grouping of nodes. They are useful, for example, when you want to logically associate together a group of nodes. This might be done to delineate phases of a process or to group by organizational responsibilities. For example, an employee termination process is typically cross-departmental, with various responsibilities falling within several organizations.
In one instance, superstates were used to group the nodes between HR, Finance and Security. Within the jBPM Graphical Process Designer (GPD), when you deposit a superstate node into the jBPM working area/canvas, a bordered region is created where you can then add nodes and transitions. As you can see, these border areas can be resized, and will sprout scrollbars where necessary. You can also associate timers to the superstate (this does require the enterprise version of jBPM, in other words, the app server addition). In the scenario shown in Figure 1, you could, for instance, notify a manager of the HR org that their team’s work has not been completed in a timely fashion. Thus, using events and timers, there is benefit beyond the obvious achieved by providing visual hierarchy and grouping. Related in concept are subprocesses, which are intended to provide greater process composition flexibility.
Subprocesses provide a means to create decomposed processes. In other words, you can define a master process which, in turn, calls subprocesses. The subprocess can be considered as though it is simply another node in the process. When the subprocess is complete, execution will continue in the calling process. This ability enables you to create more complex processes without overly complicating the visual layout. Additional benefits include the ability to create reusable process modules that can be incorporated by other process definitions. In chapter 1 we discussed that an important aspect of SOA is the ability to create composite services. Using subprocesses, you can achieve this by creating reusable processes. These can be run stand-alone, or as subprocess to a larger orchestration.
In Figure 1, we illustrated a modestly complex business process used for employee termination. In that case, superstates were used to provide some logical structure to the diagram. Since the security-related nodes were the most involved, let’s instead break that out into a separate subprocess.
In Figure 2, the node named security represents the new subprocess (identified within the node icon as >). When this node is encountered, a new process instance for the security process is instantiated.
We have now covered two approaches for helping you organize and/or decompose complex business processes — essential tools for building enterprise orchestrations. Another important aspect of enterprise solutions is effective exception handling.
Exception handling within jBPM is a bit different than what one might imagine. When managing exceptions within jBPM, you are only dealing with those that result from any handler classes that you have created. They are not used for any sort of internal jBPM error that may have been resulted from processing within the engine itself. So, for example, if you are extending functionality with an action or assignment handler, you can trap and manage those errors using the exception handling techniques we will describe.
A source of common misunderstanding about exception handling within jBPM is whether you can use this mechanism to directly alter the flow of the process. The official documentation is rather contradictory on this matter. The upshot is this: While technically you can redirect the[m], this is strongly discouraged. Instead, the proper approach is to instead set a process instance variable, which can then direct subsequent flows by way of a decision node. In addition, you can issue an alert or notification through JMS, email etc., so that someone can perform remedial actions. In chapter 7 of the book, we illustrate how exceptions can be used in tandem with process variables to achieve what is likely the desire affect — notification of the exception to an appropriate party.
While not an advanced feature, per se, we’ll next look at how Beanshell scripts can be used in lieu of Java classes for more rapid development.
There are times when authoring a jBPM business process that having to resort to creating a Java class for required functionality seems overkill. This is particularly true when you just need to introduce a few lines of programming logic. In the situations, you can use Beanshell scripts, which maybe more convenient and allow for more rapid application development. In addition, Beanshell expressions are also used in a variety of capacities within jBPM, such as within decision node logic. For those unfamiliar with Beanshell, it was one of the earliest Java scripting implementations, and recently has initiated the Java Community Process to become a JSR-compliant standard. It has enjoyed fairly wide support, and is included in a variety of applications as a lightweight scripting alternative to Java (visit the official web site for more details and usage documentation). The syntax and usage closely mirrors that of standard Java, so Java developers can generally pick it up quickly.
Beanshell scripts are supported in most cases where Java handler classes can be used. Thus, they can be used for actions, events, or setting process variables. In addition, Beanshell scripts are used by decision nodes. In this instance, they are a one-line statement that must evaluate to true or false (this is also true for anytime an expression attribute is also allowed).
Regardless of whether you extend jBPM functionality with Beanshell or Java, inevitably you will want the ability to log and monitor the activity that occurs within your process instance. This is whether jBPM audit logging comes into place. We also see in the next chapter how this capability can be used to generate events which can be consumed by an event stream processor, thus providing real-time metrics and monitoring into your jBPM process instances.
By default, there are a variety of audit logs that are produced as a result of process instance execution. Collectively, these logs will provide you complete insight into every activity that has occurred within a process instance. How can this information be beneficial? For example, you could load it into a data warehouse for reporting and analysis. Or, perhaps monitor the data in real-time for business activity monitoring dashboards, and the like. Like nearly all aspects of jBPM, you can also extend the logging features with your own required capabilities. For example, you may wish to do this if you wanted to dynamically filter the logs for only content you deem relevant. Detailing how this can be accomplished is outside the scope of this excerpt, but is address in chapter 7 of the book.
We will now conclude our discussion of jBPM advanced features by looking into asynchronous continuations, which enables process execution to be asynchronously performed by a server process.
You have likely noticed through the exercises thus far that, when you signal the execution of a process instance, it will continue to execute within the thread you are running until it encounters a wait state, such as a state or task node. At that point, you could consider the transaction to be completed. While generally this doesn’t cause any problems because most transactions complete within milliseconds, there are times when that may not be the case. Do any scenarios come to mind? How about when you have a node node-type that performs a web service call to a remote system using a traditional request/reply message exchange. In that scenario, the node will block and wait until the reply is received (or it timeouts). This could have highly undesirable consequences for your process if, for example, an immediate response is anticipated (maybe it’s a web order being kicked off through the BPM process, and the user is awaiting a response with an order identifier). Fortunately, there is already a built-in approach for managing this scenario directly within jBPM. It is called asynchronous continuations. How this works is best illustrated through a simple example.
In the process shown in Figure 3, let’s assume nodes 1, 2, and 3 include Java action handlers which perform some external action. In nodes 1 and 2, those action handlers perform their work synchronously within the same transaction that the process is initiated (this is the default behavior). However, the 3rd node is specified using @async=true. What this means is that the node, and within it any Java action handlers, will be processed by an external command executor. Since node 3 is processed asynchronously, the transaction is completed and placed in a wait state (i.e., persisted) until the join node receives node 3’s signal.
The jBPM Enterprise version, which runs within the context of an application server, is, by default, configured to support asynchronous continuations by way of its build-in Job Executor. The Job Executor receives its command message through a JMS queue that is automatically configured when jBPM Enterprise is run. In our example, what this means is that the jBPM Job Executor will asynchronously process node 3. Once completed, node 3’s action handler instruction to signal continuance of the execution will be performed. Figure 7.6 shows the process instance just after initiation, where nodes 1 and 2 have been completed and now wait in the join node for the conclusion of node 3.
As Figure 4 illustrates, the asynchronous processing of node 3 occurs in three steps: 1) a JMS message that includes the action handler to be executed is sent to a JMS queue; 2) the jBPM Enterprise Server’s command listener is listening for new messages submitted to the queue; and 3) once a message is received it then is sent to the command executor for processing. The command executor will initiate a new transaction from which the action handler is run, and will forward the execution onward. Although not shown, all 3 nodes will then have then completed, the join consummated, and execution moved to the end to complete the process instance.
We have now completed our coverage of some of jBPM advanced features. Others, such as how to create your own node types and integration of jBPM console security, are not covered. The jBPM User Guide does provide some guidance on these matters, and the forum and source code can be indispensable as well. We will now look at a very exciting topic, and that is how to integrate jBPM with SCA and SDO, which was the topic of chapters 3 and 4, and a key cornerstone for creating a SOA environment.
Integration with SCA/SDO
The Service Component Architecture (SCA), and its sister technology, Service Data Objects (SDO), are an emerging standard for creating multi-protocol, multi-language services based on the concept of reusable components. Apache Tuscany is a reference implementation of SCA/SDO, and has recently achieved its 1.0 release. Chapters 3 and 4 of the Open Source SOA book covered Tuscany in some detail, and we will utilize some of these examples to demonstrate how we can integrate jBPM with SCA/SDO to make a powerful SOA combination.
One of the most frequent themes in the jBPM forums hosted by JBoss are questions about how to expose jBPM as web services. We have demonstrated in this and the prior chapter many examples of using jBPM API, and the capabilities and flexibility it offers. However, it is Java-specific, and clients wishing to access jBPM must embed jBPM libraries and calls within their code. This runs contrary to one of the main premises behind SOA: loose coupling. By embedding jBPM API calls within your clients, you have affectively limited flexibility, as you are tightly integrated with jBPM. A far better approach is to abstract out some of the complexities of the API into a web service faç,ade. This simplifies client development, promotes loose-coupling, and exposes jBPM as a cross-platform/protocol solution.
There are two main ways in which SCA can be integrated with jBPM. The most obvious way is to expose the jBPM API through web services. With SCA, you can create a service that can be exposed through any of its available bindings, such as SOAP, EJB, JMS etc.
For example, in the complete chapter 7 found in the book, we describe how a generic style services can be setup to enable clients to access jBPM through SOAP. The jBPM API services exposed include operations to list tasks by actor; list tasks by process instance; list process instances; and list processes. Adding additional service operations is shown to be a very straightforward process after these extensive examples.
The other SCA integration demonstrates how to use a node within jBPM as an SCA client to call external services.
In figure 6, the node called soap-sca-submit is an SCA client that is calling an external service from within jBPM. One often overlooked feature of SCA is how easily external SOAP service services can be invoked. The protocol details are completely transparent to the calling client (the book similar describes how this can be done). Through this brief discussion I think you can see the great marriage that can be achieved through jBPM and SCA. jBPM is a wonderful and powerful BPM solution, and when coupled with SCA/SDO, can open a world of possibilities for integration within a SOA environment.
This excerpt from chapter 7 of the forthcoming Open Source SOA book covers the two main areas of focus for that chapter — advanced features of jBPM and integrating jBPM with SCA/SDO through its Apache Tuscany implementation. The advanced features focus on some of the enterprise capabilities of jBPM, such as the ability to create superstates and subprocesses, both of which help bring greater order and management to defining complex business processes. The use of asynchronous continuations assist in circumstances where you are integrating with services that may not have predicable and/or timely responses. They also can help you create more distributed solutions.
The second section describes how you can integrate jBPM with SCA. This marriage addresses some of the recurring concerns with jBPM, namely, how do you call external services within the context of a reusable and consistent framework. We then reversed the requirement, and described how the jBPM API can be exposed through SCA so that it can be accessed through any number of different protocols, including SOAP and JMS. Through the combination of SCA/SDO and jBPM, we have the full spectrum of services addressed, from fine to coarse-grained, layered upon a compelling technology stack. Chapter 8 of the book, and the subject of our next excerpt, will describe how we can leverage the events derived from our services to provide complete operational insight and monitoring — an important value-added feature of a SOA environment.
This article is based on Open Source SOA by Jeff Davis, to be published in March 2009 (ISBN: 1933988541). It is being reproduced here by permission from Manning Publications. Manning early access books and ebooks are sold exclusively through Manning. Visit the book’s page for more information.