JBoss-jBPM-BPEL-User-Guide

Document Sample
JBoss-jBPM-BPEL-User-Guide Powered By Docstoc
					JBoss jBPM BPEL 1.0
User Guide 1 Introduction............................................................................................................................. 2 1.1 BPEL overview................................................................................................................. 2 1.2 The service-oriented architecture..................................................................................... 2 1.3 Industry support ............................................................................................................... 2 1.4 OASIS Technical Comittee .............................................................................................. 3 1.5 Components and dependencies ...................................................................................... 3 Note: the purpose of BPEL .................................................................................................... 3 References............................................................................................................................. 3 2 Getting Started ....................................................................................................................... 5 2.1 Getting JBoss jBPM BPEL extension............................................................................... 5 2.2 Getting JBoss Application Server..................................................................................... 5 2.3 Getting Apache Ant .......................................................................................................... 5 2.4 Service setup ................................................................................................................... 6 3 Tutorial.................................................................................................................................... 8 3.1 Example setup ................................................................................................................. 8 3.2 Hello World Example........................................................................................................ 9 3.3 ATM Example ................................................................................................................ 22

1

JBoss jBPM BPEL 1.0

1 Introduction
1.1 BPEL overview
BPEL stands for Business Process Execution Language. Originally authored by a small charter of influential vendors, it is currently under standardization at OASIS (1). BPEL is an XML language for describing long-running interactions of web services centrally orchestrated by a coordinator, and exposing them as new web services. The coordinator makes decisions by interpreting «business processes» (read the note on the purpose of BPEL). BPEL has quickly become the dominant specification to standardize integration logic and process automation between Web services. It has bypassed a number of alternative specifications such as BPML and WSCI, and became a real candidate to drive the existing web service infrastructure into process-centric applications based on a service-oriented architecture.

1.2 The service-oriented architecture
Recent products and strategies announced by IBM, BEA, Microsoft and Oracle are targeted at the service-oriented architecture, SOA (2). SOA helps enterprises modify their infrastructure «on the flight», according to changes in the environment. Under this model, new applications are developed by wiring together software components, or services, that expose reusable business functions (3). Leveraging more from existing assets is a real business challenge right now. The idea of enabling legacy applications to be deployed as (web) services and orchestrated across platforms is a key part of why BPEL is becoming a cornerstone of SOA (4).

1.3 Industry support
• •

IBM and BEA worked together in a proposal named BPELJ, with the purpose of extending BPEL to integrate it more closely with the J2EE platform (5) BEA will provide full support for BPELJ in the release of WebLogic Integration following version 8.1 (6). In addition, it has submitted a specification request (JSR 207) of an annotated Java syntax and APIs for developing business processes in Java and deploying them in J2EE containers (7) IBM already offers that support as part of WebSphere Business Integration Server 5.1 (8) Microsoft BizTalk 2004 includes BPEL import/export capabilities (9) Oracle acquired Collaxa, a company that focused on implementing the standard since 2002 (10) Siebel formed an alliance with Active Endpoints, a company that supplies an open source BPEL engine (under GPL) (11)

• • • •

2

JBoss jBPM BPEL 1.0

1.4 OASIS Technical Comittee
Despite its acceptance, it is recognized that BPEL remains an emerging technology. Challenges await those interested in near-term deployment. Version 1.1, dated May 5, 2003, contains plenty of gaps and ambiguities that should come as no surprise, considering these factors:
•

The separate roots of the specification (12)
o o

Microsoft pioneered the adoption of Pi-Calculus with XLANG IBM rejuvenated the use of Petri Nets with WSFL

•

The immaturity of the overall Web services «stack»

The OASIS WS-BPEL technical committee is working diligently to overcome these deficiencies. It released the first draft of version 2.0 in July 30, 2004 and continues to publish drafts periodically as it resolves issues. Version 2.0 is receiving contributions from a much broader community and becoming the standard everyone wants it to be.

1.5 Components and dependencies
Component Partner relationships Data representation Data manipulation Message exchange Flow-control structures Scoping:
• • •

Depends on WSDL 1.1 port types XML Schema 1.0 XPath 1.0 WSDL 1.1 messages -

Compensation ("undoing") Error handling Event processing

-

Note: the purpose of BPEL
The purpose of BPEL I present here actually tries to concatenate my favorite three answers to what the purpose of BPEL is:
• • •

Defining the composition of (web) services into new (web) services (13) Describing message exchange flows between Web services within stateful, longrunning interactions (14) Describing business process behavior based on Web services (15)

References
1. OASIS Web Services Business Process Execution Language TC

3

JBoss jBPM BPEL 1.0 2. Service-Oriented Architecture 3. IBM Refocuses WebSphere on Service-Oriented Architectures 4. IBM Unveils First SOA Products, Services 5. BEA, IBM Propose Java/BPEL 'Marriage' 6. BEA - BPEL & BPELJ 7. JSR 207: Process Definition for Java 8. WebSphere Business Integration Server Foundation 9. MSDN - Importing BPEL4WS 10. Oracle BPEL Process Manager 11. Active Endpoints - Siebel Alliance 12. A Convergence Path toward a Standard BPM Stack 13. BPEL for Programmers and Architects 14. BPEL4WS Version 1.1 15. Introduction to the ActiveBPEL Engine

4

JBoss jBPM BPEL 1.0

2 Getting Started
2.1 Getting JBoss jBPM BPEL extension
The releases of the jBPM BPEL extension can be found in the jBPM download page. The file jbpm-bpel-<version>.zip contains the jBPM BPEL extension software (sources and binaries) and the libraries it depends on. Note, the BPEL extension uses JBoss jBPM 3.0 as a library. You do not have to download the full jBPM distribution, as the BPEL extension distribution already contains the library. However, it is highly recommended that you get it since the BPEL extension, as it name implies, is meant to complement jBPM. Once the archive is downloaded, unpack it to a suitable location on your machine. It should all unpack into a single directory named jbpm-bpel-<version>. Make sure you don't use a directory which has any spaces in the path (such as the Program Files directory on Windows) as this may cause problems. Alternatively, you can get the software from CVS with the following parameters. Once you have access, look for module jbpm.bpel. Parameter Connection type User Password Host Port Repository path Label Value pserver anonymous (when prompted for a password, just press enter) cvs.sourceforge.net 2401 (the default) /cvsroot/jbpm :pserver:anonymous@cvs.sourceforge.net:/cvsroot/jbpm

2.2 Getting JBoss Application Server
The deployment model of the BPEL extension is currently based on JBoss. We plan to provide an alternative model that is not tied to any particular application server. For the moment, only JBoss is supported. The BPEL extension exposes processes as web services using J2EE 1.4 port components. Therefore, you need JBoss 4.x. The extension has been tested with version 4.0.2 and 4.0.3SP1. For instructions on getting JBoss AS, see downloading and installing JBoss.

2.3 Getting Apache Ant
Ant scripts dramatically simplify the development and deployment of BPEL proceses. The tutorial section assumes you have installed Ant and are able to execute targets from the command line. Furthermore, you need Ant to build the jBPM BPEL service archive. 5

JBoss jBPM BPEL 1.0 For directions on getting Ant, see installing Ant. Important note. If you are using a standalone distribution of Ant, you need to install the JUnit library in order to run junit tasks. Just copy the JAR from the lib/junit directory of the jBPM BPEL distribution to the lib directory of your Ant installation.

2.4 Service setup
The jBPM BPEL managed bean (MBean) contains the libraries and configuration files required to execute BPEL processes. The application assembler packages these resources in a service archive and deploys them to JBoss AS. The following sections describe how to configure, package and deploy the service to JBoss AS.

2.4.1 Configuration
The service configuration files reside in directory src/resources/jbpm-bpel.sar. They fall into two categories: persistence and jBPM settings. 2.4.1.1 Persistence configuration Starting from version 1.0 alpha 3, the BPEL extension incorporates the jBPM persistence model, described in chapter 6 of the jBPM user guide. jBPM uses Hibernate as its objectrelational mapper. The next table describes the configuration files related to persistence. File Notes Contains database connection properties, among other values. Since the service runs inside an application server, you should configure Hibernate to obtain connections from a data source registered in JNDI. Refer to chapter 4 of the Hibernate manual for instructions on how to set them. Supplies parameters for the default second-level cache provider. Section 20.2 of the Hibernate reference describes the use of caches to improve performance. Administrators often prefer to separate data sources from services and applications. To facilitate evaluation of jBPM BPEL, however, we include a data source deployment descriptor with the service: jbpm-bpel-ds.xml. Apart from the preconfigured data source, this file also describes a Hypersonic MBean. When deployed, this MBean creates a lightweight database within the same VM. The database is written to disk when JBoss stops, but no other process can access it. 2.4.1.2 jBPM settings The file jbpm.properties gathers the jBPM settings. The following table summarizes the relevant properties for the BPEL extension. Property Notes

hibernate.properties

ehcache.xml

6

JBoss jBPM BPEL 1.0 The JNDI name to which the service binds the jBPM session factory The name of an alternate XML resource that lists the mapping files to consider The name of an alternate properties resource with database connection values

jbpm.session.factory.jndi.name

jbpm.hibernate.cfg.xml

jbpm.hibernate.properties

2.4.2 Packaging
Once you have set the configuration, building the service archive is easy. Locate the file build.properties in the base directory of your jBPM BPEL installation. Modify the values therein to match the directory where you installed JBoss.
jboss.home=/my/jboss/home To build the archive, locate build.xml in the same directory and run the target that

corresponds to your JBoss AS version. Target
build.service.402 build.service.403

Version 4.0.2 4.0.3 SP1

If all goes well you should see messages much like the following:
build.service.archive: [jar] Building jar: ...\jbpm-bpel.sar

2.4.3 Deployment
Start JBoss in the default server configuration (see server configurations). Then look for the jbpm-bpel.sar file you just packaged within directory build. Deploy jbpm-bpel.sar to JBoss by copying it to the deploy directory of the default server configuration. JBoss is now ready to deploy BPEL applications. We will explore the concept of BPEL application in the tutorial. Expect to see a lot of Hibernate output. If the deployment succeeds you will see this message near the end:
22:59:33,781 INFO [JbpmService] binding JbpmSessionFactory 'java:/jbpm/BpelSessionFactory' into JNDI...

7

JBoss jBPM BPEL 1.0

3 Tutorial
3.1 Example setup
The best way to get acquainted with BPEL is to see it in action. For this reason, we included some examples that will help you get started quickly. At this point, you should have the jBPM BPEL service running inside JBoss. If you don't, please check out the Getting Started guide first.

3.1.1 Getting the Java Web Services Development Pack
The BPEL extension relies on the Web Services for J2EE (WS4EE) model for exposing the functionality a BPEL process delivers. Some of the server artifacts required for a WS4EE deployment can be automatically generated from WSDL documents. JBoss recommends the wscompile tool from the Java Web Services Development Pack. For details and installation instructions, see Java WSDP.

3.1.2 Defining the environment
The resources related to each example in the doc/examples/<example-name> directory of the jBPM BPEL distribution. Starting with version 1.0 alpha 4, a web application deployed along the jBPM BPEL service performs administrative tasks such as creating the table schema and deploying a process definition. The example base directory contains build.xml, an Ant script that will help you throughout the tutorial. The script needs to be aware of your environment. Modify the values in build.properties to match the directories where you installed jBPM BPEL, JBoss and JWSDP respectively.
jbpm.bpel.home=/my/bpel/home jboss.home=/my/jboss/home wsdp.home=/my/wsdp/home

3.1.3 Creating the database schema
Before you deploy process definitions to the database, you need to create the jBPM schema. To ease things we included a create-schema task in the build file of each example. You only need to run it once. Hibernate will emit a few log messages. You will see the following output in the server console at the end of a successful schema creation.
00:28:07,218 INFO [DatasourceConnectionProvider] Using datasource: java:/JbpmBpelDS 00:28:07,265 ERROR [SchemaExport] Unsuccessful: alter table JBPM_NODE add constraint FK_ACTIVITY_COMPOSITE foreign key (COMPOSITEACTIVITY_) references JBPM_NODE 00:28:07,265 ERROR [SchemaExport] Constraint already exists in statement [alter table JBPM_NODE add constraint FK_ACTIVITY_COMPOSITE foreign key (COMPOSITEACTIVITY_) references JBPM_NODE] 00:28:07,281 INFO [SchemaExport] schema export complete

8

JBoss jBPM BPEL 1.0 Those error entries seem disturbing but are, in fact, harmless. The schema is created correctly.

3.1.4 Replacing the default XML implementations
There are known issues with the XML implementations in JSE 1.4.2 and 1.5.0. The solution is different in each case so we'll examine them separately. 3.1.4.1 JSE 1.4.2 The TrAX as well as the JAXP implementations have issues and must be replaced using the endorsed standards override mechanism. The simplest way is to copy the libraries from <jbpmbpel-home>/lib/xalan and <jbpm-bpel-home>/lib/xerces to <java-home>/lib/endorsed. Here, <java-home> refers to the directory where the runtime software is installed, which is the top-level directory of the JRE or the jre directory in the JDK. 3.1.4.2 JSE 1.5.0 Only the TrAX implementation has issues. You can replace it either using the endorsed standards override mechanism as described above or (preferrably) uncommenting the path element that references Xalan in the Ant script corresponding to the example.
<path id="servicegen.classpath"> ... <!-- uncomment to replace the TrAX implementation in JSE 1.5.0 <pathelement location="${jbpm.bpel.home}/lib/xalan/xalan-2.6.0.jar"/> --> </path>

3.2 Hello World Example
In this tutorial, we will develop a very simple BPEL process that receives a message carrying the name of a person, composes a greeting phrase containing the name, and then replies with a message carrying the greeting. The files related to this example can be found in the download package, in directory doc/examples/hello. The following picture represents the HelloWorld process.

9

JBoss jBPM BPEL 1.0

1 Create the BPEL document
The first step is creating the process definition document. The description ahead assumes familiarity with BPEL. If you are new to BPEL, the pages listed below guide you step by step in the creation of a BPEL process. However, in case you are doing any serious work with BPEL, you should learn from the specification itself.
• • •

http://activebpel.org/docs/tutorial.html http://www.smartcomps.org/confluence/pages/viewpage.action?pageId=182 http://www.oracle.com/technology/products/ias/bpel/pdf/orabpel-BPEL101.pdf

Let's call our document hello.bpel and save it in directory definition. We create a partner link to realize the abstract relationship with the caller of the service provided by the process. We indicate that the process will play the service role. Next we create two variables to hold the incoming and outgoing messages. Finally, we create a sequence of three activities that receives a request message from a client, prepares a response message and sends it back.
<process name="helloWorld" targetNamespace="http://jbpm.org/examples/hello" xmlns:tns="http://jbpm.org/examples/hello" xmlns:bpel="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/ws/2003/03/business-process/ http://schemas.xmlsoap.org/ws/2003/03/business-process/"> <partnerLinks> <!-- realizes the abstract relationship with the caller --> <partnerLink name="caller" partnerLinkType="tns:helloPLT" myRole="service"/> </partnerLinks> <variables> <!-- holds the incoming message --> <variable name="request" messageType="tns:nameMessage"/> <!-- holds the outgoing message --> <variable name="response" messageType="tns:greetingMessage"/> </variables> <sequence> <!-- receive a message carrying the name of a person --> <receive operation="sayHello" partnerLink="caller" portType="tns:helloPT" variable="request" createInstance="true"/> <!-- compose a greeting phrase containing the name --> <assign> <copy> <from expression="concat('Hello, ', bpel:getVariableData('request', 'name'), '!')"/> <to variable="response" part="greeting"/> </copy> </assign> <!-- reply with a message carrying the greeting --> <reply operation="sayHello" partnerLink="caller" portType="tns:helloPT" variable="response"/> </sequence>

10

JBoss jBPM BPEL 1.0
</process>

Attributes ending with Type refer to external WSDL definitions. We'll deal with them in step 2.

2 Create/obtain the WSDL interface documents
WSDL documents describe the interface of the process that will be presented to the outside world. To promote clarity and reuse, the WSDL specification recommends separating the different elements of a service definition into independent documents according to their level of abstraction. The proposed levels are data type definitions, abstract definitions, and specific service bindings. A service interface document describes a specific type of service. It contains the types, import, message and portType elements; it can reference other abstract definitions documents using import elements. A service implementation document contains the description of a service that implements a service interface. It contains the import, binding and service elements. At least one of the import elements references the WSDL interface document. The process definition is dependent on data type definitions and abstract definitions. The BPEL runtime is responsible of supplying the specific bindings for web services produced by a BPEL process. The specific bindings for partner services can be typically obtained at deployment or run time. We use only one WSDL interface document. Let's name it hello.wsdl and save it in directory definition. We create two mesages that respectively carry the name and greeting. Next we create a port type that describes the interface that the process presents to its callers. It exposes a single operation sayHello, which takes the name message as input and returns the greeting message as output. Finally, we create a partner link type to characterize the relationship between the service provided by the process and the caller. We define the roles played by each service and specify the interfaces they expose to each other. Because our process does not call the client back, we define only one role: no requirements are placed on the caller.
<definitions targetNamespace="http://jbpm.org/examples/hello" xmlns:tns="http://jbpm.org/examples/hello" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:plt="http://schemas.xmlsoap.org/ws/2003/05/partner-link/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/ http://schemas.xmlsoap.org/wsdl/ http://schemas.xmlsoap.org/ws/2003/05/partner-link/ http://schemas.xmlsoap.org/ws/2003/05/partner-link/"> <!-- characterizes the relationship between the process and its caller --> <plt:partnerLinkType name="helloPLT"> <plt:role name="service"> <plt:portType name="tns:helloPT"/> </plt:role> </plt:partnerLinkType> <!-- carries the name of a person --> <message name="nameMessage"> <part name="name" type="xsd:string"/>

11

JBoss jBPM BPEL 1.0
</message> <!-- carries the greeting --> <message name="greetingMessage"> <part name="greeting" type="xsd:string"/> </message> <!-- describes the interface presented to callers --> <portType name="helloPT"> <operation name="sayHello"> <input message="tns:nameMessage"/> <output message="tns:greetingMessage"/> </operation> </portType> </definitions> The values of name attributes in child elements of definitions match the names used earlier in

the process definition.

3 Deploy the process definition
3.1 Process definition package jBPM provides a mechanism to package all files related to a process definition into a process archive, and then deploy the archive to a database. The BPEL extension uses this mechanism to make the definition available to the port components and the BPEL application (we'll talk about it in step 4.2). The central file in the process archive is the definition descriptor, bpel-definition.xml (saved in directory definition). It specifies the location of the process definition file within the package. The descriptor also indicates the location of WSDL interface files, either relative to the package root or at some absolute URL.
<!-- specifies the location of the process definition --> <bpelDefinition location="hello.bpel" xmlns="http://jbpm.org/bpel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/bpel http://jbpm.org/bpel/bpel_definition_1_0.xsd"> <!-- makes WSDL interface elements available to the process --> <imports> <wsdl namespace="http://jbpm.org/examples/hello" location="hello.wsdl"/> </imports> </bpelDefinition>

To build the process archive, call:
ant pack-definition

The result is an archive named hello-definition.par (in directory build); its contents are:
+ META-INF - bpel-definition.xml - hello.bpel - hello.wsdl

12

JBoss jBPM BPEL 1.0 3.2 Process archive deployment To deploy the process archive to the database, call:
ant deploy-definition

When successful, the messages below appear in the server console:
00:39:05,953 INFO [[/jbpm-bpel]] DeployServlet: deploying process archive: file:/.../hello-definition.par 00:39:06,296 INFO [BpelReader] read wsdl definitions: hello.wsdl 00:39:06,343 INFO [BpelReader] read bpel process: hello.bpel

4 Build the WS4EE port components
In WS4EE, a port component defines the server view of a web service. It services the operation requests defined by a WSDL portType. In this step, we will create one port component for each partner link that defines a process role; that is, partnerLink elements having a myRole attribute. 4.1 WSDL implementation documents WSDL implementation documents for the process can be automatically generated from the process definition and related WSDL interface documents. The BPEL extension includes a tool just for that purpose, servicegen. This program reads a process archive. To execute the tool, call:
ant generate-service The result is a wsdl directory under directory web. The wsdl directory contains three files: hello.wsdl is a semantical equivalent of the interface document we created in step 2. Because

the location we specified in step 3.1 is relative, the tool writes this file so that its definitions are available to the port component.
• binding1.wsdl contains the SOAP binding for the caller port type of step 2. Note that

the target namespace of this document is the same as the port type's:
http://jbpm.org/examples/hello. If the process implemented other port types

belonging to such namespace they would appear also in this document. Bindings for port types of other namespaces would appear in a separate file bindingn.wsdl. The generated binding document (edited for clarity) appears next:
<definitions targetNamespace="http://www.jbpm.org/examples/hello" xmlns:tns="http://www.jbpm.org/examples/hello" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <!-- makes WSDL interface elements available to binding elements --> <import namespace="http://www.jbpm.org/examples/hello" location="interface.wsdl"/> <!-- provides SOAP 1.1 protocol details for the exposed port type --> <binding name="helloPTBinding" type="tns:helloPT"> <!-- SOAP over HTTP with RPC-oriented operations --> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="sayHello">

13

JBoss jBPM BPEL 1.0
<soap:operation soapAction="http://www.jbpm.org/examples/hello/sayHello"/> <input> <!-- message parts appear literally within the input SOAP body --> <soap:body use="literal" namespace="http://www.jbpm.org/examples/hello"/> </input> <output> <!-- message parts appear literally within the output SOAP body --> <soap:body use="literal" namespace="http://www.jbpm.org/examples/hello"/> </output> </operation> </binding> </definitions> • service.wsdl contains a single service element belonging to the target namespace of the process. The callerPort subelement implements the caller port type using its

generated SOAP binding. The tool would generate one port for each partner link with a process role. The generated service document is reproduced next:
<definitions targetNamespace="http://www.jbpm.org/examples/hello" xmlns:tns="http://www.jbpm.org/examples/hello" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <!-- represents the entire process --> <service name="helloWorldService"> <!-- realizes the abstract functionality presented in the port type --> <port name="callerPort" binding="tns:helloPTBinding"> <!-- supplies actual access info --> <soap:address location="REPLACE_WITH_ACTUAL_URI"/> </port> </service> </definitions>

Notice that the exact endpoint location is left unspecified. WS4EE will replace this entry with the definitive location during deployment. 4.2 Server artifacts The server artifacts required for a WS4EE deployment can be automatically generated from the WSDL implementation documents. For this purpose, we use wscompile from the Java WSDP. The tool reads a configuration file which in turn references a WSDL file. To execute the tool, call:
ant wscompile

You can find the configuration file we feed to wscompile in path web/wscompile-cfg.xml. It is shown in the following snippet. Attribute packageName associates the target namespace of the referenced WSDL document with the Java package org.jbpm.bpel.tutorial.hello.
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location="wsdl/service.wsdl" packageName="org.jbpm.bpel.tutorial.hello"/> </configuration> The tool places the generated artifacts in directory web. They are the service endpoint interface HelloPT, a template of the service implementation bean HelloPT_Impl and the service

14

JBoss jBPM BPEL 1.0 interface HelloWorldService (in subdirectory src) along with their binary counterparts (in subdirectory classes). wscompile also generates a document that describes the mapping details between Java and XML: jaxrpc-mapping.xml. We won't analyze these artifacts, as the BPEL extension is, in fact, agnostic to them. Consider that the variable context in BPEL is defined in terms of XML types and WSDL messages. Therefore, the BPEL extension works naturally with XML content in SOAP messages; it does not need to perform expensive Java<->XML serialization/deserialization. In WS4EE, handlers provide the means to access SOAP messages. We will configure a handler that provides this access to the BPEL extension in step 5. Nevertheless, the artifacts we just generated must still be present for the WS4EE deployment to be valid. 4.3 Port components as web applications A WS4EE java service endpoint is deployed in a web application as a servlet. Hence, we need a web.xml deployment descriptor, which we have to write by hand.
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>callerServlet</servlet-name> <!-- service implementation bean class (step 4.2) --> <servlet-class>org.jbpm.bpel.tutorial.hello.HelloPT_Impl</servlet-class> </servlet> <servlet-mapping> <servlet-name>callerServlet</servlet-name> <!-- the endpoint location, relative to the root context --> <url-pattern>/caller</url-pattern> </servlet-mapping> </web-app>

We refer to the service implementation bean in the <servlet-class> element, even though it is not a servlet at all. This is a feature of WS4EE. 4.4 Web services deployment descriptor One more descriptor is needed to glue everything together: webservices.xml. It must be written manually, too. We declare the handler that provides the BPEL extension with access to the SOAP envelope in this descriptor.
<webservices version="1.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:impl="http://www.jbpm.org/examples/hello" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/j2ee_web_services_1_1.xsd"> <webservice-description> <!-- descriptive name for the service --> <webservice-description-name>Hello World Service</webservice-description-name> <!-- WSDL service file (step 4.1) -->

15

JBoss jBPM BPEL 1.0
<wsdl-file>WEB-INF/wsdl/service.wsdl</wsdl-file> <!-- Java<->XML mapping file (step 4.2) --> <jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> <port-component> <!-- logical name for the port (unique within the module) --> <port-component-name>callerPort</port-component-name> <!-- WSDL port element (in WSDL service file) --> <wsdl-port>impl:callerPort</wsdl-port> <!-- service endpoint interface class (step 4.2) --> <service-endpoint-interface> org.jbpm.bpel.tutorial.hello.HelloPT </service-endpoint-interface> <!-- associated servlet (in web-app descriptor, step 4.3) --> <service-impl-bean> <servlet-link>callerServlet</servlet-link> </service-impl-bean> <handler> <!-- logical name for the handler (unique within the module) --> <handler-name>callerHandler</handler-name> <!-- handler class (in BPEL extension library) --> <handler-class>org.jbpm.bpel.service.messager.PortHandler</handler-class> <init-param> <description>name of the associated partner link</description> <param-name>portName</param-name> <param-value>caller</param-value> </init-param> </handler> </port-component> </webservice-description> </webservices>

4.5 Web application package We package the files for our port components in a single web app module. The organization of files within the module follows the rules in section 5.4 of the WS4EE specification. To build the web archive for our only port component, call:
ant pack-web

The result is an archive named hello-web.war (in directory build); its contents are:
+ WEB-INF - web.xml - webservices.xml - jaxrpc-mapping.xml + wsdl - service.wsdl - binding1.wsdl - hello.wsdl

16

JBoss jBPM BPEL 1.0
+ classes + org + jbpm + bpel + tutorial + hello - HelloPT.class - HelloPT_Impl.class - HelloWorldService.class

5 Build the WS4EE application client
At the end of this tutorial, the BPEL process will be fully accesible to external clients through its web service interfaces. The WSDL definition of a web service provides enough information for a non-WS4EE client to be built and run. Given we already generated the server artifacts, the WS4EE client programming model is the most comfortable choice, at least for testing purposes. In this step, we will create the application client. 5.1 Application client deployment descriptor An application client uses an descriptor called application-client.xml.
<application-client version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd"> <display-name>Hello World Service Client</display-name> <service-ref> <!-- JNDI name bound to the service interface in the client's environment context --> <service-ref-name>service/Hello</service-ref-name> <!-- service interface class (step 4.2) --> <service-interface>org.jbpm.bpel.tutorial.hello.HelloWorldService</serviceinterface> <!-- placeholder for published WSDL file --> <wsdl-file>USE_JBOSS_CLIENT_XML_OVERRIDE</wsdl-file> <!-- Java<->XML mapping file (step 4.2) --> <jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> <port-component-ref> <!-- service endpoint interface class (step 4.2) --> <service-endpoint-interface> org.jbpm.bpel.tutorial.hello.HelloPT </service-endpoint-interface> </port-component-ref> </service-ref> </application-client>

17

JBoss jBPM BPEL 1.0 5.2 Environment context In order to provide an environment context for the application client, we must reserve a name for it in the global JNDI context. This is done in jboss-client.xml. Be aware that this is a JBoss-specific descriptor.
<jboss-client> <!-- JNDI name bound to the client's environment context --> <jndi-name>hello-client</jndi-name> <service-ref> <!-- the service-ref element to configure --> <service-ref-name>service/Hello</service-ref-name> <!-- published WSDL file --> <wsdl-override>http://localhost:8080/hello/caller?wsdl</wsdl-override> </service-ref> </jboss-client>

5.3 Application client package To build the application client package, call:
ant pack-client

The result is an archive named hello-client.jar (in directory build); its contents are:
+ META-INF - application-client.xml - jboss-client.xml - jaxrpc-mapping.xml

6 Deploy the BPEL application
The BPEL extension uses JMS to ensure orderly delivery of incoming messages to the right process instances. Each partner link in a process definition is assigned a queue. An inbound message activity (receive, pick or onMessage event) listens for messages on the queue assigned to its partner link. When a SOAP message arrives at the port component that represents that partner link, it is sent to the same queue. The selection feature of JMS routes it to the right receiver. Port components and inbound message activities are engaged in a producer-consumer relationship. Therefore, we require unity in deploying port components and preparing activities for reception. The concept of BPEL application fulfills this requirement. It complements our existing web application (which groups the port components) with a messager servlet that prepares activities for reception. 6.1 Messager servlet In order to add the messager servlet to the web application, we include an extra servlet element in web.xml. We indicate the container to load the messager during web app startup, so that activities are ready before the port components begin sending messages to them.
<web-app ...> ... <servlet>

18

JBoss jBPM BPEL 1.0
<servlet-name>messagerServlet</servlet-name> <servlet-class>org.jbpm.bpel.service.messager.MessagerServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>messagerServlet</servlet-name> <url-pattern>/messager</url-pattern> </servlet-mapping> </web-app>

6.2 BPEL application descriptor The messager servlet reads a BPEL application descriptor to set itself up. You can find the bpel-application.xml descriptor in directory web; we also pack it in the web archive. Among other functions, this descriptor assigns queues to partner links. Note that queues may be shared among partner links.
<bpelApplication name="HelloWorld" xmlns="http://jbpm.org/bpel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/bpel http://jbpm.org/bpel/bpel_application_1_0.xsd"> <partnerLinks> <partnerLink name="caller"> <!-- JNDI name bound to the queue assigned to this partner link --> <myRole destination="jms/callerQueue" /> </partnerLink> </partnerLinks> </bpelApplication>

6.3 Destination and connection factory references The JNDI names in the BPEL application descriptor are message destination references. We need to assign an entry in the web application’s environment context to those references, following section 5.6 of the J2EE 1.4 specification. Only one inbound message activity is expected to receive each message, hence we use a queue rather than a topic.
<web-app ...> ... <message-destination-ref> <message-destination-ref-name>jms/callerQueue</message-destination-ref-name> <message-destination-type>javax.jms.Queue</message-destination-type> <message-destination-usage>ConsumesProduces</message-destination-usage> </message-destination-ref> </web-app>

The port components and the messager servlet require a JMS connection factory. We assign an entry in the web application’s environment to a JMS connection factory, as per section 5.4 of the J2EE 1.4 specification. We allow the deployer to set up the resource sign-on information, and enable connection sharing. Since only one connection factory is needed, we assign a single constant entry jms/ConnectionFactory.

19

JBoss jBPM BPEL 1.0
<web-app ...> ... <resource-ref> <res-ref-name>jms/ConnectionFactory</res-ref-name> <res-type>javax.jms.ConnectionFactory</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app>

6.4 Binding references to actual resources We proceed to bind the destination and connection factory references to resources that exist in the operational environment. This task is specific to the target application server. For JBoss we write a jboss-web.xml descriptor and place it in directory web.
<jboss-web> <message-destination-ref> <!-- destination reference (in web.xml) --> <message-destination-ref-name>jms/callerQueue</message-destination-ref-name> <!-- actual resource in the global JNDI context --> <jndi-name>queue/testQueue</jndi-name> </message-destination-ref> <resource-ref> <!-- connection factory reference (in web.xml) --> <res-ref-name>jms/ConnectionFactory</res-ref-name> <!-- actual resource in the java JNDI context --> <jndi-name>java:ConnectionFactory</jndi-name> </resource-ref> </jboss-web>

6.5 Enterprise application deployment descriptor To deploy our extended web module and the application client of step 5, we create an enterprise application. First we write the application.xml descriptor that references both packages. We place it in directory application.
<application version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"> <description>Hello World enterprise application</description> <display-name>HelloWorldApp</display-name> <module> <web> <web-uri>hello-web.war</web-uri> <context-root>/hello</context-root> </web> </module> <module>

20

JBoss jBPM BPEL 1.0
<java>hello-client.jar</java> </module> </application>

6.6 Enterprise application package To build the enterprise application archive, call:
ant pack-application

This will rebuild the web archive and create a hello-application.ear archive in directory build. Its contents are:
+ META-INF - application.xml - hello-web.war - hello-client.jar

6.7 Enterprise application deployment To deploy the enterprise application to JBoss, call:
ant deploy-application

On the server you should see messages similar to these:
03:46:17,187 INFO application.ear 03:46:17,718 INFO 03:46:17,718 INFO exp.war/ 03:46:18,140 INFO 03:46:18,218 INFO 03:46:18,343 INFO 03:46:18,718 INFO 03:46:18,734 INFO application.ear [EARDeployer] Init J2EE application: file:/.../hello[ClientDeployer] Client ENC bound under: hello-client [TomcatDeployer] deploy, ctxPath=/hello, warUrl=.../hello-web[[/hello]] messagerServlet: BPEL application started: helloWorld [WSDLFilePublisher] WSDL published to: file:/.../service.wsdl [AxisService] WSDD published to: ...\callerPort.wsdd [AxisService] Web Service deployed: http://.../hello/caller [EARDeployer] Started J2EE application: file:/.../hello-

7 Test the process
Now that our process has been started, we need to make sure it works as we expect. In this step, we will create a JUnit test case named HelloTest under the test directory. 7.1 Remote web service access The deployment of the application client we built in step 5 causes the app server to bind an instance of the service interface under the client's environment context, java:comp/env, using the logical name of the service reference. In our example the logical name is service/Hello, which matches the service-ref-name we specified in step 5.1. The test setup code looks up the service instance. This object is a factory the client uses to get a proxy that implements the service endpoint interface.
private HelloPT greeter; protected void setUp() throws Exception { InitialContext ctx = getInitialContext(); // JNDI name bound to the service interface (in application-client.xml) String serviceRefName = "service/Hello";

21

JBoss jBPM BPEL 1.0
// lookup the service interface in the environment context HelloWorldService service = (HelloWorldService) ctx.lookup("java:comp/env/" + serviceName); // obtain the dynamic proxy for the web service port greeter = service.getCallerPort(); }

The test method uses the proxy that implements the SEI like a local java object.
public void testSayHello() throws Exception { // use the proxy like a local java object String greeting = greeter.sayHello("Popeye"); assertEquals("Hello, Popeye!", greeting); }

7.2 Client JNDI properties Besides the properties in file jndi.properties, we need to set the property j2ee.clientName to match the JNDI name of the client's environment context that we specified in step 5.2.
protected InitialContext getInitialContext() throws NamingException { // JNDI name bound to the client's environment context (in jboss-client.xml) String envContextName = "hello-client"; // prepare the enviroment Properties env = new Properties(); env.setProperty("j2ee.clientName", envContextName); // properties in env *and* jndi.properties are placed in the context's environment return new InitialContext(env); }

7.3 Test execution To execute the JUnit test, run:
ant run-test

If all goes well you should see messages similar to these:
run-test: [junit] Testsuite: org.jbpm.bpel.tutorial.hello.HelloTest [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 2.735 sec

3.3 ATM Example
In this tutorial, we'll develop a process that handles the lifecycle of Automated Teller Machines sessions. Each session will allow a client to perform a set of operations in an orderly manner. These operations include: connecting, logging in, querying the state of the session, querying an account balance, withdrawing / depositing funds, logging off and disconnecting. The related files of this tutorial are in the jBPM BPEL extension download package, in directory
doc/examples/atm.

The following picture represents the top level view of the ATM process:

22

JBoss jBPM BPEL 1.0

1 Create the BPEL document
We'll start with the process-level definitions. First, we create a partner link to represent the relationship between the ATM service clients and the process. The process assumes the service role; the client has no explicit role. Second, we define another partner link to represent the relationship between the process and a partner session generator service. The session generator assumes the service role; the process has no explicit role. Next we create four variables: two of them will hold the exchanged messages and the rest will be used as status flags. Finally, we declare a correlation set that distinguishes client connections from each other using the session id property.
<process name="atm" targetNamespace="urn:samples:atm" xmlns="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:tns="urn:samples:atm" xmlns:atm="urn:samples:atm" xmlns:ses="urn:samples:session" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:bpel="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/ws/2003/03/business-process/ http://schemas.xmlsoap.org/ws/2003/03/business-process/"> <partnerLinks> <!-- realizes the abstract relationship with the ATM client --> <partnerLink name="frontEnd" partnerLinkType="tns:atmFrontEnd" myRole="front"/> <!-- realizes the abstract relationship with the session generator --> <partnerLink name="sessionFactory" partnerLinkType="tns:atmSessionFactory" partnerRole="factory"/> </partnerLinks> <variables> <!-- incoming connection request message --> <variable name="connectReq" messageType="atm:connectRequest"/> <!-- session generation request message -->

23

JBoss jBPM BPEL 1.0
<variable name="sessionReq" messageType="ses:sessionRequest"/> <!-- session id message --> <variable name="sessionMsg" messageType="ses:sessionMessage"/> <!-- a flag that indicates if the user is connected --> <variable name="connected" type="xsd:boolean"/> <!-- a flag that indicates if the user is logged on --> <variable name="loggedon" type="xsd:boolean"/> </variables> <correlationSets> <!-- identifies the conversation with a connected client--> <correlationSet name="sessionInteraction" properties="tns:sessionid"/> </correlationSets>

Let's move on to with the control flow. We define a main sequence for handling the lifecycle of an ATM session. It consists of four activities that: receive a connection request, invoke the session generator service, send a session message back to the client and finally wait for client interactions that corresponding to the newly created session:
<process ...> ... <sequence name="mainSequence"> <!-- receive a connection request --> <receive operation="connect" partnerLink="frontEnd" portType="atm:atm" variable="connectReq" createInstance="yes"/> <!-- generate a session id --> <invoke operation="openSession" partnerLink="sessionFactory" portType="ses:sessionFactory" inputVariable="sessionReq" outputVariable="sessionMsg"> <correlations> <correlation set="sessionInteraction" pattern="in" initiate="yes"/> </correlations> </invoke> <!-- synchronous response to the client, holding the generated session id --> <reply operation="connect" partnerLink="frontEnd" portType="atm:atm" variable="sessionMsg"> <correlations> <correlation set="sessionInteraction"/> </correlations> </reply> <!-- initialize the status flags to connected / not logged--> <assign name="initStatus"> <copy> <from expression="true()"/> <to variable="connected"/> </copy> <copy> <from expression="false()"/> <to variable="loggedon"/> </copy> </assign> <!-- handles the user interactions while connected --> <scope name="connectedScope"> ... </scope> </sequence> </process>

24

JBoss jBPM BPEL 1.0 The scope element at the end of the sequence is used to encapsulate the connection handling logic. This activity allows specifying a nested execution flow and local definitions of variables, correlation sets and fault/event handling behavior. The following diagram shows the control flow of the handleConnection scope:

Let's continue with the scope definition. First, we declare two local variables for incoming and outgoing messages: logonReq and statusRsp. We also include a correlation set that distinguishes logged-on users from each other using the customer id property. Once this is done we start modeling the control flow. Lets define a while activity to process client requests. The loop consists of a pick activity that chooses between two paths depending on the request it receives first. This logic is repeated while the connected flag is true. We add to this pick two message receptions set to use the sessionInteraction correlation. Each one is configured with an activity to be performed upon reception. For logon requests, we use a scope that enables customer interactions. For disconnect request, an assign that sets false the connected flag to break the cycle and complete the handleConnection scope.
... <scope name="connectedScope"> <variables> <!-- incoming logon request message --> <variable name="logonReq" messageType="atm:logonRequest"/> <!-- outgoing status response message --> <variable name="statusRsp" messageType="atm:statusResponse"/> </variables>

25

JBoss jBPM BPEL 1.0
<correlationSets> <!-- Identifies the conversation of a loggedon ATM user--> <correlationSet name="customerInteraction" properties="tns:customerid"/> </correlationSets> <!-- wait for user interaction while connected --> <while name="connectedLoop" condition="bpel:getVariableData('connected')"> <!-- listen for disconnect and logon requests --> <pick name="logon-disconnect"> <onMessage operation="disconnect" partnerLink="frontEnd" portType="atm:atm" variable="sessionMsg"> <correlations> <correlation set="sessionInteraction"/> </correlations> <!-- sets connected to false to break the cycle --> <assign name="setDisconnected"> <copy> <from expression="false()"/> <to variable="connected"/> </copy> </assign> </onMessage> <onMessage operation="logon" partnerLink="frontEnd" portType="atm:atm" variable="logonReq"> <correlations> <correlation set="sessionInteraction"/> <correlation set="customerInteraction" initiate="yes"/> </correlations> <!-- handles the user interactions while loggedon --> <scope name="loggedonScope"> ... </scope> </onMessage> </pick> </while> </scope> ...

To add a little flavor let's define an event for handling status requests inside this scope. The status request event will let users query for their session status while the scope is active:

26

JBoss jBPM BPEL 1.0

The following snippet shows the scope's event handling code:
<scope name="connectedScope"> ... <eventHandlers> <!-- receive a request status event--> <onMessage operation="status" partnerLink="frontEnd" portType="atm:atm" variable="sessionMsg"> <correlations> <correlation set="sessionInteraction"/> </correlations> <sequence name="statusSequence"> <!-- assign a status to the response depending on the flag values--> <switch name="statusSwitch"> <case condition="bpel:getVariableData('loggedon')"> <assign name="setStatusLoggedon"> <copy> <from expression="'loggedon'"/> <to variable="statusRsp" part="status"/> </copy> </assign> </case> <case condition="bpel:getVariableData('connected')"> <assign name="setStatusConnected"> <copy> <from expression="'connected'"/> <to variable="statusRsp" part="status"/> </copy> </assign>

27

JBoss jBPM BPEL 1.0
</case> <otherwise> <assign name="setStatusDisconnected"> <copy> <from expression="'disconnected'"/> <to variable="statusRsp" part="status"/> </copy> </assign> </otherwise> </switch> <!-- reply with a message carrying the status --> <reply operation="status" partnerLink="frontEnd" portType="atm:atm" variable="statusRsp"/> </sequence> </onMessage> <eventHandlers/> ... </scope> Finally, we need to model the core of the ATM process: loggedonScope. The following picture

summarizes its flow control:

28

JBoss jBPM BPEL 1.0 Let's declare four local variables for incoming and outgoing messages: balanceReq, depositReq, withdrawReq and statusRsp. In this example, we use an additional variable to store the account balance inside the process. Now let's model the control flow. First, we initialize the amount variable to zero. Then, as in the previous scope, we use a while activity with a nested pick to handle customer requests. We add to this pick four message receptions set to use the customerInteraction correlation. Each one is configured with an activity to be performed upon reception. For getBalance request we use a sequence that assigns the amount variable to a response and sends it back to the customer. For withdraw and deposit a sequence that updates the amount variable and reply with an operation response message. Finally, for logoff an activity that sets false the logged flag to break the cycle and complete the loggedonScope.
<scope name="loggedonScope"> <variables> <variable name="amount" type="xsd:int"/> <variable name="logoffReq" messageType="atm:logoffRequest"/> <variable name="balanceReq" messageType="atm:balanceRequest"/> <variable name="depositReq" messageType="atm:operationRequest"/> <variable name="withdrawReq" messageType="atm:operationRequest"/> <variable name="operationRsp" messageType="atm:operationResponse"/> </variables> <sequence name="loggedonSequence"> <!-- reply with a message carrying the status --> <assign name="initLogon"> <copy> <from expression="true()"/> <to variable="loggedon"/> </copy> <!--initial balance--> <copy> <from expression="0"/> <to variable="amount"/> </copy> </assign> <!-- wait for user interaction while logged on --> <while name="loggedonLoop" condition="bpel:getVariableData('loggedon')"> <!-- listen for ATM requests; first message determines the path to take --> <pick name="deposit-withdraw-logoff"> <onMessage operation="logoff" partnerLink="rontEnd" portType="atm:atm" variable="logoffReq"> <correlations> <correlation set="customerInteraction"/> </correlations> <!-- sets connected to false to break the cycle --> <assign name="setLoggedOff"> <copy> <from expression="false()"/> <to variable="loggedon"/> </copy> </assign> </onMessage>

29

JBoss jBPM BPEL 1.0
<onMessage operation="getBalance" partnerLink="frontEnd" portType="atm:atm" variable="balanceReq"> <correlations> <correlation set="customerInteraction"/> </correlations> <sequence> <!-- sets the amount to the response --> <assign name="getAmount"> <copy> <from variable="amount"/> <to variable="operationRsp" part="balance"/> </copy> </assign> <!-- sends getBalance response --> <reply operation="getBalance" partnerLink="frontEnd" portType="atm:atm" variable="operationRsp"/> </sequence> </onMessage> <onMessage operation="deposit" partnerLink="frontEnd" portType="atm:atm" variable="depositReq"> <correlations> <correlation set="customerInteraction"/> </correlations> <sequence> <!-- increases the amount and sets the result to the response --> <assign name="increaseAmount"> <copy> <from expression="bpel:getVariableData('amount') + bpel:getVariableData('depositReq', 'request', '/request/amount')"/> <to variable="amount"/> </copy> <copy> <from variable="amount"/> <to variable="operationRsp" part="balance"/> </copy> </assign> <!-- sends deposit response --> <reply operation="deposit" partnerLink="frontEnd" portType="atm:atm" variable="operationRsp"/> </sequence> </onMessage> <onMessage operation="withdraw" partnerLink="frontEnd" portType="atm:atm" variable="withdrawReq"> <correlations> <correlation set="customerInteraction"/> </correlations> <scope name="withdrawScope"> ... </scope> </onMessage> </pick> </while> </sequence>

30

JBoss jBPM BPEL 1.0
</scope>

The withdraw operation deserves special attention. The requested amount might be larger than the available funds. If there is enough money, the process substracts the amount and returns the new balance. Otherwise, it must leave the funds intact and let the customer know of the problem with a fault.
<scope name="withdrawScope"> <variables> <variable name="newAmount"> <variable name="noFundsFault" messageType="atm:operationFault" /> </variables> <sequence> <!-- substracts the amount and sets the result to a local variable --> <assign name="decreaseAmount"> <copy> <from expression="bpel:getVariableData('amount') - bpel:getVariableData('withdrawReq', 'request', '/request/amount')"/> <to variable="newAmount"/> </copy> </assign> <!-- decides the outcome depending on the result of the substraction --> <switch name="checkPositiveBalance"> <case condition="bpel:getVariableData('newAmount') >= 0.0"> <sequence> <!-- sets the result to the amount and the response --> <assign name="updateAmount"> <copy> <from variable="newAmount" /> <to variable="amount" /> </copy> <copy> <from variable="amount" /> <to variable="operationRsp" part="balance" /> </copy> </assign> <!-- sends withdraw response --> <reply operation="withdraw" partnerLink="frontEnd" portType="atm:atm" variable="operationRsp" /> </sequence> </case> <otherwise> <sequence> <!--sets the fault detail --> <assign name="fillNoFundsFault"> <copy> <from> <types:operationFault xmlns:types="urn:samples:atmTypes" xmlns=""> <code>100</code> <description>not enough funds</description> </types:operationFault> </from> <to variable="noFundsFault" part="fault" query="/types:operationFault" xmlns:types="urn:samples:atmTypes" /> </copy> </assign>

31

JBoss jBPM BPEL 1.0
<!-- sends withdraw fault --> <reply operation="withdraw" partnerLink="frontEnd" portType="atm:atm" variable="noFundsFault" faultName="atm:notEnoughFunds" /> </sequence> </otherwise> </switch> </sequence> </scope>

2 Create/obtain the WSDL interface documents
To better organize WSDL definitions, we'll use three interface documents for the ATM service. Let's save it in directory definition. The first document, interface/session.wsdl contains the interface of the session generator partner service. We suppose that this service is already deployed somewhere and we obtained its WSDL abstract definitions.
<definitions targetNamespace="urn:samples:session" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:samples:session" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/ http://schemas.xmlsoap.org/wsdl/"> <!-- requests session id generation --> <message name="sessionRequest"/> <!-- carries the session id --> <message name="sessionMessage"> <part name="sessionID" type="xsd:int"/> </message> <!-- describes the interface of the session generator --> <portType name="sessionFactory"> <operation name="openSession"> <input message="tns:sessionRequest"/> <output message="tns:sessionMessage"/> </operation> </portType> </definitions>

The second document, interface/frontEnd.wsdl, contains the interface that the process presents to ATM clients. In the first place, we import the session WSDL document to reuse the sessionMessage. After that, we declare custom schema types to better encapsule exchanged data. We also need to declare a total of 7 messages used in the process. Next, we create a port type that describes the ATM interface. It exposes connection, authentication and account related operations.
<definitions targetNamespace="urn:samples:atm" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:samples:atm" xmlns:ses="urn:samples:session" xmlns:types="urn:samples:atmTypes" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

32

JBoss jBPM BPEL 1.0
xsi:schemaLocation="http://schemas.xmlsoap.org/wsdl/ http://schemas.xmlsoap.org/wsdl/"> <!-- reuse session definitions --> <import namespace="urn:samples:session" location="session.wsdl" /> <types> <schema targetNamespace="urn:samples:atmTypes" xmlns="http://www.w3.org/2001/XMLSchema"> <!-- describes an account operation request --> <complexType name="operationRequestType"> <sequence> <element name="customerName" type="string"/> <element name="amount" type="double"/> </sequence> </complexType> <!-- describes an account operation fault --> <complexType name="operationFaultType"> <sequence> <element name="code" type="int"/> <element name="description" type="string"/> </sequence> </complexType> <element name="operationFault" type="types:operationFaultType"/> </schema> </types> <!-- requests connection --> <message name="connectRequest" /> <!-- requests customer logoff --> <message name="logoffRequest"> <part name="customerName" type="xsd:string"/> </message> <!-- requests customer logon --> <message name="logonRequest"> <part name="sessionID" type="xsd:int"/> <part name="customerName" type="xsd:string"/> </message> <!-- requests customer balance --> <message name="balanceRequest"> <part name="customerName" type="xsd:string"/> </message> <!-- requests account operation --> <message name="operationRequest"> <part name="request" type="types:operationRequestType"/> </message> <!-- replies account operation --> <message name="operationResponse"> <part name="balance" type="xsd:double"/> </message> <!-- replies session status --> <message name="statusResponse"> <part name="status" type="xsd:string"/> </message> <!-- describes the interface presented to ATM clients --> <portType name="atm">

33

JBoss jBPM BPEL 1.0
<operation name="connect"> <input message="tns:connectRequest"/> <output message="ses:sessionMessage"/> </operation> <operation name="disconnect"> <input message="ses:sessionMessage"/> </operation> <operation name="status"> <input message="ses:sessionMessage"/> <output message="tns:statusResponse"/> </operation> <operation name="logon"> <input message="tns:logonRequest"/> </operation> <operation name="logoff"> <input message="tns:logoffRequest"/> </operation> <operation name="getBalance"> <input message="tns:balanceRequest"/> <output message="tns:operationResponse"/> </operation> <operation name="deposit"> <input message="tns:operationRequest"/> <output message="tns:operationResponse"/> </operation> <operation name="withdraw"> <input message="tns:operationRequest"/> <output message="tns:operationResponse"/> <fault message="tns:operationFault" name="notEnoughFunds"/> </operation> </portType> </definitions>

The third document, atm.wsdl, contains BPEL extensibility elements. First we import the previous two documents to reference their definitions. Later we define some properties for correlation purposes. We create sessionid to help us distinguishing connections and customerid for distinguishing logged customers. We also have to declare a set of propertyAlias elements to tie these properties with key pieces of data carried in messages. Finally, we create partner link types to characterize the relationship between the process and the ATM clients (atmFrontEnd) as well as between the process and the session generator (atmSessionFactory). We define the roles played by each service and specify the interfaces they expose to each other. Our process does not call back the client, neither does the session generator call back the process. Therefore, both partner link types have a single role.
<definitions targetNamespace="urn:samples:atm" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="urn:samples:atm" xmlns:atm="urn:samples:atm" xmlns:ses="urn:samples:session" xmlns:types="urn:samples:atm:types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:bpel="http://schemas.xmlsoap.org/ws/2003/03/business-process/" xmlns:plt="http://schemas.xmlsoap.org/ws/2003/05/partner-link/">

34

JBoss jBPM BPEL 1.0
<!-- reference abstract definitions --> <import namespace="urn:samples:atm" location="interface/frontend.wsdl" /> <import namespace="urn:samples:session" location="interface/session.wsdl" /> <!-- identifies logged customers --> <bpel:property name="customerid" type="xsd:string"/> <!-- customer property ties --> <bpel:propertyAlias propertyName="tns:customerid" messageType="atm:logonRequest" part="customerName"/> <bpel:propertyAlias propertyName="tns:customerid" messageType="atm:logoffRequest" part="customerName"/> <bpel:propertyAlias propertyName="tns:customerid" messageType="atm:balanceRequest" part="customerName"/> <bpel:propertyAlias propertyName="tns:customerid" messageType="atm:operationRequest" part="request" query="/request/customerName"/> <!-- identifies connected sessions --> <bpel:property name="sessionid" type="xsd:int"/> <!-- session property ties --> <bpel:propertyAlias propertyName="tns:sessionid" messageType="ses:sessionMessage" part="sessionID"/> <bpel:propertyAlias propertyName="tns:sessionid" messageType="atm:logonRequest" part="sessionID"/> <!-- characterizes the relationship between the process and ATM clients --> <plt:partnerLinkType name="atmFrontEnd"> <plt:role name="front"> <plt:portType name="atm:atm"/> </plt:role> </plt:partnerLinkType> <!-- characterizes the relationship between the process and session factory --> <plt:partnerLinkType name="atmSessionFactory"> <plt:role name="factory"> <plt:portType name="ses:sessionFactory"/> </plt:role> </plt:partnerLinkType> </definitions>

3 Deploy the process definition
3.1 Process definition package Create the bpel-definition.xml file:
<!-- specifies the location of the process definition --> <bpelDefinition location="atm.bpel" xmlns="http://jbpm.org/bpel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/bpel http://jbpm.org/bpel/bpel_definition_1_0.xsd"> <!-- makes WSDL interface elements available to the process --> <imports>

35

JBoss jBPM BPEL 1.0
<wsdl namespace="urn:samples:atm" location="atm.wsdl"/> </imports> </bpelDefinition>

Build the process archive by calling:
ant pack-definition

The result is an archive named atm-definition.par (in directory build); its contents are:
+ META-INF - bpel-definition.xml + interface - frontend.wsdl - session.wsdl - atm.bpel - atm.wsdl

3.2 Process archive deployment Now deploy the process archive to the database:
ant deploy-definition

The server console should read like this:
08:34:25,515 INFO [[/jbpm-bpel]] DeployServlet: deploying process archive: file:/.../atm-definition.par 08:34:26,015 INFO [BpelReader] read wsdl definitions: atm.wsdl 08:34:26,171 INFO [BpelReader] read bpel process: atm.bpel

4 Build the port components
4.1 WSDL implementation documents Generate the ATM wsdl implementation files by calling generate-service target:
ant generate-service The task creates a wsdl directory under web. It writes the interface documents of step 2, a binding1.wsdl document for the SOAP binding of the atm port type, and the service.wsdl document for the service that represents the process. The service contains a frontEndPort associated to the frontEnd partner link.

4.2 Server artifacts We are ready to generate the WS4EE server artifacts. Call:
ant wscompile

The previous target uses the wscompile-cfg.xml file located in the atmFrontEnd directory:
<configuration xmlns="http://java.sun.com/xml/ns/jax-rpc/ri/config"> <wsdl location="wsdl/implementation.wsdl" packageName="org.jbpm.bpel.tutorial.atm"/> <!-- maps xml namespaces (other than the target namespace) to package names --> <namespaceMappingRegistry> <namespaceMapping namespace="urn:samples:atm:types" packageName="org.jbpm.bpel.tutorial.atm.types"/> </namespaceMappingRegistry> </configuration>

36

JBoss jBPM BPEL 1.0 4.3 Port components as web applications Write by hand a web application descriptor called web.xml in the web directory
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>frontEndServlet</servlet-name> <!-- service implementation bean class (step 4.2) --> <servlet-class>org.jbpm.bpel.tutorial.atm.Atm_Impl</servlet-class> </servlet> <servlet-mapping> <servlet-name>frontEndServlet</servlet-name> <!-- the endpoint location, relative to the context root --> <url-pattern>/frontEnd</url-pattern> </servlet-mapping> </web-app>

4.4 The web services deployment descriptor Write by hand a web service descriptor called webservices.xml in the web directory
<webservices version="1.1" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:impl="urn:samples:ATMService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/j2ee_web_services_1_1.xsd"> <webservice-description> <webservice-description-name>atmService</webservice-description-name> <!-- WSDL implementation file (step 4.1) --> <wsdl-file>WEB-INF/wsdl/service.wsdl</wsdl-file> <!-- Java<->XML mapping file (step 4.2) --> <jaxrpc-mapping-file>WEB-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> <port-component> <!-- logical name for the port (unique within the module) --> <port-component-name>frontEndPort</port-component-name> <!-- WSDL port element (in WSDL service file) --> <wsdl-port>impl:frontEndPort</wsdl-port> <!-- service endpoint interface class (step 4.2) --> <service-endpoint-interface>org.jbpm.bpel.tutorial.atm.Atm</service-endpointinterface> <service-impl-bean> <!-- associated servlet (in web-app descriptor) --> <servlet-link>frontEndServlet</servlet-link> </service-impl-bean> <handler> <!-- logical name for the handler (unique within the module) --> <handler-name>atmHandler</handler-name> <!-- handler class (in BPEL extension library) -->

37

JBoss jBPM BPEL 1.0
<handler-class>org.jbpm.bpel.service.messager.PortHandler</handler-class> <init-param> <description>name of the associated partner link</description> <param-name>portName</param-name> <param-value>frontEnd</param-value> </init-param> <init-param> <description>time to wait for response messages, in millis</description> <param-name>responseTimeout</param-name> <param-value>60000</param-value> </init-param> <init-param> <description>time to expire one-way messages, in millis</description> <param-name>oneWayTimeout</param-name> <param-value>300000</param-value> </init-param> </handler> </port-component> </webservice-description> </webservices>

4.5 Web application package To build the web archive, call:
ant pack-web

The result is an archive named atm-web.war (in directory build); its contents are:
+ WEB-INF - web.xml - webservices.xml - jaxrpc-mapping.xml + wsdl - atm.wsdl - binding1.wsdl - service.wsdl + interface - frontend.wsdl - session.wsdl + classes + org + jbpm + bpel + tutorial + atm - Atm.class - Atm_Impl.class - AtmService.class + types -OperationRequestType.class

38

JBoss jBPM BPEL 1.0

5 Build the WS4EE application client
5.1 Client deployment descriptor Create the aplication-client.xml descriptor in the client directory:
<application-client version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application-client_1_4.xsd"> <display-name>ATM service client</display-name> <service-ref> <!-- JNDI name bound to the service interface in the client's env context --> <service-ref-name>service/ATM</service-ref-name> <!-- service interface class (step 4.2) --> <service-interface>org.jbpm.bpel.tutorial.atm.AtmService</service-interface> <!-- placeholder for published wsdl file --> <wsdl-file>USE_JBOSS_CLIENT_XML_OVERRIDE</wsdl-file> <!-- Java<->XML mapping file (step 4.2) --> <jaxrpc-mapping-file>META-INF/jaxrpc-mapping.xml</jaxrpc-mapping-file> <port-component-ref> <!-- service endpoint interface class (step 4.2) --> <service-endpoint-interface>org.jbpm.bpel.tutorial.atm.Atm</service-endpointinterface> </port-component-ref> </service-ref> </application-client>

5.2 Environment context Create the jboss-client.xml in the client directory
<jboss-client> <!-- JNDI name bound to client's environment context --> <jndi-name>atm-client</jndi-name> <service-ref> <!-- The service-ref element to configure--> <service-ref-name>service/ATM</service-ref-name> <!-- published WSDL file--> <wsdl-override>http://localhost:8080/atm/frontEnd?wsdl</wsdl-override> </service-ref> </jboss-client>

5.3 Application client package To build the application client package, call:
ant pack-client

The result is an archive named atm-client.jar (in directory build); its contents are:
+ META-INF - application-client.xml

39

JBoss jBPM BPEL 1.0
- jboss-client.xml - jaxrpc-mapping.xml

6 Deploy the BPEL application
6.1 Messager servlet Modify the web.xml descriptor to include the messager servlet in the same way as the hello world example. 6.2 BPEL application descriptor We assign a queue for the frontEnd partner link in the bpel-application.xml descriptor.
<bpelApplication name="atm" xmlns="http://jbpm.org/bpel" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jbpm.org/bpel http://jbpm.org/bpel/bpel_application_1_0.xsd"> <partnerLinks> <partnerLink name="frontEnd"> <!-- name bound to the queue assigned to this partner link --> <myRole destination="jms/frontEndQueue" /> </partnerLink> </partnerLinks> </bpelApplication>

This time the process does not only produce a service but also consumes an external one. In this case the BPEL application descriptor must also supply a set of catalogs from which the process retrieves full WSDL definitions of deployed partner services. Right now jBPM BPEL comes only with a definition catalog: a collection of URLs, either absolute or relative to the web archive root, pointing to implementation WSDL documents. This should be enough for most applications. However, the design of the service catalog feature took into account UDDI registries, so a UDDI catalog will become available soon.
<bpelApplication...> ... <serviceCatalogs> <definitionCatalog> <!-- location of the WSDL document that describes the partner service --> <definition location="http://localhost:8080/session/sessionFactory?wsdl" /> </definitionCatalog> </serviceCatalogs> </bpelApplication>

The BPEL application descriptor is also the place for static assignment of endpoint references. If no endpoint reference is assigned here, the process must explicitly initialize the reference using the assign activity. As a third alternative, you can set the initiate attribute of the partnerRole element to "pull". Under this approach, the invoke activity will try to locate a partner service with a port that implements the partner role's declared port type.
<bpelApplication...>

40

JBoss jBPM BPEL 1.0
<partnerLinks> ... <partnerLink name="sessionFactory"> <partnerRole> <!-- static endpoint reference of the session generator service --> <wsa:EndpointReference xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"> <wsa:Address>USE_ACTUAL_URI_FROM_CATALOG</wsa:Address> <wsa:ServiceName xmlns:ses="urn:samples:session">ses:sessionService</wsa:ServiceName> </wsa:EndpointReference> </partnerRole> </partnerLink> </partnerLinks> </bpelApplication>

6.3 Destination and connection factory references We assign an entry in the web application’s environment context to the destination reference of the frontEnd partner link.
<web-app...> ... <message-destination-ref> <message-destination-ref-name>jms/frontEndQueue</message-destination-ref-name> <message-destination-type>javax.jms.Queue</message-destination-type> <message-destination-usage>ConsumesProduces</message-destination-usage> </message-destination-ref> </web-app>

Afterwards, we assign an entry in the web application’s environment to a JMS connection factory in the same way as the hello world example. 6.4 Binding references to actual resources Let's bind the destination and connection factory references to resources that exist in the operational environment.
<jboss-web> <resource-ref> <!-- connection factory reference (in web.xml) --> <res-ref-name>jms/ConnectionFactory</res-ref-name> <!-- actual resource in the java JNDI context --> <jndi-name>java:ConnectionFactory</jndi-name> </resource-ref> <message-destination-ref> <!-- destination reference (in web.xml) --> <message-destination-ref-name>jms/frontEndQueue</message-destination-ref-name> <!-- actual resource in the global JNDI context --> <jndi-name>queue/testQueue</jndi-name> </message-destination-ref> </jboss-web>

41

JBoss jBPM BPEL 1.0 6.5 Enterprise application deployment descriptor Here we create the application.xml descriptor that references the web module and the application client.
<application version="1.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/application_1_4.xsd"> <description>ATM enterprise application</description> <display-name>ATMApp</display-name> <module> <web> <web-uri>atm-web.war</web-uri> <context-root>/atm</context-root> </web> </module> <module> <java>atm-client.jar</java> </module> </application>

6.6 Enterprise application package To build the enterprise application archive, call:
ant pack-application

This will rebuild the web archive and create an atm-application.ear archive in directory build. Its contents are:
+ META-INF - application.xml - atm-web.war - atm-client.jar

6.7 Enterprise application deployment All is ready to deploy the enterprise application. Go back to the example base directory and call:
ant deploy-application

If the application was correctly deployed, should see messages on the server similar to these:
08:37:45,156 INFO application.ear 08:37:45,718 INFO 08:37:45,734 INFO exp.war/ 08:37:46,296 INFO 08:37:46,359 INFO 08:37:46,765 INFO 08:37:46,859 INFO 08:37:46,875 INFO application.ear [EARDeployer] Init J2EE application: file:/.../atm[ClientDeployer] Client ENC bound under: atm-client [TomcatDeployer] deploy, ctxPath=/atm, warUrl=.../atm-web[[/atm]] messagerServlet: BPEL application started: atm [WSDLFilePublisher] WSDL published to: file:/.../service.wsdl [AxisService] WSDD published to: ...\frontEndPort.wsdd [AxisService] Web Service deployed: http://.../atm/frontEnd [EARDeployer] Started J2EE application: file:/.../atm-

42

JBoss jBPM BPEL 1.0 Back in step 2, we assumed that the session generator service was already deployed somewhere. We must deploy this service before creating process instances, as the service catalog will retrieve the WSDL definitions when an invoke activity is executed. Change to directory partners/session. Edit the file build.properties to match your environment. Locate the Ant build file in directory. To deploy the session generator service to JBoss, call:
ant deploy

You should see these messages in the console:
08:59:13,812 INFO [TomcatDeployer] deploy, ctxPath=/session, warUrl=.../tmp1132session-exp.war/ 08:59:14,015 INFO [WSDLFilePublisher] WSDL published to: file:/.../session.svc.wsdl 08:59:14,062 INFO [AxisService] WSDD published to: ...\sessionPort.wsdd 08:59:14,062 INFO [AxisService] Web Service deployed: http://.../session/sessionFactory

7 Test the process
Once our process is up and running, we need to make sure that it is working as expected. Let's create a JUnit test case called AtmTest under the test directory. 7.1 Remote web service access This is the setup code for establishing a connection with the ATM service:
private Atm atm; protected void setUp() throws Exception { Context initialContext = getInitialContext(); // lookup the service interface in the environment context AtmService service = (AtmService) initialContext.lookup("java:comp/env/service/ATM"); // obtain the dynamic proxy for the web service port atm = service.getFrontEndPort(); }

This is a scenario in which we connect to the server, logon with some credentials, deposit and withdraw funds, logout and finally disconnect:
public void testAtmSimpleScenario() throws Exception { // connect to the server int sessionId = atm.connect(); assertTrue(sessionId > 0); // check the atm is connected String status = atm.status(sessionId); assertEquals("connected", status); // log on as identified customer atm.logon(sessionId, "Pete"); /* check the customer is logged on * logon is one-way, allow some time for the status to change */ Thread.sleep(500); status = atm.status(sessionId);

43

JBoss jBPM BPEL 1.0
assertEquals("loggedon", status); // get current balance double balance = atm.getBalance("Pete"); // deposit some funds OperationRequestType operation = new OperationRequestType(); operation.setCustomerName("Pete"); operation.setAmount(300); double oldBalance = balance; balance = atm.deposit(operation); // check the new balance is correct assertEquals(oldBalance + 300, balance, 0); // withdraw some funds operation.setAmount(100); oldBalance = balance; balance = atm.withdraw(operation); // check the new balance is correct assertEquals(oldBalance - 100, balance, 0); // try to withdraw a large sum operation.setAmount(100000); try { atm.withdraw(operation); fail("big withdraw should have failed"); } catch (OperationFaultType e) { assertEquals(100, e.getCode()); // check the account balance has not changed assertEquals(balance, atm.getBalance("Pete"), 0); } // logoff atm.logoff("Pete"); /* check the customer is logged off * logoff is one-way, allow some time for the status to change */ Thread.sleep(500); status = atm.status(sessionId); assertEquals("connected", status); /* disconnect from the server * disconnect is one-way, allow some time for the outgoing message to leave */ atm.disconnect(sessionId); Thread.sleep(500); }

7.2 Client JNDI properties We set the property j2ee.clientName in our JNDI context:
protected InitialContext getInitialContext() throws NamingException { // prepare the environment Properties env = new Properties(); // set the JNDI name bound to the client's environment context env.setProperty("j2ee.clientName", "atm-client");

44

JBoss jBPM BPEL 1.0
// properties in jndi.properties *and* env are placed in the environment return new InitialContext(env); }

7.3 Test execution The following target executes the junit test case:
ant run-test

If everything goes right the target output should look like this:
run-test: [junit] Testsuite: org.jbpm.bpel.tutorial.atm.AtmTest [junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 10.938 sec

45


				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:120
posted:7/17/2009
language:English
pages:45
Description: JBOSS JBPM