Agila BPEL Developer Guide
Agila BPEL is composed of several components interacting altogether. Those components are distributed in several war and jar artifacts:
- agila-engine-x.x.jar: Agila BPEL engine jar groups all server components making the Agila BPEL solution. The engine core, the process deployer, the worklist manager, a user/role manager and few other utilities are packaged in this library. For detailed information on this module (javadoc, test results, ...), see the engine documentation.
- agila-ws-x.x.war: this web application is the web service adapter for the engine. It provides the entry point to the engine using SOAP/HTTP (thanks to Axis) ans simply presents engine's interfaces. See detailed documentation on the web services module documentations.
- agila-client-x.x.jar: this jar file replicates the public engine interfaces on the client side encapsulating the SOAP/HTTP remote call. So engine's interface can be simply called in Java, just as if it was local.
When Agila is just downloaded and installed it is already fully functional but is not setup to invoke your web services. We chose to have a default 'demonstration' setup that just logs the calls to services for testing. You just need to change a line in a configuration file to let Agila BPEL call your web services from their WSDL descriptions. It can then be used to organize the work of people and interact with those services, which is probably the most valuable role of a business process management system.
Making Agila BPEL call your services
Setting up Web Services invocation
Edit agila-configuration.xml that should be located in the common/classes directory of your Tomcat installation. In the engine/implementation node you should find something like:
To enable web services invocation using the deployed WSDL description, just replace this with:
If you don't want to use Web Services invocation and invoke your services in your own proprietary way (for performance or convenience reasons), you will have to implement your own class that Agila BPEL will use for delegating the services calls: a MessageBroker.
Implementing the MessageBroker
MessageBroker is an abstract class that receives all messages from the engine and will resend them to the methods or your subclass. To write your own Message Broker you will have to extend it and therefore implement the two following methods:
protected void asyncSend(String partner, String portType, String operation, Document message); protected Document syncSend(String partner, String portType, String operation, Document message);
The first method should be implemented as an asynchronous invocation so the call should return almost immediately and no result are required. The second method requires a result relevant to the service processing so its execution have to be synchronous.
The parameters provided refer to the service that should be called. The partner (actually partner link) is the name of the business partner who is invokved in this business interaction. The portType and the operation have the same semantic as defined by WSDL . Those parameters are the ones that have been defined in the process BPEL description.
If you are familiar with BPEL, the first method is called when Agila BPEL meets a reply element or an invoke with no output variable. The second is called in case of an invoke with an output variable.
Configuring Agila BPEL to use your MessageBroker
To let Agila BPEL use your Message Broker you just have to modify Agila BPEL's configuration file and put your class in Agila BPEL's classpath. Edit agila-configuration.xml located in Tomcat's conf directory. Change the impl attribute of the element in path agila/engine/implementations/message-broker by replacing the class currently specified with the fully qualified name of your Message Broker.
Then, to add your Message Broker in Agila BPEL classpath, if it's packaged inside a jar file, copy it to:
[TOMCAT_HOME ] /webapps/agila-ws/WEB-INF/lib
If it's just a class file, copy it to:
[TOMCAT_HOME ] /webapps/agila-ws/WEB-INF/classes
Don't forget to copy those files again if you need to reinstall Agila BPEL. Redeploying Agila BPEL webapp would mean deleting all the agila-ws directory.
Calling Agila BPEL
To make calling Agila BPEL easy, we implemented client stubs that wrap the SOAP/HTTP network calls, so you just need to use client classes to invoke Agila BPEL. There is one client stub for each server component, so if you check the package org.apache.agila.bpel.client you will find 5 client stubs (AgilaDeployer, AgilaEngine, AgilaEngineAdmin, AgilaUser and AgilaWorkList) and few java beans that can hold the returned data. Actually the only stub you're probably going to need is AgilaEngine. Others are mostly used by Agila BPEL WorkList UI and Agila BPEL administration console.
Setting your classpath
To use our client module, you'll have to setup your classpath correctly. So additionally to agila-client.jar, include the following libraries :
- axis-1.1.jar : main axis library, needed for web services invocation
- axis-jaxrpc-1.2-alpha-1.jar : needed by Axis
- axis-saaj-1.2-alpha-1.jar : needed by Axis
- commons-discovery-SNAPSHOT.jar : needed by Axis
- commons-logging-1.0.3.jar : our logging library.
Sending a message
There are two ways to send a message to your process using Agila BPEL:
- Send your message to the process endpoint, providing the target partner, portType and operation in the header of the SOAP message.
- Send the message directly to Agila BPEL engine using Agila BPEL specific message format.
Both methods have advantages and disadvantages. The first method is prefered as it is compliant with the WS-BPEL specification, each process have to be available as separate web service. However there are some cases where you just want to send a message without knowing exactly wich process is the target. The second method makes this possible, the engine will know for you which process is the target of your message using the partner, portType and operation provided.
Here is an example of java code that prepares the appropriate SOAP envelope to send to your process using the first method:
String SOAP_ATTRIBUTE_NS = "http://www.apache.org/agila"; String SOAP_ATTRIBUTE_PARTNER = "partner"; String SOAP_ATTRIBUTE_PORTTYPE = "port"; String SOAP_ATTRIBUTE_OPERATION = "operation"; SOAPHeaderElement partnerElmt = new SOAPHeaderElement(envelope.createName( SOAP_ATTRIBUTE_PARTNER, "tws", SOAP_ATTRIBUTE_NS)); partnerElmt.addTextNode(partner); SOAPHeaderElement portElmt = new SOAPHeaderElement(envelope.createName( SOAP_ATTRIBUTE_PORTTYPE, "tws", SOAP_ATTRIBUTE_NS)); portElmt.addTextNode(port); SOAPHeaderElement operationElmt = new SOAPHeaderElement( envelope.createName(SOAP_ATTRIBUTE_OPERATION, "tws", SOAP_ATTRIBUTE_NS)); operationElmt.addTextNode(operation); envelope.addHeader(partnerElmt); envelope.addHeader(portElmt); envelope.addHeader(operationElmt); envelope.addBodyElmt(wsdlMessageBodyElmt);
When you deploy a process in Agila BPEL engine, it is automatically available at the address http://server:port/agila-ws/processname.
Using the java client
The Agila BPEL Engine client class implements two methods to contact the engine, each using one of the message sending mechanism illustrated before. The method you're going to call is:
public Document acknowledge(String partner, String port, String operation, Document message) throws ServiceException, RemoteException; public Document acknowledge(String targetProcess, String namespace, String partner, String port, String operation, Document message) throws ServiceException, RemoteException;
Main parameters are the partnerlink, port type and operation the message is targeted at (actually Agila BPEL engine is 'playing' the role of several web services). From those parameters, the AgilaEngine class is building a SOAP message following a pre-defined XML Schema (message.xsd in the conf directory of your Agila BPEL distribution) and sending it using Axis to the Agila BPEL engine web service.
The last parameter is the body of the message, it's also included in the SOAP message sent to the engine's web service as is. This message should correspond to a pending receive held by the engine. If the engine cannot find any receive waiting for such a message in an instance relevant to the message content (see message correlation in WS-BPEL) it will just be ignored.
Calling other Agila BPEL services
If you want to use the AgilaDeployer client (for exampe to deploy using your own UI) or any other client class, just call them just like you called the engine. The javadoc of the client module should give you a good idea of which methods are available, what they are doing and how to call them.
Agila BPEL listener
Agila BPEL is running inside a web container as a server, it's logging all actions properly but it can be sometimes hard to react to server errors automatically only with logging. We therefore implemented a simple listener interface that is notified when Agila BPEL meets a problem.
To add a listener of your own that can be notified of such events, you just need to complete the following steps: