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
- Modify the WSDL associated with a process to redirect outbound Web Service invocations to a test URN
- Set up a series of WSUnit test response files and the configuration information needed to use them
- Use a Java client to invoke a test process whose Invoke activity requests are handled by WSUnit
- Optionally, use the ActiveBPEL Server 3.0 engine's URN Mapping mechanism to redirect outbound Web Service invocations instead of modifying WSDL files
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.
├─── 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, 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:
<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:
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.
Copyright © 2004–2006 Active Endpoints, Inc. - All Rights Reserved
