How-to: Deploy and Invoke a BPEL Process, Part Two: Invocation
Introduction
This How-to is a follow-on to BPEL
Process Deployment, which discusses the steps needed to hand-code
and deploy a BPEL process from scratch. Once you have deployed your
process it can be invoked from any language/application that can make
compliant SOAP invocations. This How-to discusses the details of
invocation from within a Java application. The basic
requirements are access to the necessary jars, access to the
process’ WSDL definition and connectivity to the Web Services
environment that hosts the process to be invoked. We’ll
discuss each of these in turn within the context of building a Java
application to invoke the “Hello, World!” echo process deployed in the
How-to, BPEL Process Deployment., If you haven’t gone
through that How-to, you should do so now.
As you begin this How-to, you should have the echo process deployed to a running
ActiveBPEL™ engine on a
Tomcat server to which you have connectivity from your system. A
server running on the same system you’re using for development is
fine.
Objectives
- Locate a target process' WSDL definition.
- Implement a Web Service client to access the process.
- Invoke the deployed process and examine the response.
Getting Set Up
The files provided with this How-to are contained in invoke.zip. You may extract this archive into a directory of your choosing. The archive contains numerous directories with an Eclipse Java Project, an ActiveWebflow™ BPEL Project and various support and deployment files.
If you plan to use ActiveWebflow
to create, simulate or test your process, run ActiveWebflow
Designer, select File / Import / Existing project into
workspace and navigate to the following ActiveWebflow
project directory
/invoke
Open the ActiveWebflow
project called invoke, 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 support.
Add the echoDefs.wsdl
file that you see there. It then appears in the Web References View.
If you’re using Eclipse to do your
client application development, run Eclipse, select File /
Import / Existing project into workspace and navigate to the
following Eclipse project directory
/invoke
Open the Java project called invoke, which has various supporting directories. The project is self-sufficient and contains the source files needed to build a test client application.
One manual step you may need to perform if using 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). Do this 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\ActiveWebflow Professional\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 either of these tools, you can still use the files in this How-to. There is a build.xml Ant script in the project directory root that contains build targets for compiling the source and running the client application - all described in detail below. Here’s the archive’s directory structure.
├─── doc
├─── src
│ └─── org
│ └─── activebpel
│ └─── samples
│ └─── invoke < Source File for Java test client
└─── support
└─── echo
├─── bpel < BPEL source echo.bpel
├─── META-INF
└─── wsdl < Web Service definition echoDefs.wsdl
WSDL File
Our work begins by examining the WSDL file for the process to be invoked.
Once
you’ve deployed the echo process
from
the Deployment How-to, you can view the deployed WSDL by pointing your
browser to:
http://localhost:8080/active-bpel/services/echoService?wsdl
After you’ve accessed the WSDL definition for a Web Services /
BPEL Process that you want to invoke, you’ll need to make note of
a few details, as follows:
- The target namespace for the process.
- The names and types for any message parts to be sent in the invocation request.
- The type for any message part to be returned in the response.
- The name of the operation you wish to invoke.
- The access URL, or endpoint, needed to invoke the process.
wsdl:definitions
When you access the WSDL for echoService, you should see the
following at the top of the output screen
activebpel/sample/wsdl/echoDefs/2006/09/echoDefs.wsdl">
. . .
The first definition you’re interested in recording here is the targetNamespace attribute of the wsdl:definitions element. This namespace is
used later in your Java application to specify the namespace for the
operation you wish to
invoke
in the BPEL process. Specifying the
operation requires construction of a QName, which comprises a namespace
and a name. This targetNamespace will
be used in constructing that QName.
wsdl:message
The first two child elements of the wsdl:definitions
element are wsdl:message elements.
These define the response and request messages. Note that the
order in which they appear here is completely arbitrary.
<wsdl:part name="echoPart1and2" type="xsd:string"/>
</wsdl:message>
<wsdl:message name="echoRequest">
<wsdl:part name="echoPart1" type="xsd:string"/>
<wsdl:part name="echoPart2" type="xsd:string"/>
</wsdl:message>
You should make a note here of the types
specified for the request and response parts.
These are all xsd:string, which indicates
that the Java objects you sending and receive are type java.lang.String.
Note also that echoRequest message has two parts, echoPart1 and echoPart2, which you’ll need to identify and
populate in your client code. The echoResponse
message has a single part, which is the
result sent back by the process after it concatenates the two parts
from the echoRequest message. You
don’t really care about its name,
since you won’t have to specify it in your Java source, but you
do want to remember
its type, as you'll need to define a
corresponding object of that type to hold the response.
wsdl:portType and wsdl:operation
The WSDL portType and operation
are defined next.
<wsdl:operation name="echo">
<wsdl:input name="echoRequest" message="tns:echoRequest"/>
<wsdl:output name="echoResponse" message="tns:echoResponse"/>
</wsdl:operation>
</wsdl:portType>
The only portion of interest here, which we want to record for use later, is the wsdl:operation element’s name attribute: echo. This is the name portion of the QName wel specify when defining the operation we want to invoke from our client.
wsdl:binding
The wsdl:binding element, when present, specifies the concrete binding information associated with the service defined in the WSDL. For this How-to we've chosen a binding type of "rpc encoded", to match the mechanisms we use in the Java client (org.apache.axis.client.Call and org.apache.axis.client.Service). Other choices are "doc literal" and "rpc literal".
The binding element for our echo process is defined as follows:
<wsdlsoap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<wsdl:operation name="echo">
<wsdlsoap:operation soapAction=""
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"/>
<wsdl:input name="echoRequest">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://docs.active-endpoints.com/
activebpel/sample/wsdl/echoDefs/2006/09/echoDefs.wsdl"
use="encoded"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:input>
<wsdl:output name="echoResponse">
<wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
namespace="http://docs.active-endpoints.com/activebpel/
sample/wsdl/echoDefs/2006/09/echoDefs.wsdl"
use="encoded"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
wsdl:service
The wsdl:service element defines the
address normally used to access the BPEL process. The URL is
defined as the location
attribute of the soap:address element as
shown below.
<wsdl:port binding="tns:echoServiceBinding" name="echoServicePort">
<soap:address location=
"http://localhost:8080/active-bpel/services/echoService"/>
</wsdl:port>
</wsdl:service>
Required jars
To implement a Java client that
interacts with a BPEL process, wel need resources
defined in a number of Java library archives. These are as
follows:
- axis.jar
- commons-discovery.jar
- commons-logging.jar
- jaxen-1.1-beta-2.jar
- jaxrpc.jar
- saaj.jar
- wsdl4j.jar
- xercesImpl.jar
- xml-apis.jar
These jars must be available on your system and specified in the Java classpath during program compilation and execution. If you're using the Eclipse project provided with this How-to, these references are predefined using the CATALINA_HOME variable.
Java Client Application Sample Source Code
Now that we’ve identified the WSDL parameters needed, and we have access to the necessary Java libraries required to implement our client class, we can start on the actual source code for the client application. As it turns out, it’s actually fairly simple.
import javax.xml.rpc.ParameterMode;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
public class TestClient
{
public static void main(String [] args)
{
try {
String endpoint =
"http://localhost:8080/active-bpel/services/echoService";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(
new QName("http://docs.active-endpoints.com/
activebpel/sample/wsdl/echoDefs/2006/09/echoDefs.wsdl", "echo") );
call.addParameter("echoPart1", org.apache.axis.Constants.XSD_STRING,
ParameterMode.IN);
call.addParameter("echoPart2", org.apache.axis.Constants.XSD_STRING,
ParameterMode.IN);
call.setReturnType(org.apache.axis.Constants.XSD_STRING);
String ret = (String) call.invoke(
new Object[] { "Hello, ", "World!" } );
System.out.println("Sent 'Hello, ' and 'World!', got '"
+ ret + "'");
} catch (Exception e) {
System.err.println(e.toString());
}
}
}
If you’re not running the ActiveBPEL
engine in a Tomcat server on port 8080, you may need to change the line
that defines the endpoint variable.
Aside from that, the rest of this java class should work as shown.
Note the various points in the code where we use the references we noted earlier. You should easily be able to match the values in the code above (those in blue italics) with the noted references.
This TestClient class presently hard-codes the two message parts that are sent to the BPEL process. These are “Hello, “ and “World!”. The process concatenates these two strings and returns the string “Hello, World!” as the result.
So when you compile and run this application, you should see the following output:
Once you have this running and successfully invoking with the echo process, you might try modifying the application to accept two strings as user or command-line input, and to use that input as the input values to the process.
Note that this How-to also includes a Java client and ant build
targets that demonstrate the "doc/lit" (document style, literal usage)
method of service invocation. See TestClientDocLit.java and
build.xml for information on how to build, deploy and run this example.
This client depends on the util
project.
That’s it! If you run into problems, the first place to look for trouble is typos in the various parameters copied from the WSDL.
Resources
Join a discussion on this topic in the ActiveBPEL Forum. Login to participate.
Copyright © 2004–2006 Active Endpoints, Inc. - All Rights Reserved
