In this blog I will add relevant materials for the courses I teach at the University of Coimbra, Portugal

sábado, 12 de novembro de 2011

Using Orchestration in JBoss ESB

NOTE: Creating a jBPM 3 project is not the only way of doing what I explain here. It is possible to write an orchestration process inside a JBoss ESB project.

NOTE: You may need to install the following software and configure a jBPM runtime before being able to follow this tutorial (check version 3 here:http://sourceforge.net/projects/jbpm/files/). This serves only for the development in the JBoss Developer Studio. Don't point to your JBoss ESB during installation of this jbpm, because JBoss ESB will break. Right now I can see the following in my preferences of JBoss Developer Studio:

To create a project for a jBPM process do as follows:

This will create a lot of files that can provide you some help, including a sketch of a process. We will take advantage of it! As you can see in the following figure, we have only three nodes. In the middle one we will invoke an ESB service. In the first and in the last we will invoke local handlers: com.sample.action.MessageActionHandler andc om.sample.action.MessageActionHandler2. In the second one we will display results that we got from the ESB service invoked before. Here is the picture of the process:

The code looks as follows:

package com.sample.action;import org.jbpm.graph.def.ActionHandler;import org.jbpm.graph.exe.ExecutionContext;public class MessageActionHandler implements ActionHandler {private static final long serialVersionUID = 1L;/** * The message member gets its value from the configuration in the * processdefinition. The value is injected directly by the engine. */String message;/** * A message process variable is assigned the value of the message * member. The process variable is created if it doesn't exist yet. */public void execute(ExecutionContext context) throws Exception {System.out.println("MessageActionHandler: " + message);}}

package com.sample.action;import org.jbpm.graph.def.ActionHandler;import org.jbpm.graph.exe.ExecutionContext;public class MessageActionHandler2 implements ActionHandler {private static final long serialVersionUID = 1L;/** * The message member gets its value from the configuration in the * processdefinition. The value is injected directly by the engine. */String message;/** * A message process variable is assigned the value of the message * member. The process variable is created if it doesn't exist yet. */public void execute(ExecutionContext context) throws Exception {System.out.println("Inside MessageActionHandler2");System.out.println(context.getContextInstance().getVariable("theBody"));}}

and finally the process that corresponds to the figure above. One should carefully note the correspondence of names of the variables between jBPM and ESB and notice the access that we do to “theBody” in the MessageActionHandler2:

<?xmlversion="1.0"encoding="UTF-8"?><process-definitionxmlns="urn:jbpm.org:jpdl-3.2"name="simple"><start-statename="start"><transitionname="to_state"to="first"><actionname="action"class="com.sample.action.MessageActionHandler"><message>Going to the first state!</message></action></transition></start-state><nodename="first"><actionname="esbAction"class="org.jboss.soa.esb.services.jbpm.actionhandlers.EsbActionHandler"><esbCategoryName>My_Demo_Service</esbCategoryName><esbServiceName>Hello</esbServiceName><bpmToEsbVars><mappingbpm="myname"esb="whoami"/><mappingbpm="theBody"esb="BODY_CONTENT"/></bpmToEsbVars><esbToBpmVars><mappingesb="BODY_CONTENT"bpm="theBody"/></esbToBpmVars></action><transitionname="to_end"to="end"></transition></node><end-statename="end"><eventtype="node-enter"><actionname="action"class="com.sample.action.MessageActionHandler2"></action></event></end-state></process-definition>

In the Deployment tab of the process we can define some details, including the classes we need (this is mandatary).To deploy the process in the JBoss ESB server we pick the following option in the menus and save it to some directory as in the following two figures:

Then we deploy the process in the JBoss web management console. The URL ishttp://localhost:8080/jbpm-console and we log in with the username and password admin/admin. We upload the file p.par that we saved in the previous steps (selecting Deploy in the following figure):

We then follow to the ESB project:

It is very simple. It only has three entry points (queues): two serve to start the jBPM process (as usual a JMS and an ESB one) and are the entry point to the service My_Demo_Service/Start, whereas the last one is invoked by the process node called “first” (see the figure above) and is the entry point to the service My_Demo_Service/Hello. One should notice the property mep=”OneWay”. It means that the pipeline is unidirectional. No reply is expected. In the other service (My_Demo_Service/Hello), the pipeline responds to the invoker, in the case the process node “first”. How? This is automatic. The return message in the last action of the pipeline is the reply to the node “first”. You can then see how the contents of the message are converted back to the BPM side on the definition of the node “first” in the process. Let’s look at the jboss-esb.xml:

<?xmlversion="1.0"?><jbossesbparameterReloadSecs="5"xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd http://anonsvn.jboss.org/repos/labs/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.3.0.xsd"><providers><jms-providerconnection-factory="ConnectionFactory"name="JMS"><jms-busbusid="startGwChannel"><jms-message-filterdest-name="queue/bpm_demo_start_Request_gw"dest-type="QUEUE"/></jms-bus><jms-busbusid="startEsbChannel"><jms-message-filterdest-name="queue/bpm_demo_start_Request_esb"dest-type="QUEUE"/></jms-bus><jms-busbusid="HelloEsbChannel"><jms-message-filterdest-name="queue/bpm_hello_Request_esb"dest-type="QUEUE"/></jms-bus></jms-provider></providers><services><servicecategory="My_Demo_Service"description="BPM Demo Orchestration: Use this service to start a process instance"name="Start"><listeners><jms-listenerbusidref="startGwChannel"is-gateway="true"name="JMS-Gateway"/><jms-listenerbusidref="startEsbChannel"name="ESB-Listener"/></listeners><actionsmep="OneWay"><actionclass="action.InitializeListenerAction"name="init"process="init"/><actionclass="org.jboss.soa.esb.services.jbpm.actions.BpmProcessor"name="lottery"><propertyname="command"value="StartProcessInstanceCommand"/><propertyname="process-definition-name"value="simple"/><propertyname="esbToBpmVars"><mappingbpm="myname"esb="userName"/><mappingbpm="theBody"esb="BODY_CONTENT"/></property></action></actions></service><servicecategory="My_Demo_Service"description="BPM Demo Orchestration: Use this service to invoke the hello"name="Hello"><listeners><jms-listenerbusidref="HelloEsbChannel"name="ESB-Listener"/></listeners><actions><actionclass="action.MyListenerAction"name="helloaction"process="hello"/></actions></service></services></jbossesb>

We need two listener actions. The initializer expects a message of the form:single_name_no_spaces message perhaps with several spacesPay special attention to the names of the variables, which correspond to what we have in the “simple” process above.

package action;/** JBoss, Home of Professional Open Source* Copyright 2006, JBoss Inc., and others contributors as indicated* by the @authors tag. All rights reserved.* See the copyright.txt in the distribution for a* full listing of individual contributors.* This copyrighted material is made available to anyone wishing to use,* modify, copy, or redistribute it subject to the terms and conditions* of the GNU Lesser General Public License, v. 2.1.* This program is distributed in the hope that it will be useful, but WITHOUT A* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.* You should have received a copy of the GNU Lesser General Public License,* v.2.1 along with this distribution; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,* MA 02110-1301, USA.** (C) 2005-2006,* @author JBoss Inc.*/import org.jboss.soa.esb.actions.AbstractActionLifecycle;import org.jboss.soa.esb.helpers.ConfigTree;import org.jboss.soa.esb.message.Message;public class InitializeListenerAction extends AbstractActionLifecycle{protected ConfigTree_config;public InitializeListenerAction(ConfigTree config) {_config = config;}public Message init(Message message) throws Exception{System.out.println("---------------------------------- Initialize ----------------------------------");String msgbody = (String) message.getBody().get();String [] vec = msgbody.split(" ", 2);String user = vec[0];String text = vec[1];message.getBody().add("userName", user);message.getBody().add(text);System.out.println("Initialize got the following data. User = " + user + ". Text = " + text);System.out.println("-------------------------------- end initialize --------------------------------");return message;}}

package action;/** JBoss, Home of Professional Open Source* Copyright 2006, JBoss Inc., and others contributors as indicated* by the @authors tag. All rights reserved.* See the copyright.txt in the distribution for a* full listing of individual contributors.* This copyrighted material is made available to anyone wishing to use,* modify, copy, or redistribute it subject to the terms and conditions* of the GNU Lesser General Public License, v. 2.1.* This program is distributed in the hope that it will be useful, but WITHOUT A* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.* You should have received a copy of the GNU Lesser General Public License,* v.2.1 along with this distribution; if not, write to the Free Software* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,* MA 02110-1301, USA.** (C) 2005-2006,* @author JBoss Inc.*/import org.jboss.soa.esb.actions.AbstractActionLifecycle;import org.jboss.soa.esb.helpers.ConfigTree;import org.jboss.soa.esb.message.Message;public class MyListenerAction extends AbstractActionLifecycle{protected ConfigTree_config;public MyListenerAction(ConfigTree config) {_config = config;}public Message hello(Message message) {System.out.println("---------------------------------- hello ----------------------------------");String who = (String) message.getBody().get("whoami");String textinbody = (String) message.getBody().get();message.getBody().add("Hello " + who + ". You said: " + textinbody);System.out.println("-------------------------------- end hello --------------------------------");return message;}}

Just to help you with the configurations I also add the jbm-queue-service.xml and the deployment.xml: