Tuesday, May 1, 2012

jBPM tools

jBPM, Drools Guvnor and Web designer

This post will cover:
Here it's an overview of the main free BPM.

What is jBPM

jBPM is a Business Process Management System which in short words means that its main function is to run business processes. 
It's possible to look at business processes as workflows which are basically a group of sequenced activities with inputs and ouputs. 

Let's use an example to better explain how it works:
  1. A TV broadcaster wishes to capture an important event
  2. Afterwards Introduce some information about the recorded media
  3. And then publish the video
    1. To the channel's web site (normal quality)
    2. To the broadcasting station (high quality)
This workflow with 5 activities can been described as a business process using a language understood by jBPM, which is the BPMN2.0 standard (Business Process Modeling Notation).

BPMN2.0 is basically a standardized XML containing information about the visual and execution counterparts of the business process.
This way everyone that knows the BPMN2.0 standard understands the visual representation and business process management systems as the jBPMN can execute it.

The referred workflow can been seen here, modeled using the designer:



jBPM would then run the workflow and do any kind of work demanded by the activities.

In the described example that could mean start capturing the video at 9 pm on a defined feed for the duration of one hour, then ask for human input after the capture process ended and start converting the media to two different file types and finally save them to a specific location.How this is done in detail will be covered next.

So in a nutshell a workflow/business process is described using BPMN2.0, which in turn is generated by the web designer and the jBPM API has the responsibility to run it.

jBPM different components and how they interact

As we've seen jBPM has the task of processing the workflow but it has to get the generated XML description (in the BPMN2.0 standard) from somewhere. This is where the designer and Guvnor repository come in.

If you download jBPM from here and ran the ant install.demo script that's exactly what you'll have.
Drools guvnor is used as the rule based repository where the bpmn2.0 business process representations are stored along with other assets and the designer is a tool to create those assets.

The following image gives a basic scheme how the different components interact:



Running the business process

jBPM has 3 main components:

  1. The knowledge base
  2. The session
  3. The events
To keep things simple, here it is a very short summary of what they do:

The knowledge base is what you use to load the business process. It basically fetch the bpmn2 file and loads so it can be used by the workflow engine. Involves parsing and compiling the process definition.
The session provied methods to interact with the engine, for instance to start running the business process. 
Finally the events is nothing more then an interface which has methods like afterProcessCompleted.

Note: In java events are simulated by the implementation of an interface and that's exactly what this is. You declare a java class which implements this interface and pass it to the caller which in turn will fire the interface's methods.

So let's see some code on how to run a process stored in the guvnor repository:

The code assumes the presence of jBPM library and that drools guvnor has a package called defaultPackage which contains CaptureEventWorkflow business process.

String title = "CaptureEventWorkflow";
String base_url = "http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/webdav/packages/defaultPackage/";
/* building the knowledge base by fetching the bpmn2 process definition from drools guvnor repository */
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newUrlResource(url+title+".bpmn2"), ResourceType.BPMN2);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
/* now that the knowledge base is ready a session is needed to interact with the workflow engine */
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
/* a session might have more than one process to start so providing the process id is required */
ksession.startProcess("defaultPackage.CaptureEventWorkflow");
  

Now let's assume you'd like to keep track of the process execution state. There are a couple of ways to do this, you can inquire jBPM through REST using the following url:

http://{your-address}/gwt-console-server/rs/process/instance/{your-process-instance-id}/activeNodeInfo

Or you could simply pass to the session a class that implements theProcessEventListener interface, like so:

public class EventsClass implements ProcessEventListener {

 public void afterNodeLeft(ProcessNodeLeftEvent arg0) {
  System.out.println("Node with name: "+arg0.getNodeInstance().getNodeName()+" just started");
 }
        ...
}
ksession.addEventListener(new EventsClass());
  
And keep track of the process state using the ProcessEventListener class.

Using the tools within an application

Now that we've covered how to make a business process (using the designer), load it and run it...let's take a look on how we could use these tools in an application.


Adding a new asset to Drools Guvnor (programmatically) 

To add a new asset to droosl guvnor repository it's possible to use the REST API or open the designer in New Asset Mode. 

Using Drools Guvnor REST API


To add a new process, or any kind of asset, to the drools guvnor repository a POST must be done with the asset as a byte stream or atom-xml. More info here.

The following example uses the RestEasy framework which comes by default with jboss.

Note: RestEasy can greatly simplify the REST interactions by allowing the developper to define an interface which will then be used by a proxy to make the requests.

First define the interface with the methods to use:

http://{your.ip}:{your.port}/drools-guvnor/rest/packages/{packageName}/assets  

public interface RepoClient {
 @POST
 @Path("/packages/{packageName}/assets")
 @Consumes(MediaType.APPLICATION_OCTET_STREAM)
 @Produces(MediaType.APPLICATION_ATOM_XML)
        /* The package parameter will replace the {packageName} path field
           the slug will contain the asset name and type (filename)
           the asset parameter is the byte representation   */
 String addAsset(@PathParam("package") String package,@HeaderParam("Slug") String slug, byte[] asset);
}   

To actually do the post of a new process without any elements you can do the following:

RepoClient client = ProxyFactory.create(RepoClient.class,"http://pc-lazevedo:8080/drools-guvnor/rest");
String result = client.addAsset("package", processName.replace(" ", "")+".bpmn2", "".getBytes());  
The result will be a xml with information about the generated process including the asset UUID which might be relevant to hold for later use with the StandAlone Editor.

Opening the Designer in New Asset Mode


By opening the StandAlone editor with the following url, it will automatically create a new asset.

http://{your.ip}:{your.port}/drools-guvnor/org.drools.guvnor.Guvnor/standaloneEditorServlet?client=oryx
With these Get parameters:
  • packageName: the package where the process will be hold
  • categoryName: honestly I don't know what this is for, but I created a category within the previously defined package
  • createNewAsset: true
  • assetName: the business process name (without spaces)
  • assetFormat: bpmn2
Something like:
http://localhost:8080/drools-guvnor/org.drools.guvnor.Guvnor/standaloneEditorServlet?packageName=defaultPackage&categoryName=mycategory&createNewAsset=true&assetName=myprocess&assetFormat=bpmn2&client=oryx

Using the New Asset Mode of the designer is probably the more intuitive one but due to some problems, which will be described next, I preferred to first create the asset through REST and then call the StandAlone Editor on it.

Using the Standalone web designer

In order to embed the drool designer in you application, using the standalone web designer is necessary.
This is where things get a little tricky. Regarding version 2.1 some hacks are necessary to make it work properly.
But let's start on how to open it. To do this you only need to call:


http://{your.ip}:{your.port}/drools-guvnor/org.drools.guvnor.Guvnor/standaloneEditorServlet?assetsUUIDs={asset.UUID}&client=oryx"

The assetsUUIDs is an unique ID that serves to tell what asset the designer should open. After you POST a new asset to the REST API as explained before, the returned xml has this UUID.

As for what I experienced getting this far is quite trivial the problem now is what happens when you try to save the process make changes and then save again. If you are able to do that using the Standalone Editor without any errors, then the following notes can be ignored, if not then this should useful.

Designer, correcting after save changes error

The goal is to force the designer to refresh after saving changes to fix the error when trying to "re-save".
For that there are two options, though only the second one worked for me:

Using the guvnorEditorObject

So after calling the Standalone Designer a JavaScript object  to interact with it should be available. By using a tool like FireBug or Chrome console it's possible to check what methods the object provides. The one that we are interested in is registerAfterSave... which receives as an argument a function to be called after saving the process. There you can simply pass something in the lines of



location=http://{your.ip}:{your.port}/drools-guvnor/org.drools.guvnor.Guvnor/standaloneEditorServlet?assetsUUIDs={asset.UUID}&client=oryx".

Doing location.reload() might not work because, at least with me, the Standalone editor added some Get parameters after loading and refreshing the window results in an error.

Add EventListener to the save button

Well, this is kinda of an ugly solution but honestly it was the one that worked for me. Hold the Standalone Editor in an iframe and on the main window have a javascript function running in 250ms intervals (setInterval) trying to add an event listener to the save button. Something like this:

registerEditorInterval = setInterval(registerEditor, 250);
...

var registerEditor = function()
 {
  if($("#frameEditor").contents().find(".gwt-Button").length>0)
  {
   clearInterval( registerEditorInterval  );
   $("#frameEditor").contents().find(".gwt-Button")[0].addEventListener("click",function(){
    $("#frameEditor")[0].src="<%=request.getParameter("iframeSrc") %>";
    registerIntervals();
    },false);
  }
 };

Getting an image preview of the process

One requirement for the app I'm developing with Guvnor and jBPM is that the user should be able to see the process without the need of opening the designer. For that I needed to "catch" a SVG of the diagram. Fortunetly the Designer has a JavaScript API that provides such method and this is how you can use it:


var svg = frames[0].frames[2].ORYX.EDITOR.getCanvas().getSVGRepresentation();

Again put this inside a function that runs within a defined interval because ORYX.EDITOR takes time to load.

If you would like to resize the SVG to a defined width and height without lossing its aspect ration here it is the math for that:

var svgWidth = parseFloat(svg.getAttribute("width"));
var svgHeight =parseFloat(svg.getAttribute("height"));
var holderWidth = 780;
var holderHeight = 410; 
var svgRacio = svgWidth/svgHeight;
var newY = Math.min(holderHeight,holderWidth/svgRacio);
var newX = svgRacio*newY;
svg.setAttribute("width",newX);
svg.setAttribute("height",newY);
svg.getElementsByTagName("g")[0].setAttribute("transform","scale("+newX/svgWidth+" "+newY/svgHeight+")");


Summing up

First let me start by saying that I was astonished when I realized what these tools can do for FREE. I know it's easy to complain about features that aren't working as well as they should or that things are not as strait forward as they seem in the documentation, BUT these tools are developed in an open source philosophy and have a tone of great features. Obviously, I didn't even scratch the surface with this post but only referred what I found more relevant.

What I think it needs priority attention is the Standalone editor. In my environment after opening the editor if I tried to refresh the window it was in, I'd get an error. The same would happen with multiple consecutive process savings. Without the small "improvements" I referred the Standalone editor simply wasn't working.

Another positive word must go to the support I've received in the jBPM irc channel. I needed help adding a Work Item Definition through the REST API and for two hours I received full attention and got it working.
This is what I consider truly supportive community and is crucial when adopting any kind of software.



9 comments:

  1. really nice post! keep up the good work!

    ReplyDelete
  2. Can I use the web designer against the jbpm runtime and model proceses with forms, table bowsers, decsion input, etc withou engaging with Eclipse nor direct Java coding?

    ReplyDelete
    Replies
    1. I'm sorry but what I said previously it's not 100% correct. You can actually run simple BPMN2.0 business process without needing to write java code. You just need to use the Web Designer to define the business process and then run it through the jbpm console http://localhost:8080/jbpm-console. More info here: http://docs.jboss.org/jbpm/v5.1/userguide/ch11.html#d0e3081

      Delete
  3. The web designer alone doesn't need java behind it, besides setting the jboss and respective packages, as it directly handles the communications with drools guvnor repository. But if you want to actually run it and track things like what activities are being execute in order to fire custom components you certainly need java.
    If by Eclipse you mean the Eclipse designer you won't be needing it if you use the Web Designer

    ReplyDelete
  4. I think that here

    http://docs.jboss.org/jbpm/v5.1/userguide/ch03.html

    Is what I need. My intention is to ue the web designer to model some test processes, use the console and run my models. I would like to avoid the Eclipse and the plugin, any thoughts?

    ReplyDelete
    Replies
    1. For what I understood you wish to use jBPM to do some testing. If that testing requires jBPM to interact with an outside application or run specific code, you will have to implement Java. Nevertheless it's not required to use the Eclipse designer plugin, you can do all the design with the Web Designer and then run the business process with the jBPM console.
      If the testing are simple enough you can implement the activites as script tasks "http://docs.jboss.org/jbpm/v5.1/userguide/ch05.html#d0e1094"

      Delete
    2. Apologies I went into too much trouble but the installer available at

      http://sourceforge.net/projects/jbpm/files/jBPM%205/jbpm-5.2.0.Final/

      contains the jBPM engine, the h2 DB, the console and the web designer Gurvnor. Intalling Ant, the Java SDK and maink both available in he PATH was enough to make this complesx work.

      What I would like to see is a how-to doc or wiki to reboot the jBPM into another database, for instance PostgreSQL or Oracle XE.

      Delete
    3. http://docs.jboss.org/jbpm/v5.3/userguide/ch.installer.html#d0e597

      Delete
  5. Nice Blog Thanks For Sharing post i like your blog because i am interested in JBPM Community.

    Outsource JBPM Development includes more powerful business rules and event integration as well as more support for highly advanced, flexible and latest business processes that are around. It is a result obtained by merging of jBPM project with Drools Flow which is a sub-project of Drools system.

    All your comment for Outsource JBPM Development are welcome.

    Thanks in advance.

    ReplyDelete