Internal Workflow with jBPM



Transaction Workflow with jBPM

Doug Smith, CIS 764, Fall Semester 2007

Purpose

The purpose of this tutorial is introduce jBPM, and show its use for transaction workflow, using the session façade pattern to demonstrate how jBPM can fit into J2EE applications.

jBPM

JBoss jBPM is a workflow engine that can be used in settings from standalone Java programs coordinating tasks to full large scale application server deployments involving business process implementations involving long running processes, system orchestration and human interaction.

jBPM provides a graphical process designer, an execution engine, an administrative console application, and components for identity management, email integration, and database integration, among others.

At its core, jBPM provides a facility for a graph oriented programming abstraction. Many computing problems can be modeled as the execution of a directed graph, such as business process management, web page flow, service orchestration, and so on.

For an in-depth treatment of graph oriented programming with jBPM, refer to the Graph Oriented Programming section of the jBPM user guide:

An Example Scenario

For the purposes of this tutorial, we will use a simplified version of enrolling in a university course as an example. Figure 1 shows a BPMN diagram of the process. Basically, when a student requests enrollment for a course, if the course is not full, the student is added to the course, and an entry is made to their transcript.

[pic]

Figure 1 Enrollment Process

This is a very simplified view of the process, but it should suffice for the purposes of this tutorial.

The Session Façade Pattern

One of the patterns we’ve seen in CIS 764 is the session façade pattern. The typical use of the session façade pattern in J2EE applications is to provide a transaction oriented interface to clients, scripting the necessary interactions between EJBs needed to provide a service. It is also used to reduce round-trips between the client and server required for a transaction, as well as to shield the client from the complexity and baggage associated with using EJBs.

One of the most important components of the session façade pattern, however, is to not make the client responsible for implementing the business logic associated with the transaction. A session façade provides a service-oriented view of a transaction: the client can consume the service without needing to understand how it is implemented.

Based on the above scenario, the following diagram shows the classes that can be used to implement the enrollment process.

[pic]

Figure 2 Class model for Enrollment service

The following sequence diagram shows how the session façade can coordinate the interactions with the entity classes to implement the enrollment process.

[pic]

This pattern has worked well in practice, but in some cases an alternative approach may be warranted:

➢ If the workflow in the session façade represents a business process, as opposed to domain logic in an application, class and sequence diagrams are not a good communication vehicle when interacting with business analysts and other stakeholders from the business community.

➢ If the process is subject to frequent change, implementation in a session façade may not provide the right level of agility to deal with change.

➢ Processes that are long duration and combine tasks performed by humans with tasks performed by systems require a different solution paradigm, and in the interest of consistency it may make sense to use the same technology for all process execution, both short lived straight through processing and longer duration processes.

Using jBPM in the Session Façade

jBPM provides a way to implement the workflow shown in the scenario above, using a technology that promotes agility by putting the business logic in an XML file, executed by infrastructure that can also host long duration processes that involve humans, too. This demonstration will implement the enrollment process using jBPM. As the focus is on the use of jBPM, plain old Java objects with stubbed methods will be used as proxies for actual entities.

Tools

To complete this tutorial, you will need:

➢ The jBPM jPDL suite, available from

➢ Eclipse 3.3, available from

➢ The AspectJ development tools (AJDT 1.5 for eclipse 3.3) , available from

➢ Apache ant, available from

The tutorial assumes you have a JDK installed – the tutorial was done with a 1.5 JDK. The tutorial was also done on Windows, so installation procedures may differ for other platforms.

To set up the tools, first install ant. Once ant is installed, unzip the jBPM jPDL suite. Next, copy the eclipse 3.3 SDK zip file you downloaded into the jBPM jPDL suite’s designer directory.

Edit the build.properties file in the designer directory to set the path to the eclipse zip file as:

eclipse.local.path=.

Remove or comment out any other definitions for elipse.local.path. Save the file, then run ant, this will install eclipse. Note the installation process is backwards from most eclipse plugins and environments: jBPM provides an eclipse directory with only their add ons, then have you unzip eclipse into their directory. If you delete their eclipse directory, you will lose the jBPM functionality.

After the ant script finishes, install the AspectJ development tools as an eclipse plugin: simply unzip the AJDT zip file into the root eclipse directory in the designer folder. Note that AspectJ is used to print entry into the Java stubs provided for the tutorial: if you’d like to avoid installing AspectJ, simply added the appropriate logging or System.out.println statements to the stubs to view execution, and adjust the instructions below.

Create the Project

Once the tools are installed, start the jBPM designer by double clicking designer.bat. This will launch eclipse. Once eclipse is launched, create a new jBPM Project.

1. Select File > New Project…

2. In the New Project dialog, expand JBoss jBPM and select Process Project.

3. Name the project Tutorial, the select Finish.

This will create a project configured with everything needed to execute a jBPM process, including a sample process and JUnit test. For this tutorial, we will simply add some additional files to the project.

Add the Sample Code

Grab the sample code from the link in the references section, and unzip it in a temporary location on your hard drive.

Before adding the code to the project, convert the project to an AspectJ project:

1. Select the project in the package explorer.

2. Right click, and select Convert to AspectJ Project from the AspectJ Tools context menu.

Next, create folders for the example code:

1. Select src/main/java in the package explorer.

2. Right click and select New > Folder.

3. Create a folder named aspects.

4. Repeat this process, creating folders named enroll and run.

Finally, drag and drop the source files from the aspects, enroll, and run folders on your hard drive into the corresponding folders in the eclipse package explorer.

Implement the Sample Process

At this point, it is time to outline the process shown in Figure 1.

1. In the package explorer, select the src/main/jpdl folder.

2. Right click and select New > Other…

3. Expand JBoss jBPM and select Process Definition.

4. Click next, and name the process enrollment1.

5. Click the Finish button.

This will create a folder named enrollment1, and will open the processdefinition.xml file in Diagram mode. At this point, you can draw the process diagram. It should look something like this:

[pic]

Note this diagram is much closer to something you could show to a business analyst than a sequence diagram – the essential pieces of the process are shown, with the details needed to implement the process to be embedded in its XML representation (soon to be shown below).

After drawing the diagram, click the source tab. The XML representation of the process should look like the following. Note that you may have to update the namespace for the document to be “urn::jpdl-3.2”:

At this point the states and transitions have been established, but the associated Java interactions and decision logic needs to be added.

To add calls to Java objects in the process definition, jBPM uses the beanshell scripting language and engine to add Java calls to the process execution. For decision logic, according to the JPDL part of the user guide, jBPM uses a “JSP/JSF EL like expression language” for expressing transition guards. I have not found a reference to the exact language, but it seems to align with JSP/JSF EL, through it is embedded slightly differently, e.g. using #{}

The following XML adds the object scripting and condition expressions needed to complete the process.

import enroll.*;

CourseCatalog catalog = new CourseCatalog();

theCourse = catalog.getCourse(courseId, semester);

spaceAvailable = theCourse.spaceAvailable();

import enroll.*;

Registrar registrar = new Registrar();

theStudent = registrar.getStudent(studentId);

theCourse.addStudent(theStudent);

import enroll.*;

Transcript transcript = theStudent.getTranscript();

transcript.addCourse(courseId, semester);

Note that variables are introduced into scripts using the variable tag. Variables can either be variables already present in the process context, or new variables to be introduced in the process context.

Next, examine the RunEnrollment1 class:

package run;

import org.jbpm.context.exe.ContextInstance;

import org.jbpm.graph.def.ProcessDefinition;

import org.jbpm.graph.exe.ProcessInstance;

public class RunEnrollment1 {

public static void main(String[] args) {

try {

//Instantiate a process instance.

ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource("enrollment1/processdefinition.xml");

ProcessInstance instance = new ProcessInstance(processDefinition);

//Set the process data

ContextInstance ctx = instance.getContextInstance();

ctx.setVariable("studentId", "123");

ctx.setVariable("courseId", "CIS764");

ctx.setVariable("semester", "Fall 2007");

//Execute the process

while(!instance.hasEnded()) {

instance.signal();

}

} catch(Throwable t) {

t.printStackTrace();

}

}

}

Some things to note about the process:

1. The process variables are provided to the process instance via the ContextInstance class.

2. The instance is signaled to move it between states.

3. Obviously a real implementation would have to check the process state, distinguish a fully completed process from an aborted process, and handle errors and exceptions.

This is a simple program that executes the process we just defined. To see the process run:

1. Edit log4j.properties in src/main/config, setting the jBPM root logger level to INFO: change log4j..jbpm=DEBUG to log4j..jbpm=INFO.

2. Select RunEnrollment1 (in the src/main/java/run folder) in the package explorer.

3. Right click, then select Run As > Java Application

Your output should look like:

Entering run.RunEnrollment1.main

11:22:28,968 [main] INFO JbpmConfiguration : using jbpm configuration resource 'jbpm.cfg.xml'

11:22:29,078 [main] INFO StaleObjectLogConfigurer : stale object exceptions will be hidden from logging

Entering enroll.CourseCatalog.getCourse

Entering enroll.Course.spaceAvailable

Entering enroll.Registrar.getStudent

Entering enroll.Student.setStudentId

Entering enroll.Course.addStudent

Entering enroll.Student.getTranscript

Entering enroll.Transcript.addCourse

At this point we’ve shown how object interactions to provide a client transaction can be executed using a jBPM process and some simple object scripting.

Modifying the Process

To demonstrate how easy it is to modify a jBPM process, consider the following update to the enrollment process.

[pic]

Figure 3 Updated Enrollment Process

We will start by creating an enrollment2 process – follow the same procedure used to create enrollment1, except name it enrollment2. Copy the XML from enrollment1’s processdefinition.xml file into enrollment2’s processdefinition.xml file, then change the process name to enrollment2 in the enrollment2 file.

In modifying enrollment1 (with the modified process captured in enrollment2), note that:

➢ A check of the student’s standing with the bursar has been added, along with a decision to continue or end the process based on the student’s standing.

➢ A check of the student’s transcript against the prerequisites of the course they enrolling in have been added, along with a decision to continue or end the process based on the student’s standing.

We will make the modifications directly to the XML.

First, add the new states and decisions:

Update the 'next' state in the start-state, and remove the transition script :

Add code to get bursar status:

import enroll.*;

Bursar bursar = new Bursar();

bursarStatus = bursar.inGoodStanding(studentId);

Add conditions to decision transitions:

Similarly, add scripts and conditions for the prereq check:

import enroll.*;

Registrar registrar = new Registrar();

theStudent = registrar.getStudent(studentId);

Transcript transcript = theStudent.getTranscript();

CourseCatalog catalog = new CourseCatalog();

prerequisitesOk = catalog.satisfiedPrerequisites(courseId, transcript);

Finally, modify the check current enrollment transition script:

import enroll.*;

CourseCatalog catalog = new CourseCatalog();

theCourse = catalog.getCourse(courseId, semester);

spaceAvailable = theCourse.spaceAvailable();

You can run the process as shown above, using RunProcess2 in the run package. Your output should look like:

Entering run.RunEnrollment2.main

12:07:29,751 [main] INFO JbpmConfiguration : using jbpm configuration resource 'jbpm.cfg.xml'

12:07:29,851 [main] INFO StaleObjectLogConfigurer : stale object exceptions will be hidden from logging

Entering enroll.Bursar.inGoodStanding

Entering enroll.Registrar.getStudent

Entering enroll.Student.setStudentId

Entering enroll.Student.getTranscript

Entering enroll.CourseCatalog.satisfiedPrerequisites

Entering enroll.CourseCatalog.getCourse

Entering enroll.Course.spaceAvailable

Entering enroll.Registrar.getStudent

Entering enroll.Student.setStudentId

Entering enroll.Course.addStudent

Entering enroll.Student.getTranscript

Entering enroll.Transcript.addCourse

Conclusions

jBPM provides a nice mechanism for implementing process logic and transaction workflows in J2EE applications. It’s combination of graphical process representation and XML scripting provide a nice separation of concerns for collaboration between business analysts and developers.

Resources

jBPM Community Web Site:

jBPM User Guide:

Session Façade Pattern:

TIBCO Business Studio (free BPMN modeling and simulation tool):

Beanshell Scripting Language:

Example project export (with source code):

................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download