Version 3.0 - September, 2006
Testing BPEL Processes with WSUnit and the ActiveBPEL Server Engine
Introduction
Getting Set Up
WSUnit Configuration
Test Process and Client Application
URN Mapping in ActiveBPEL Server 3.0

Testing BPEL Processes with WSUnit and the ActiveBPEL Server Engine

Introduction

WSUnit is a tool for testing Web Service consumers. It generates consistent, repeatable responses to Web Service invocations. Because BPEL processes invoke Web Services, WSUnit is a useful tool to examine process behavior. Using WSUnit in conjunction with ActiveBPEL Server engine's URN Mapping capability, you can perform repeatable unit testing during process development and throughout process life cycle.

This sample demonstrates the use of WSUnit in conjunction with the ActiveBPEL Server engine to provide fixed, predefined responses to Web Service invocations. It also explores ways to select from fixed responses based upon message part values set in the invocation request message.

Also included in this sample is a section on ActiveBPEL Server's URN Mapping function, and how this function is used to avoid any changes to your WSDL when testing. This method requires that you have installed version 3.0 of the ActiveBPEL Server engine, which contains URN Mapping capability in the Administration Console.

Objectives

Getting Set Up

You may extract this sample's archive into a directory of your choosing. The archive contains numerous directories with an Eclipse Java Project and various support files.

If you plan to use ActiveBPEL Designer to create, simulate or test your process, run ActiveBPEL Designer, select File / Import / Existing project into workspace and navigate to the following ActiveBPEL project directory.

/wsunit

Import the ActiveBPEL project called wsunit, which should appear in the Navigator View.

With the project successfully imported, switch to the Web References View and select the Add a Web Reference icon. Select the Browse Projects... button and navigate to the wsdl directory under wsunit. Add the wsEchoDefs.wsdl and wsunittest.wsdl files that you see there. They appear in the Web References View.

If you're using Eclipse for your client application development, run Eclipse, select File / Import / Existing project into workspace and navigate to the following Eclipse project directory

/wsunit

Open the Java project called wsunit, with various supporting directories. The project is self-sufficient and contains the source, support and configuration files needed to build your test client application.

One manual step you may need to perform in Eclipse is to create a CATALINA_HOME variable for the project's Java Build Path (i.e., you may see "Unbound classpath variable" errors for the project). Create the variable by right-clicking on the project in the Package Explorer and selecting Properties. Next, select Java Build Path, select the Libraries tab, and click the Add Variable... button. Click the Configure Variables... button in the dialog that appears, and then New... Create a CATALINA_HOME variable that points to the root of the application server in which your BPEL Engine is running (e.g., C:/jakarta-tomcat-5.0.28, C:\Program Files\Active Endpoints\ActiveBPEL Designer\Server\ActiveBPEL_Tomcat, etc.) – it must have a shared/lib directory containing the necessary jars for this project (see below). Click OK to exit the dialogs and answer Yes if asked to do a full rebuild of the project.

If you're not using ActiveBPEL Designer or Eclipse, you can still use the files in this sample. Here's the archive's directory structure.

wsunit
├─── doc
├─── src
│    └─── org
│         └─── activebpel
│              └─── samples
│                   └─── wsunit  < Source File for Java Client App.
└─── support
     ├─── bpel_process  < BPEL and WSDL files
     │    ├─── bpel     < .bpel file for process to be tested
     │    ├─── bpr      < .pdd and .bpr files for ActiveBPEL Server 3.0
     │    │    └─── v1.1  < .bpr and supporting files for ActiveBPEL 1.1 engine
     │    └─── wsdl     < .wsdl files
     └─── sample_data   < WSUnit sample data response directories, files

Inside the support/sample_data subdirectory is a directory named active-bpel. Copy active-bpel and its contents to CATALINA_HOME/shared/classes. This puts WSUnit's sample data response files into the server classpath.

Next, copy the wsunit.war file, found in the support directory, to CATALINA_HOME/webapps. This is the WSUnit web application that handles the Web Service invocations for our process-under-test.

WSUnit Configuration

WSUnit is a servlet that examines the URL for the request target, service name, operation and one or more optional message parts. It uses these elements to construct a mapping to a file system location that contains a response file that you create. As such, the directory structure and the configuration file contents for the response files you'll provide are directly related to the URL associated with the Web Service invocation we wish to test. Taking a look at wsEchoDefs.wsdl, we find a portType, wsEchoService, which exposes an operation called echo. This is the portType / operation combination our test process (testWsUnit.bpel) consumes as part of its normal operation. Based on the WSDL specifications in wsEchoDefs.wsdl, the URL to invoke this service looks like this:

http://localhost:8080/active-bpel/services/wsEchoService

Note that while the host for this URL is local, it could be any valid Web Service host.

In order to test our process, we will program it to invoke a service endpoint that causes WSUnit to provide the response (in place of the real service). To do this, we make some modifications to the WSDL (and indirectly, to the Process Deployment Descriptor) so that the invocation request message goes to WSUnit.

To facilitate our testing, we need to modify this endpoint URL in the WSDL and then set up directories and files used by WSUnit in returning a response.

Modifying the WSDL for WSUnit

Note: if you're using this sample in conjunction with ActiveBPEL Server 3.0 (or ActiveBPEL Enterprise), you should perform the steps in URN Mapping in ActiveBPEL Server 3.0 and then continue with the next sub-section - WSUnit Configuration. If you're using ActiveBPEL 1.1 or earlier, you'll need to perform the steps in the next several paragraphs in order to directly modify the endpoint for the invoke activity contained in the BPEL process being tested.

Locate the file support/bpel_process/bpr/v1.1/testWsUnit_1.1.bpr. This is the ActiveBPEL version 1.1 compatible Business Process Archive file that deploys the BPEL process we'll be testing with WSUnit. It is comprised of the files in the v1.1 subdirectories, to which we've made the following modification.

In order to redirect the invocations from the process under test, we modify the endpoint URL for the service consumed by the invoke activity in our process under test. View .../v1.1/wsdl/wsunit/wsEchoDefs.wsdl and note the following line, near the bottom:

<wsdlsoap:address location="http://localhost:8080/wsunit/active-bpel/services/wsEchoService"

Note the addition of "wsunit/", as compared to the copy of this file in support/bpel_process/wsdl. This change causes the wsEchoService invocation to be directed to WSUnit, which will return one of a number of fixed response files.

When testing, similiar modifications are made to the endpoint URL of any services invoked by processes you want to test with WSUnit. You then generate the Process Deployment Descriptor and Business Process Archive files as you normally would (these have been created for you in this sample).

WSUnit Configuration

WSUnit locates test response files by mapping parts of the service request URL and the operation to a file system location. For our test, we use the service consumed by the invoke activity in our process under test, /active-bpel/services/wsEchoService, as a guide to an identical directory found under CATALINA_HOME/shared/classes (where we copied it earlier). If you traverse into this directory, you will find one of WSUnit's configuration files: dir-keys.properties. For our purposes, only one entry is needed in this file:

xpath.name=/Envelope/Body/*

This is a directive to WSUnit that says, essentially, "take the name of the first tag found in the SOAP Envelope's Body element and use that to determine the directory to traverse into next". In our case, the first tag is the operation being invoked, echo, and we see that this is the name of the directory we've created at this level.

Inside the echo directory, we find another of WSUnit's configuration files: file-keys.properties. In our configuration, WSUnit will use the entries in this file to determine which response file to return to the invoking process (i.e., the Web Service consumer we're testing). Our file-keys.properties file has two entries:

xpath.content=/Envelope/Body/echo/echoPart1/text()
xpath.content=/Envelope/Body/echo/echoPart2/text()

This is a directive to WSUnit that says, "get the value of echoPart1, combine it with the value of echoPart2, and use that to form a filename root". The filename that results from this process is of the form key1-key2.xml, where key1 and key2 are the values found in the message parts specified and a dash is used to separate them.

Looking into the echo directory we find, in addition to file-keys.properties, the following files:

default.xml
Hello-Leia!.xml
Hello-Luke!.xml
Hello-World!.xml

Each of these files contains an XML representation of a SOAP message, one for each simulated response we want to return to our Web Service consumer while testing it. The default.xml file is returned by WSUnit if it can't find a match. The others are returned as "requested", i.e., by placing the appropriate values into the echoPart1 and echoPart2 parts when invoking the wsEchoService Web Service. In this way it's possible to simulate an infinite number of response scenarios, simply by sending different message part values as needed.

With our test response setup complete, copy the appropriate Business Process Archive (.bpr) file to CATALINA_HOME/bpr (note: if your server installation has no bpr directory, follow the steps to install ActiveBPEL, found here). If you're working with ActiveBPEL 1.1, then deploy .../v1.1/testWsUnit_1.1.bpr, if working with ActiveBPEL Server 3.0, then deploy support/bpel_process/bpr/testWsUnit.bpr.

Test Process and Java Client Application

Now that we have the WSUnit configuration set up, the next step is to create a BPEL process to test and a client application to invoke that process.

If you traverse to the wsunit/support/bpel_process/bpel directory (or open the ActiveBPEL project called wsunit, discussed above), you will find testWsUnit.bpel, which is a simple process that accepts a message containing two xsd:string message parts and passes those two values to an invocation of the wsEchoService Web Service. The response to this invocation is then passed back as a reply to the caller.

In this case the caller is a Java client application defined in WSUnitTestClient.java, which is found in the Eclipse project discussed above: org.activebpel.samples.wsunit. If you're not using Eclipse you can find it in wsunit/src/org/activebpel/samples/wsunit/WSUnitTestClient.java.

This Java client comprises three Web Service invocations. Each invocation calls the wsUnitTestPLTService service that is exposed by testWsUnit.bpel. and each sends different values for the echoPart1 and echoPart2 request message parts. The responses generated by WSUnit and returned by our test process are determined by those message part values.

It's important to note here that wsEchoService is defined in wsEchoDefs.wsdl, but the Web Service itself is not actually deployed anywhere for the purposes of our testing. We use WSUnit to simulate this service - at least as far as its response is concerned. For real-world operation, this Web Service would be deployed and, without the WSDL changes performed above (or URN Mapping described below), would be invoked by the BPEL testWsUnit.bpel process.

At this point we're ready to test. Ensure that you have copied the wsunit.war and the appropriate BPR files to the appropriate directories (see Getting Set Up), then start your Tomcat (or equivalent) server to initialize the ActiveBPEL Server engine. Run WSUnitTestClient.java as a Java Application and you should see the following output:

Sent request, received 'Hello, World! This is a response from wsunit.'
Sent request, received 'Hello, Luke! This is a response from wsunit.'
Sent request, received 'Hello, Leia! This is a response from wsunit.'

In each of the three calls, the variation in the request message causes WSUnit to return a different response, as determined by the file selected through examination of the URL, service, operation and message part values. Examine the service and operation names, as well as the request message values to see which response files were returned from the WSUnit response directories.

In configuring WSUnit, you can specify multiple operations supported by a service, if needed. You can create a correspondingly-named directory for each and WSUnit could resolve them all with the single entry in dir-keys.properties. More complex entry constructs are available - please see the WSUnit sample code and documentation for details (note: you may need to register with java.net, and request an Observer role for the wsunit project, in order to download code here).

URN Mapping in ActiveBPEL Server 3.0

The ActiveBPEL Server engine version 3.0 includes a URN Mapping function we can use to simplify our WSUnit testing - especially in cases where the WSDL upon which our process is based is not easily editable. Using AcitveBPEL's URN re-map capability, we can redirect invocations to WSDL-specified endpoints so that those invocations are handled by WSUnit when our process-under-test invokes it.

With the ActiveBPEL Server engine running, launch the Administration Console in your browser via

http://localhost:8080/BpelAdmin/

Select the Configuration link in the Engine menu and then select the URN Mappings tab (note: if you don't see this tab, you need the 3.0 version of the ActiveBPEL Server engine and can get it here when it becomes available). In the Add new config section, enter a new URN of

ae:services

and a URL of

http://localhost:8080/wsunit/active-bpel/services/${urn.3}

Click Add/Update Mapping. We'll talk about how this mapping works further on.

URN Mapping

ActiveBPEL Server 3.0 and later accepts Process Deployment Descriptor (.pdd) files with wsa:Address specifications defined as replaceable tokens as well as standard URLs. The standard deployment descriptor for our testWsUnit.bpel process looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<process location="bpel/wsunit/bpel/testWsUnit.bpel" name="bpelns:wsunittest"
  xmlns="http://schemas.active-endpoints.com/pdd/2004/09/pdd.xsd"
  xmlns:bpelns="http://docs.active-endpoints.com/activebpel/sample/bpel/wsunittest/
  2006/09/wsunittest.bpel"
  xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
  <partnerLinks>
    <partnerLink name="echoPLT">
      <partnerRole endpointReference="static">
      <wsa:EndpointReference xmlns:s="http://docs.active-endpoints.com/
        activebpel/sample/wsdl/wsEchoDefs/2006/09/wsEchoDefs.wsdl">
          <wsa:Address>
            http://localhost:8080/active-bpel/services/wsEchoService
          </wsa:Address>
          <wsa:ServiceNamePortName="wsEchoService">
            s:wsEchoServiceService
          </wsa:ServiceName>
        </wsa:EndpointReference>
      </partnerRole>
    </partnerLink>
    <partnerLink name="wsUnitTestPLT">
      <myRole allowedRoles="" binding="RPC" service="wsUnitTestPLTService"/>
    </partnerLink>
  </partnerLinks>
  <wsdlReferences>
    <wsdl location="project:/wsunit/wsdl/wsunittest.wsdl"
         namespace="http://docs.active-endpoints.com/
         activebpel/sample/wsdl/wsunittest/2006/09/wsunittest.wsdl"/>
    <wsdl location="project:/wsunit/wsdl/wsEchoDefs.wsdl"
         namespace="http://docs.active-endpoints.com/
         activebpel/sample/wsdl/wsEchoDefs/2006/09/wsEchoDefs.wsdl"/>
  </wsdlReferences>
</process>

Here, we can replace the wsa:Address specification, which defines the URL for the endpoint invoked by our test process, shown above in blue italics, to a tokenized string. In this case we'll replace the endpoint reference URL with a tokenized mapping specification:

<wsa:EndpointReference xmlns:s="http://docs.active-endpoints.com/
  activebpel/sample/wsdl/wsEchoDefs/2006/09/wsEchoDefs.wsdl">
  <wsa:Address>
    ae:services:wsEchoService
  </wsa:Address>
  <wsa:ServiceName PortName="wsEchoService">
    s:wsEchoServiceService
  </wsa:ServiceName>
</wsa:EndpointReference>

Part of this specification, ae:services, should look familiar because it's the URN we used earlier to map to the wsunit application deployed in our server environment. The URL to which we mapped that URN ended with the text ${urn.3}. This indicates to the mapper that the base URL should be appended with the third token in the wsa:Address value (if it finds one), in this case wsEchoService. When the mapper has completed its token replacement, the resulting URL is:

http://localhost:8080/wsunit/active-bpel/services/wsEchoService

This is just what we want, since /wsunit is exactly where our wsunit Web Application is located.

Feel free to experiment with WSUnit by varying the request message, changing the response value to a complex data structure, or other tests.

Thanks go to Daniel Bradby for making WSUnit available and providing additional technical information in the preparation of this sample.