Combining Mule with a BPEL Engine

18 Dec

In my current project we are going to need a BPEL engine besides our Mule CE implementation. Actually, we will use Mule for our stateless communication between systems and use BPEL for the stateful processes. One of the possible frameworks to use as a BPEL engine is Apache ODE. In this post I will show you how you can start a BPEL process in Apache ODE with Mule. As you will see, it is merely a combination of posts I made earlier, but I think it is nice to have the complete thing in one post.

Step 0: Assumptionss
Assumed is:

  • an Apache ODE instance (preferably deployed in Tomcat)
  • Maven 2.2.0
  • JDK 1.6
  • Netbeans 6.8,
  • Mule CE 2.2.2-SNAPSHOT

Of course, it might work with other version but these are the versions I used.

Step 1: Create a running BPEL process

The first step is to create a running BPEL example. I use the latest version of Netbeans for that and
this post. To make use of the SOA wizards in the new Netbeans you have to enable this as an extension. To create the BPEL example perform the following steps:

  1. Creating a new BPEL module named ‘TextModule’
  2. Add a WSDL to the project
  3. Add a WSDL that describes the web service (remark: I wasn’t able to create a document-literal web service with the wizard in Netbeans so I edited the source by hand afterwards).

  4. Add a BPEL process to the module, name it ‘txtLengthProcess’

    This created process is empty so add functionality to it by following the guidelines as in this post. I ended up with the following process diagram:

    The mapping in the assignment step looks like this:

    I created the necessary variables to assign the values to in the ‘receive’ and ‘reply’ step.

  5. Create a file ‘deploy.xml’
    My file has the following content:

    <?xml version="1.0" encoding="UTF-8"?>
    <deploy xmlns="http://www.apache.org/ode/schemas/dd/2007/03"
        xmlns:pns="http://www.pascalalma.net/TxtLengthProcess"
        xmlns:wns="http://www.pascalalma.net/TxtLengthService">
    
        <process name="pns:TxtLengthProcess">
            <active>true</active>
            <provide partnerLink="TxtLengthPartnerLink">
                <service name="wns:TxtLengthServiceService" port="TxtLengthServicePort"/>
            </provide>
        </process>
    </deploy>
    
  6. Deploy it to the Tomcat instance that is running Apache ODE
    To deploy the process create a directory named ‘TxtLengthService’ under ‘/webapps/ode/WEB-INF/processes’. Copy the three files (deploy.xml, TxtLengthProcess.bpel and TxtLengthService.wsdl) to this directory. When your deployment was successful you’ll see the ‘TxtLengthService.wsdl’ at http://localhost:8080/ode/services/listServices:
  7. (Optional) you can test the service with SoapUI
    With a successful request-response you will get the following result:
  8. If you want more details on how to set up a Apache ODE service have look here. It goes into more detail then I am in this post.

    Step 2: Generate Java client for web service to start ODE process

    We use Metro for this because we had some bad experiences when using CXF for this. It is described here how to do this in combination with Maven.
    I created a new Maven project. When the client is generated you can test it with a test class like this:

    package net.pascalalma.ws.test;
    
    import net.pascalalma.txtlengthservice.TxtLengthService;
    import org.junit.Test;
    
    /**
     *
     * @author pascal
     */
    public class TestService {
    
        @Test
         public void testIt()
        {
            TxtLengthService service = new TxtLengthService();
    
            String value = service.getTxtLengthServiceSOAP11PortHttp().txtLengthOperation("Pascal Alma");
    
            System.out.println("result = " + value);
        }
    }
    

    Step 3: Create the Mule project

    To let Mule call the BPEL process I created a new Maven project that is able to test the call with a Mule client. The used ‘ode-test-config.xml’ looks like:

    <?xml version="1.0" encoding="UTF-8"?>
    <mule xmlns="http://www.mulesource.org/schema/mule/core/2.2"
           xmlns:spring="http://www.springframework.org/schema/beans"
           xmlns:test="http://www.mulesource.org/schema/mule/test/2.2"
           xmlns:vm="http://www.mulesource.org/schema/mule/vm/2.2"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="
           http://www.mulesource.org/schema/mule/core/2.2 http://www.mulesource.org/schema/mule/core/2.2/mule.xsd
           http://www.mulesource.org/schema/mule/test/2.2 http://www.mulesource.org/schema/mule/test/2.2/mule-test.xsd
           http://www.mulesource.org/schema/mule/vm/2.2 http://www.mulesource.org/schema/mule/vm/2.2/mule-vm.xsd
           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
    
        <model name="mule-ode">
            <service name="start">
                <inbound>
                    <vm:inbound-endpoint path="msg-in" synchronous="true"/>
                </inbound>
                <component class="net.pascalalma.mule.BpelProcessClient" />
            </service>
        </model>
    </mule>
    

    The created component class that handles the call to the SOAP client looks like:

    package net.pascalalma.mule;
    
    import net.pascalalma.txtlengthservice.TxtLengthService;
    
    /**
     *
     * @author pascal
     */
    public class BpelProcessClient {
    
        public String callProcess(String request) {
            return new TxtLengthService().getTxtLengthServiceSOAP11PortHttp().txtLengthOperation(request);
        }
    }
    

    And the used test class looks like:

    package net.pascalalma.mule;
    
    import org.junit.Test;
    import org.mule.api.MuleException;
    import org.mule.api.MuleMessage;
    import org.mule.module.client.MuleClient;
    import org.mule.tck.FunctionalTestCase;
    
    public class BpelProcessClientTest extends FunctionalTestCase {
    
        private MuleClient client = null;
    
        protected MuleClient getClient() {
            try {
                if (client == null) {
                    client = new MuleClient();
                }
            } catch (MuleException e) {
                throw new RuntimeException(e);
            }
            return client;
        }
    
       protected final String getConfigResources() {
            return "config/ode-test-config.xml ";
        }
    
        @Test
        public void testBpelTest() throws MuleException
        {
            MuleMessage msg = getClient().send("vm://msg-in", "123456789012345", null);
            System.out.println("payload = " + msg.getPayload());
        }
    }
    

    When the test class is executed this results in the following output:

    **********************************************************************
    * Mule ESB and Integration Platform *
    * Version: 2.2.2-SNAPSHOT Build: 15252 *
    * MuleSource, Inc. *
    * For more information go to http://mule.mulesource.org *
    * *
    * Server started: 12/17/09 8:34 PM *
    * Server ID: 3d3eb71b-eb43-11de-bca6-7b92b51f04e0 *
    * JDK: 1.6.0_17 (mixed mode) *
    * OS encoding: MacRoman, Mule encoding: UTF-8 *
    * OS: Mac OS X (10.6.2, x86_64) *
    * Host: macbook-van-pascal-alma.local (192.168.1.204) *
    * *
    * Agents Running: None *
    **********************************************************************
    INFO 2009-12-17 20:34:50,730 [main] org.mule.module.client.MuleClient: Using existing MuleContext: org.mule.DefaultMuleContext@1d6b6c55
    INFO 2009-12-17 20:34:50,756 [main] org.mule.transport.vm.VMMessageDispatcher: Connected: endpoint.outbound.vm://msg-in
    payload = 15
    INFO 2009-12-17 20:34:51,784 [main] org.mule.transport.vm.VMConnector: Removing listener on endpointUri: vm://msg-in
    INFO 2009-12-17 20:34:51,784 [main] org.mule.transport.vm.VMMessageReceiver: Disconnected: VMMessageReceiver{this=5a56182f, receiverKey=msg-in, endpoint=vm://msg-in}
    INFO 2009-12-17 20:34:51,785 [main] org.mule.component.DefaultJavaComponent: Stopping: org.mule.component.DefaultJavaComponent component for: SedaService{start}
    INFO 2009-12-17 20:34:51,785 [main] org.mule.model.seda.SedaService: Mule Service start has been stopped successfully
    INFO 2009-12-17 20:34:51,787 [main] org.mule.transport.vm.VMConnector: Stopping: VMConnector{this=75d709a5, started=true, initialised=true, name=’connector.VM.0′, disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=true, supportedProtocols=[vm], serviceOverrides=null}
    INFO 2009-12-17 20:34:51,787 [main] org.mule.transport.vm.VMConnector: Disconnected: VMConnector{this=75d709a5, started=false, initialised=true, name=’connector.VM.0′, disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[vm], serviceOverrides=null}
    INFO 2009-12-17 20:34:51,787 [main] org.mule.transport.vm.VMConnector: Stopped: VMConnector{this=75d709a5, started=false, initialised=true, name=’connector.VM.0′, disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[vm], serviceOverrides=null}
    INFO 2009-12-17 20:34:51,788 [main] org.mule.util.queue.TransactionalQueueManager: Stopping ResourceManager
    INFO 2009-12-17 20:34:51,788 [main] org.mule.util.queue.TransactionalQueueManager: Stopped ResourceManager
    INFO 2009-12-17 20:34:51,788 [main] org.mule.transport.vm.VMConnector: Disposing: VMConnector{this=75d709a5, started=false, initialised=true, name=’connector.VM.0′, disposed=false, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[vm], serviceOverrides=null}
    INFO 2009-12-17 20:34:51,788 [main] org.mule.transport.vm.VMMessageDispatcher: Disconnected: VMMessageDispatcher{this=1915470e, endpoint=vm://msg-in, disposed=false}
    INFO 2009-12-17 20:34:51,788 [main] org.mule.transport.vm.VMConnector: Disposed: VMConnector{this=75d709a5, started=false, initialised=false, name=’connector.VM.0′, disposed=true, numberOfConcurrentTransactedReceivers=4, createMultipleTransactedReceivers=true, connected=false, supportedProtocols=[vm], serviceOverrides=null}
    INFO 2009-12-17 20:34:51,789 [main] org.mule.config.spring.MuleApplicationContext: Closing org.mule.config.spring.MuleApplicationContext@356f144c: display name [org.mule.config.spring.MuleApplicationContext@356f144c]; startup date [Thu Dec 17 20:34:49 CET 2009]; root of context hierarchy
    INFO 2009-12-17 20:34:51,789 [main] org.springframework.beans.factory.support.DefaultListableBeanFactory: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@29abc69: defining beans [customEditorConfigurer,_muleObjectNameProcessor,_mulePropertyPlaceholderProcessor, _muleSimpleRegistryBootstrap,_muleNotificationManager,_muleConfiguration,._muleNotificationManager: notification.1,._muleNotificationManager:notification.2,._muleNotificationManager:notification.3, ._muleNotificationManager:notification.4,._muleNotificationManager:notification.5,._muleNotificationManager: notification.6,._muleNotificationManager:notification.7,._muleNotificationManager:notification.8, ._muleNotificationManager:notification.9,._muleNotificationManager:notification.10,_muleSystemModel, _muleQueueManager,_muleSecurityManager,_muleProperties,_muleEndpointFactory,_muleStreamCloserService, _defaultThreadingProfile,_defaultMessageDispatcherThreadingProfile,_defaultMessageRequesterThreadingProfile, _defaultMessageReceiverThreadingProfile,_defaultServiceThreadingProfile,_defaultRetryPolicyTemplate, mule-ode,start,.start:inbound.11,.start:inbound.11:inbound-endpoint.12,.start:component.13]; root of factory hierarchy
    INFO 2009-12-17 20:34:51,995 [main] org.mule.DefaultMuleContext:
    **********************************************************************
    * Mule shut down normally on: 12/17/09 8:34 PM *
    * Server was up for: 0 days, 0 hours, 0 mins, 1.318 sec *
    **********************************************************************
    Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.103 sec

    So by finishing this post you should be able to execute a (simple) BPEL process in Apache ODE by using Mule. However, it is not certain we will use Apache ODE like this. I think we would like Intalio|server more because of the handy features/tooling they have added to Apache ODE.

Follow

Get every new post delivered to your Inbox.

Join 97 other followers

%d bloggers like this: