Note: You should be familiar with WebSphere Studio Application Developer Integration Edition Version 5.1.1 Web services development environment, ASP .NET Web services, and have knowledge of building a BPEL process. The sample code for the BPEL business process is included.
BPEL, through its use of XML and Web services, has quickly become the cornerstone of Service-Oriented Architecture (SOA) implementations and provides the open standard for the WebSphere Application Server Enterprise Process Choreographer (Process Choreographer). Over the years, many business applications have been developed and deployed on J2EE platforms and .NET platforms, independently and in parallel. Those business applications are designed with fine-grained business functions. For example, in the J2EE world, information persistence is implemented using entity beans and business logic using session beans. Within the limited business domains, those business applications also provide an integration framework to integrate with back-end or legacy enterprise applications. For example, the Java Connector Architecture (JCA) and Java Messaging Service (JMS) are the typical integration frameworks for J2EE applications.
With the emergence of Web services, the back-end enterprise applications are exposed as discoverable and callable business services through the use of WSDL. WSDL defines the service semantics for the Web service interface, such as operations, protocol bindings, and message types. BPEL is a layer on top of WSDL; it specifies the behavior for the composite Web services participating in a process flow. Therefore, it enables business analysts and architects to define the logic of business process flow, and it makes it possible to use BPEL to support long-running conversations with J2EE Web Services and .NET Web Services.
In essence, whether a BPEL process flow succeeds or not all boils down to the XML service semantics defined in the WSDL document of each participant Web service. XML schemas differentiate XML from other file formats. XSD, the XML schema definition, is a comprehensive and complex data typing system. Simply put, XSD defines what an XML document should look like. Designing simple and strongly-typed objects from XSD is fundamental to Web services interoperability. "Improve interoperability between J2EE technology and .NET" (Part 1 of this series) pointed out that many Web services programmers neglect the importance of the XSD schema design.That is, they use their favorite programming language to code the Web services implementations and then derive the Web service semantics from the implementation using vendors' tools. This bottom-up approach creates interoperability problems.
A common source of interoperability problems between .NET and J2EE are issues resulting from the use of XML namespace and complex-data types, such as nested complex-type arrays and dates and times (Part 2 and Part 3 of the series). This tip shows how a nested array, complex types, and dates can be safely and accurately passed between the two platforms in the BPEL process integration, but only if you design the XSD schema for those complex types carefully.
To build the process, you must install IBM WebSphere Studio Application Developer V5.1.1 and Microsoft .NET Framwork 1.1 on a Windows machine. For this tip, both products are installed and run from the same machine. .NET Visual Studio is the integrated tool for building a .NET Web service, but for the purpose of this tip, it's not used.
By default, the document root for IIS is C:\Inetpub\wwwroot. I use this directory for publishing a .NET Web service. Also, the .NET Framework 1.1 is installed in C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322 and the SDK in c:\Program Files\Microsoft.NET\SDK\v1.1.
Add the following two directories to the system PATH variable:
- c:\Windows\Microsoft.NET\Framework\v1.1.4322
- c:\Program Files\Microsoft.NET\SDK\v1.1\Bin
The sample code for the BPEL business process is included in the Download section.
A typical interop business scenario
Consider a purchasing scenario in which a buyer works through a merchandise agent to fulfill an order request. The merchandise agent has a number of participating suppliers; each participant is an independent subscriber and has its own independent product inventory management system, which means one supplier might run J2EE Web services to manage its inventory and another to run .NET Web services.
The purchasing process begins with getting product quotes from different suppliers. Before a buyer submits an order, the agent communicates with each supplier for a product quote, and each supplier returns the detailed information about the product in its inventory. The buyer then reviews the information and proceeds with the next ordering process. Figure 1 shows a sequence diagram for the quote request with two participating suppliers: Supplier A and Supplier B. The buyer requests a quote from the agent, and the agent issues a quote request to each supplier and returns the composed quotes to the buyer.
Figure 1. Sequence diagram for the quote request

In the diagram:
- Buyer is the client who initiates the purchasing request.
- Agent is the business process that requests product information from each supplier and places the order for the buyer.
- Supplier A is the Java Web service managing the inventory for Supplier A.
- Supplier B is the .NET Web service managing the inventory for Supplier B.
For the purchasing request from the buyer, the agent process first constructs a product quote request for each supplier. Each supplier responds with the product information, including the price, quantity, and other propriety product information. The agent then returns the composed product information for the buyer to review and enters the order.
The following sections build the Java Web service for Supplier A, .NET Web service for Supplier B, and the agent process.
Create the Java Web service for Supplier A
In Part 1 of this series, you found out that one of the foremost best practices often neglected is the design of the XML schemas and WSDL for a Web service. Programmers often start building Web services in their favorite programming language and then use vendor tools to derive the Web services semantics and expose the WSDL. This is a bottom-up approach -- it does not take into consideration the fact that Web services are message-centric and data and message types must be carefully designed, rather than generated by tools. This section shows how the XML schema and WSDL for a Web service can be designed using WebSphere Studio Application Developer Integration Edition Version 5.1.1.
For Supplier A, the inventory service must implement at least two operations: getQuote to return the product information in its inventory and fulfillOrder to fulfill the order request from the agent. Figure 2 below demonstrates this process for the service interface.
Figure 2. The interface diagram for Supplier A Web services

The Product is a flat complexType with four attributes; each is a primitive data type. This section shows how to leverage the XML schema editor in WebSphere Studio Application Developer Integration Edition Version 5.1.1 to define the product type in the XML schema language. The next section shows how to design a compound Product complexType for the .NET Web service to demonstrate the interoperability.
Step 1. Create a service project
First, create a service project and a package to hold the XML schema files and WSDLs for all of the partner Web services and process definitions.
- Start a new WebSphere Studio Application Developer Integration Edition Version 5.1.1 workspace.
- Select File>New>Service Project.
- Specify the service project name as
QuoteProcessServiceand click Finish. - Right-click on the
QuoteProcessServiceproject and select New>Package. - Enter a new Java package name
quote.processand click Finish.
Step 2. Create a new XML schema
Next, create a new XML schema and define the Product complexType.
- Right-click the package
quote.processand select New>XML schema. - Enter the new schema name
SupplierASchema.xsdand click Finish. The XML schema editor opens. - In the Outline view, select the
SupplierASchema.xsd. - In the Schema panel, enter
http://schema.a.supplieras the namespace URI. This will be the target namespace for the schema. Click Apply. - In the Outline view, right-click
SupplierASchema.xsdand clickAdd Complex Type. - In the Outline view, select
NewComplexType. - In the Complex Type panel, enter the name for the complex type:
Product. - In the Outline view, right-click the
Producttype and clickAdd Content Model. - In the Outline view, expand the
Product. - Right-click the content model icon and click
Add Element. ANewElementis added. - In the Outline view, select the
NewElement. - In the Element panel, rename the
NewElementas_nameand set the type toxsd:string.
Notice that in Step 4, the target namespace for the schema is set to http://schema.a.supplier instead of http://a.supplier/schema. This is the result of the JAX-RPC behavior: JAX-RPC will make the domain name part of the URI to generate the package name for the serializable product class. To avoid potential naming conflicts, the domain name part of the namespace URI should be as fine-grained as possible, as illustrated in "
Improve interoperability between J2EE technology and .NET, Part 3
". Another reason for that is some clients will fail to find a de-serializer when the namespace qualified product object ({http://a.supplier/schema}Product) is received, while the Java package for the serializer class is supplier.a.
Repeat the last three steps, create the remaining elements for Product type and save the XSD file.
_price: xsd:float_qty: xsd:int_refurbished: xsd:boolean
Step 3. Create the WSDL for Supplier A
You can now design the WSDL for Supplier A and define the service methods (operations) and message bindings. In the quote process, getQuote is the only operation needed.
First, create a blank WSDL and import the product schema defined in the previous steps.
- Right-click the
quote.processpackage. Select New>Other>Web Services>WSDL and click Next. - Enter the new WSDL name
SupplierAService.wsdland click Next. - In the wizard, set the target namespace to
http://a.supplier/service/and click Finish. The WSDL editor opens. - In the Outline view, right-click Imports and select Add Child>Import.
- In the Import panel, click on the push button beside the location box.
- Browse to
SupplierASchema.xsdand click OK.
The Product complexType is imported into the WSDL under the namespace http://schema.a.supplier.
Step 4. Create messages and message parts
Next, create the messages and message parts. For each getQuote invocation, there is a request message that sends the product name and a response message that returns the Product object from the inventory.
- In the Outline view, right-click Messages and select Add Child>Message.
- Enter the name
getQuoteRequest. - Right-click the newly created
getQuoteRequestand select Add Child>Part. - Name the new message part
productNameand click OK.
Notice that the message part name has a default type xsd:string. Accept the default. Now repeat the above steps. Create a new message getQuoteResponse with a message part product, which is the Product type defined in the imported SupplierASchema.xsd.
- Right-click the
Productmessage part and click Set Type. - Check Select Existing Type radio box, and select
xsd1:Product, as shown in Figure 3 below. Click Finish.
Figure 3. Specify type for product message part

Next, define the Port Type, where all service operations are exposed. In this scenario, only the getQuote operation is defined.
- In the Outline view, right-click the
Port Typesand select Add Child>Port Type. - Name the new port type
SupplierAQuotePortTypeand click OK. - Right-click
SupplierAQuotePortTypeand select Add Child>Operation. - Enter the new operation name
getQuoteand click OK. - Right-click the
getQuoteoperation and select Add Child>input. - Right-click input>Set Message.
- Select the existing message
tns:getQuoteRequestthat you defined in Step 4. Create messages and message parts and click Finish.
Repeat the above three steps. Create an output for getQuote operation and link it to the tns:getQuoteResponse.
Step 6. Define the binding protocol
Finally, you can define the binding protocol for the service port.
- In the Outline view, right-click the
Bindingsand select Add Child>Binding. - Specify the binding details, as shown in Figure 4 below. Make sure that document/literal is selected as the SOAP binding option. Click Finish.
- Right-click the
Servicesand select Add Child>Service. - Enter
SupplierAQuoteServiceas the new service name and click OK. - Right-click the
SupplierAQuoteServiceand select Add Child>Port. - Enter the port details as in Figure 5 and click Finish.
Figure 4. Specify binding details

Figure 5. Specify service port details

Step 7. Implement the Web service
Finally, you can implement a Web service based on the SupplierAService.wsdl and SupplierASchema.xsd. WebSphere Studio can generate a skeleton Java bean Web service from the WSDL.
- Select File>New>Other>Web Services>Web service and click Next.
- In the next Web Service Wizard, select Web service type Skeleton Java bean Web Service. Leave other fields as the default settings and click Next.
- In the next window, specify
SupplierAServiceEARas the Service project EAR andSupplierAServiceWebas the Service Web project. This is the enterprise project that holds the Java Web service. Click Next. - Browse to the
SupplierAService.wsdlthat you just created. Click OK, click Next, and click Finish.
Examine the SupplierAServiceWeb project. A serializable Product class is created from the complex type Product defined in SupplierASchema.xsd and a Java skeleton Web service is built. But this is an empty service that only has the interface functions; the concrete implementation of the interface operation getQuote needs to be provided by hand in the SupplierAQuoteServiceBindingImpl class.
First, add a constructor to the Product class.
Listing 1. Adding a constructor to the
Product class
public Product(String name, int qty, float price, boolean isRefurbished) {
this.set_name(name);
this.set_qty(qty);
this.set_price(price);
this.set_refurbished(isRefurbished);
}
|
Next, add a constructor to the SupplierAQuoteServiceBindingImpl class to hard-code the inventory. In reality, you would need to expose an interface method, such as addInventory(Product item), to restock a product.
Listing 2. Adding a constructor to the
SupplierAQuoteServiceBindingImpl class
private static Hashtable fCurrentInventory = new Hashtable();
public SupplierAQuoteServiceBindingImpl() {
fCurrentInventory.put(
"IBM ThinkPad T40",
new Product("IBM ThinkPad T40", 200, 1499.99f, false));
fCurrentInventory.put(
"Dell Inspiron 4000",
new Product("Dell Inspiron 4000", 100, 999.99f, true));
fCurrentInventory.put(
"Toshiba Satellite 2210X",
new Product("Toshiba Satellite 2210X", 300, 599.99f, false));
}
|
Replace the getQuote method in the SupplierAQuoteServiceBindingImpl class with the code in Listing 3.
Listing 3. Replacing the
getQuote method
public Product getQuote(java.lang.String productName)
throws java.rmi.RemoteException {
if (fCurrentInventory.containsKey(productName))
return (Product) fCurrentInventory.get(productName);
else
return new Product(productName, 0, 0f, false);
}
|
The quote Web service for Supplier A is ready to deploy and run. You will not test until after BPEL process has been created.
Create the .NET Web service for Supplier B
For the .NET Web service for Supplier B, you will add a little more complexity to the schema: nesting an array of complex types inside another complex type. This added complexity isn't significant in a programming language and is quite a natural thing to do in reality, but it's the frequent source of the XML message serialization failure. Most notably, the message receiving side is often unable to match a proper XML serializer class.:dateTime is also a common source of interoperability problems between J2EE and .NET. One main purpose of this tip is to show how you can avoid the interoperability problem by carefully designing the XML schemas for the messages and data types.
To build the .NET Web service, you will use a slightly different approach. But the XSD schemas should always be designed first.
Assume Supplier B has a different requirement to keep its inventory product information. Instead of listing a product as refurbished or not as in Supplier A, Supplier B keeps a list of information for its products such as manufacturing date, inventory date, and restocking date.
Figure 6. The interface diagram for Supplier B Web service

In this UML diagram, Product has an attribute _dates, which is an aggregate of DateInfo, which in turn is a complex type. A UML aggregate translates to an array in a programming language. But on the other end, how is the relationship between the Product and the DateInfo represented in XML schema or as an XSD type? It needs another complex type ArrayOfDateInfo to represent the relationship. The ArrayOfDateInfo type will have an unbound sequence of elements of the DateInfo type. Therefore, to properly serialize the Product object in the .NET Web service, three complex types need to be defined in the XML Schema: DateInfo, ArrayOfDateInfo, and Product.
Similar to the steps illustrated in the previous section, first create a SupplierBSchema.xsd with the target namespace http://schema.b.supplier and define a complex type DateInfo, as shown in Listing 4.
Listing 4. Defining a complex type
DateInfo
<complexType name="DateInfo">
<sequence>
<element name="_date" type="dateTime"/>
<element name="_desc" type="string"/>
</sequence>
</complexType>
|
Next, add a complex type ArrayOfDateInfo with an unbounded sequence of elements of the DateInfo type in the SupplierBSchema.xsd.
- In the Outline view, right-click the
SupplierBSchema.xsdand click Add Complex Type. - Rename the new complex type
ArrayOfDateInfo. - Right-click on the
ArrayOfDateInfoand click Add Content Model. - Right-click on the content model icon and click Add element.
- Rename the new element as:
DateInfo. - Set the user-defined complex type:
SupplierBSchema:DateInfo. - Set
minOccursattribute to be zero and themaxOccursattribute to be unbounded.
Listing 5 contains the resulting ArrayOfDateInfo schema.
Listing 5. The
ArrayOfDateInfo schema
<complexType name="ArrayOfDateInfo">
<sequence>
<element maxOccurs="unbounded" minOccurs="0"
name="_dateInfo" type="SupplierBSchema:DateInfo"/>
</sequence>
</complexType>
|
Follow the similar steps to define the complexType Product, as shown in Listing 6 below.
Listing 6. The
complexType Product
<complexType name="Product">
<sequence>
<element name="_name" type="string"/>
<element name="_qty" type="int"/>
<element name="_price" type="float"/>
<element name="_dates" type="SupplierBSchema:ArrayOfDateInfo"/>
</sequence>
</complexType>
|
In .NET Framework 1.1, the XML Schema Definition tool (Xsd.exe) can generate runtime classes from XSD files. The Xsd.exe utility generates a set of C# class templates from XSD schemas. From the templates, you can provide the concrete implementation and produce the whole project. However, the Xsd.exe utility requires at least one top-level element defined in the schema, so you'll define one global element: productItem.
- In the Outline view, right-click on the
SupplierBSchema.xsd, and click Add Global Element. - Name the element
productItemand set the type toSupplierBSchema:Product. - Save the file.
Now, export the SupplierBSchema.xsd file to a directory and run the Xsd.exe command in that directory to generate the C# type classes: xsd.exe SupplierBSchema.xsd /classes.
A set of C# type classes are generated in SupplierBSchema.cs file. The DateInfo and Product classes are defined and qualified by the http://schema.b.supplier namespace. See the complete source of classes in the Download section. Since you have just designed the most important piece in this interoperability scenario, you can start building the .NET Web service implementation. In Build the agent process section, the SupplierASchema.xsd and SupplierBSchema.xsd will also be the starting point to build the BPEL process.
To start building the Supplier B .NET Web service, you can either build the .NET assembly using .NET Visual Studio, or simply write C# code in an .asmx file and wrap the types classes in the SupplierBSchema.cs file. In this section, you'll use the latter approach.
- Copy the
SupplierBSchema.csfile to theC:\Inetpub\wwwroot\SupplierB\directory and rename it toSupplierBQuoteService.asmx, and open it in an editor. - Comment out the following line:
[System.Xml.Serialization.XmlRootAttribute("productItem", Namespace="http://schema.b.supplier", IsNullable=false)]. - Add the constructors to the
ProductandDateInfoclasses to do the initialization. In .NET, a default constructor is also needed for a serialization class:public DateInfo() {} public DateInfo(DateTime date, string desc) { _date = date; _desc = desc; }
andpublic Product() {} public Product(string name, int qty, float price, DateInfo[] dates) { _name = name; _qty = qty; _price = price; _dates = dates; } -
Add a Web service class
SupplierBQuoteServiceand expose a methodgetQuoteunder namespace http://b.supplier/service as a document/literal Web service method. In .NET, document/literal is the default binding style:[WebService(Namespace="http://b.supplier/service")] public class SupplierBQuoteService { private static Hashtable fCurrentInventory = null; private static Hashtable getCurrentInventory() { return fCurrentInventory; } public SupplierBQuoteService() { fCurrentInventory = new Hashtable(); Product item1 = new Product("IBM ThinkPad T40", 200, 1399.99f, new DateInfo[] {new DateInfo(DateTime.Now, "Manufacture Date"), new DateInfo(DateTime.Now.AddYears(3), "Expiry Date")}); Product item2 = new Product("Dell Inspiron 4000", 200, 899.99f, new DateInfo[] {new DateInfo(DateTime.Now, "Manufacture Date"), new DateInfo(DateTime.Now.AddYears(5), "Expiry Date")}); Product item3 = new Product("Toshiba Satellite 2210X", 200, 599.99f, new DateInfo[] {new DateInfo(DateTime.Now, "Manufacture Date"), new DateInfo(DateTime.Now.AddYears(10), "Expiry Date")}); getCurrentInventory().Add("IBM ThinkPad T40", item1); getCurrentInventory().Add("Dell Inspiron 4000", item2); getCurrentInventory().Add("Toshiba Satellite 2210X", item3); } [WebMethod] public Product getQuote(string quoteItemName) { string item = quoteItemName; if (!getCurrentInventory().ContainsKey(item)) return new Product(item, 0, 0, new DateInfo[] {new DateInfo(DateTime.Now, "Manufacture Date"), new DateInfo(DateTime.Now, "Expiry Date")}); else return (Product)(getCurrentInventory()[item]); } }
The complete SupplierBQuoteService.asmx file is included in the Download section.
Now you can test the getQuote method of the Supplier B Web service from the browser.
- From a browser, enter the following URL: http://localhost/SupplierB/getQuoteServiceImpl.asmx.
- The only Web service method
getQuoteis returned. Click on thegetQuotemethod. - Enter IBM ThinkPad T40 in the item text box and click Invoke.
The product information for an IBM ThinkPad T40 is returned, as shown in Figure 7 below.
Figure 7. Test result for the
getQuote method of the .NET Web service
Notice how the Manufacture Date and the Expiry Date are displayed.
Enter the URL: http://localhost/SupplierB/SupplierBQuoteService.asmx?wsdl in the browser. The browser displays the WSDL document for the .NET Web service. Even though it's generated by the .NET WSDL engine, the data type schemas and namespace come directly from the SupplierBSchema.xsd that was designed in earlier steps. Import this WSDL into the quote.process package in the service project.
In this section, you'll define the agent Quote Process interface. The output data type of the process is the combined result of product quotes from Supplier A and Supplier B, as shown in the UML diagram in Figure 8.
Figure 8. The interface diagram for the
Quote Process
You need to define a complex type to compose the final quotes by importing the two Product complex types from SupplierASchema.xsd and SupplierBSchema.xsd.
First, create a QuoteProcess.xsd schema file and import both SupplierASchema.xsd and SupplierBSchema.xsd:
- Right-click on the
quote.processpackage and select New>XML Schema. - Enter the new schema name:
QuoteProcessSchema.xsdand click Finish. The schema editor opens. - In the Outline view, select the
QuoteProcessSchema.xsd. - In the Outline view, right-click on the
QuoteProcessSchema.xsdand click Add Import. - In the Outline view, expand the + sign and click the import icon.
- In the Import panel, browse to the
SupplierASchema.xsdfile and click Finish.
Repeat the Steps 4 to 6 and import the SupplierBSchema.xsd file.
Step 2. Create the complex type
Next, create the complex type ProductQuotes:
- In the Outline view, right-click on the
QuoteProcess.xsdand click Add Complex Type. - In the Complex Type window, name the new complex type
ProductQuotes. - In the Outline view, right-click the
ProductQuotesand click Add Content Model. - In the Outline view, right-click on the icon: and click Add Element.
- In the Element window, name the new element
SupplierAQuote. - Set the
SupplierAQuoteelement to the user-defined complex typeSupplierASchema:Product.
Repeat the last three steps to add another element SupplierBQuote with the user-defined complex type SupplierBSchema:Product.
In the Source view, the resulting ProductQuotes schema is shown in Listing 7.
Listing 7. The
ProductQuotes schema
<?xml version="1.0"?>
<schema targetNamespace="http://www.ibm.com"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:QuoteProcessSchema="http://www.ibm.com"
xmlns:SupplierASchema="http://schema.a.supplier" xmlns:SupplierBSchema=
"http://schema.b.supplier">
<import namespace="http://schema.b.supplier" schemaLocation=
"SupplierBSchema.xsd"/><import schemaLocation=
"SupplierASchema.xsd" namespace="http://schema.a.supplier"/>
<complexType name="ProductQuotes">
<sequence>
<element name="SupplierBQuote" type="SupplierBSchema:Product"/>
<element name="SupplierAQuote" type="SupplierASchema:Product"/>
</sequence>
</complexType>
</schema>
|
The BPEL process will be deployed and run as a Web service, so the next step is to create the process interface WSDL and import the QuoteProcessSchema.xsd.
Step 3. Create the process interface WSDL
Create the process interface WSDL.
- Create a blank WSDL in the package
quote.processand name itquoteProcessClient.wsdl. In the Wizard, set the target namespace tohttp://quote.process/quoteProcessClient/. - When the WSDL editor opens in the Outline view, right-click on the Imports and import the
QuoteProcessSchema.xsdfile.
Step 4. Define the process inbound and outbound messages
Next, define the process inbound and outbound messages.
- In the Outline view, right-click on the Messages and select Add Child>Message.
- Set the new message name to
getQuotesRequestand click OK. - In the Outline view, right-click on the
getQuotesRequestand select Add Child>Part. - Enter the part name
productName. The defaultxsd:stringis its type.
Repeat the above steps, create a new message getQuotesResponse, add a message part quotes, and set the type for quotes.
- In the Outline view, right-click on quotes and click
Set Type. - Specify the type to be
xsd1:ProductQuotesand click Finish, as shown in Figure 9 below.
Figure 9. Specify type for the quotes

Next, add Port Types and operation for the process and define the input and output.
- In the Outline view, right-click on
Port Typesand select Add Child>Port Type. - Add the new
Port TypenameQuotesProcessPortType. - Right-click on
QuotesProcessPortTypeand select Add Child>Operation. - Name the operation
getQuotes. - Right-click on the operation
getQuotes, select Add Child>input, and right-click on input. - Click
Set Messageand select the Select an existing message radio box. - Set the message for the input to be
tns:getQuotesRequestand click Finish.
Repeat the last three steps, add an output, set the message to be tns:getQuotesResponse, and save the quoteProcessClient.wsdl.
Step 6. Construct the business process flow
Now construct the business process flow. First, create an empty process definition file.
- Right-click on the
quote.processpackage in theQuoteProcessServiceand select New>Business Process. - Set business process name to be
QuotesProcessand click Next. - Select Sequence-based BPEL Process and click Finish.
Step 7. Create the partner link
A BPEL process invokes a Web service through a simple concept called <partnerLink>. A <partnerLink> is a BPEL abstraction of the operations defined in a Web service WSDL file. A partner link reads the portType of the external Web service defined in the WSDL and allows an invoke activity to be associated with an actual operation in the portType. Each partner link is associated with a logical role.
In this process, there are three partners: Agent, Supplier A, and Supplier B. The interface for each partner service is described in its WSDL file: quoteProcessClient.wsdl, SupplierAService.wsdl, and SupplierBService.wsdl, respectively.
- Double-click on the
quotesProcess.bpelfile to open it in the editor and delete the default partner link. - Drag and drop the
quoteProcessClient.wsdlinto the editor and accept the default. - In the editor, select the
QuotesProcessPortTypepartner link. In the details area, click the Implementation tab and click the role switch icon to promote theQuotesProcessPortTypeRoleas the process role name. - Similarly, drag and drop the
SupplierAService.wsdlandSupplierBService.wsdlfiles into the editor; accept the defaults.
Step 8. Define the process variables
Next, define the process variables. The process state information flow is managed by process variables. In WebSphere Studio Application Developer Integrated Edition V5.1.1, all of the process variables created are global. So, you can access the process variables from any code block. Each partner link has input and output variables, thus three pairs of variables need to be defined in the quotesProcess.
- In the BPEL editor, delete the default
InputVariable. - Click the plus icon and add a new variable named
Input. - In the details area, click the Message tab and browse to the
quoteProcessClient.wsdlfile and link it to thegetQuotesRequestmessage.
Repeat the same steps and create the following process variables. Link them to their respective messages, as shown in the following table:
| Variable | Message | WSDL |
| Output | getQuotesResponse | quoteProcessClient.wsdl |
| SupplierAQuoteReq | getQuoteRequest | SupplierAService.wsdl |
| SupplierAQuoteRes | getQuoteResponse | SupplierAService.wsdl |
| SupplierBQuoteReq | getQuoteSoapIn | SupplierBService.wsdl |
| SupplierBQuoteRes | getQuoteSoapOut | SupplierBService.wsdl |
Step 9. Implement the Receive and Reply activities
Next, implement the Receive and Reply activities. The Receive activity receives the Web service request, which initiates the quote process. The Reply activity sends the quotes response to the caller using a Web service call.
- Click the
Receiveactivity. - In the Details area, click the Implementation detail tab and set the
PartnerLinktoQuotesProcessPortType. Set the Operation togetQuotesand the Request toInput. - Similarly, for the
Replyactivity, set thePartnerLinktoQuotesProcessPortType. Set theOperationtogetQuotesand theResponsetoOutput.
Step 10. Create Flow and Sequence activities
A Flow activity is a group of activities that run in parallel, and a Sequence activity is a group of activities that run in sequence. In the agent quotes process, you want to invoke the Web services for Supplier A and Supplier B in parallel. So, create a Flow activity in which two sequence activities run in parallel, and each Sequence activity prepares the call, invokes the Web service of the supplier, and processesnot the result. In BPEL, the Invoke activity is used to execute the business logic implemented externally in a Web service.
- From the Palette, select a
Flowactivity and drop it into the editor between theReceiveandReplyactivities. - From the Palette, select a
Sequenceactivity and drop it into theFlowactivity. Name theSequenceactivityQuoteSupplierA. - Prepare the variables for invoking the Supplier A Web service. On the Palette, select an
Assignactivity and drop it inside theQuoteSupplierAsequence activity. Name itInit. - In the Implementation details area, copy the input part of the
getQuotesRequestmessage of theInputvariable to theproductNamepart of thegetQuoteRequestof theSupplierAQuoteReqvariable. - Drop an
Invokeactivity in theQuoteSupplierAsequence activity and below theInitactivity. Rename it togetQuote. - In the Implementation details area, set the
getQuoteactivity to the Partner LinkSupplierAQuotePortType, the Operation togetQuote, the Request message toSupplierAQuoteReqand the Response message toSupplierAQuoteRes.
Step 11. Create an Invoke activity
Next, create an Invoke activity for Supplier B. Here you'll use a Java snippet for the initialization of process variable getSupplierBQuoteReq for the invocation of Supplier B Web service. You can also use a Java snippet to implement simple business logic that does not involve the external Web services.
- Drop a
Sequenceactivity on the canvas inside theFlowactivity and name itQuoteSupplierB.QuoteSupplierBis a parallel sequence activity to theQuoteSupplierA. - Drop a Java snippet inside the
QuoteSupplierBsequence activity and rename itInit. - In the Implementation detail area for the Init Java snippet, copy and paste the following code:
supplier.b.service.GetQuoteElement newValue = new supplier.b.service.GetQuoteElement(); newValue.setQuoteItemName(getInput(true).getInput()); getSupplierBQuoteReq(true).setParameters(newValue);
- Drop an
Invokeactivity below theInitinQuoteSupplierB. Rename it togetQuote. - Set the
getQuoteactivity to Partner LinkSupplierBQuoteServiceSoap, Operation togetQuote, Request message toSupplierBQuoteReq, and Response message toSupplierBQuoteRes. - Now drop a Java snippet immediately after the
Flowactivity, but before theReplyactivity to prepare the output. Name itpreReply. - Copy and paste the following code snippet in the Implementation detail area for the
preReplyJava snippet:ProductQuotes newValue = new ProductQuotes(); newValue.setSupplierBQuote(getSupplierBQuoteRes(true). getParameters().getGetQuoteResult()); newValue.setSupplierAQuote(getSupplierAQuoteRes(true).getProduct()); getOutput(true).setOutput(newValue);
Now, you have the complete quote process defined as in Figure 10.
Figure 10. The agent Quotes process

Step 12. Generate the deploy code
Save the BPEL file and generate the deploy code.
- Right-click the
quotesProcess.bpelfile and select Enterprise Services>Generate deploy code. - In the Generate BPEL Deploy Code wizard, click the
quotesProcessPortTypeinterface. - Select SOAP/HTTP as the binding and select the IBM Web Service. Click OK.
The agent process is deployed as a SOAP/HTTP Web service. The WSDL and XSD files in the QuotesProcessServiceWeb project expose its interface for any clients to invoke the process.
Figure 11. WSDL and XSDs for the agent process

Generate a Java client proxy to interface with the agent process
In this section, you can use the process WSDL and XSD files in Figure 11 to generate a Java client proxy invoked by the buyer in your business scenario, as shown in Figure 1.
First, create a Java project QuoteProcessTestClient and copy the WSDL and the three XSD files from the QuoteProcessServiceWeb to the test client project.
Next, generate a JAX-RPC client proxy from the WSDL.
- Right-click
QuotesProcess_QuotesProcessPortType_HTTP.wsdlfile and select Enterprise Services>Generate Service Proxy. - In the wizard, select Java API for XML-based RPC (JAX-RPC) as the proxy type, click Next, and click Next again.
- Make sure that Java is selected as the
Clienttype andQuoteProcessTestClientis selected as the Client project. Click Next. - Accept all the default options in the following pages and click Finish.
The set of classes for JAX-RPC proxy are generated, as shown in Figure 12, except for the Buyer.java in the testclient package, which will be created in the next section.
Figure 12. JAX-RPC proxy for the agent process

To test the agent process, first create a test server and deploy the Supplier A Web service and the agent process on the server.
- Switch to the Server perspective. Create a new integration test server and configuration and name it
TestServer. - In the Servers window, right-click the
TestServer. Click Add and Remove Projects. - Add the two projects:
SupplierAServiceEARandQuoteProcessServiceEARon theTestServer. Click Finish. - Right-click the
TestServerand click Start.
Next, implement a main class representing the Buyer to call the JAX-RPC proxy to invoke the agent process.
- Create a new Java package. Right-click the
QuoteProcessTestClient, select New>Package, and name the new Java package astestclient. Click Finish. - Create a Buyer class. Right-click the
testclientpackage, select New>Class, and name the new class asBuyer. Click Finish. TheBuyerclass opens. - Copy and paste the code in Listing 8 onto the
Buyerclass editor and save the Java file.
Listing 8. The
Buyer class
package testclient;
import java.util.Calendar;
import java.util.Date;
import process.quote.QuotesProcessPortTypeProxy;
import supplier.b.schema.DateInfo;
import com.ibm.www.ProductQuotes;
public class Buyer {
public static void main(String[] args) {
String product = "IBM ThinkPad T40";
QuotesProcessPortTypeProxy aProxy = new QuotesProcessPortTypeProxy();
try {
ProductQuotes result = aProxy.getQuotes(product);
supplier.a.schema.Product quoteA = result.getSupplierAQuote();
supplier.b.schema.Product quoteB = result.getSupplierBQuote();
System.out.println("Quotes for product: " + product);
System.out.println("\tSupplier A: ");
System.out.println("\t\tQuantity: " + quoteA.get_qty());
System.out.println("\t\tPrice: " + quoteA.get_price());
System.out.println(
"\t\tIs refurbished: " + quoteA.is_refurbished());
System.out.println("\tSupplier B: ");
System.out.println("\t\tQuantity: " + quoteB.get_qty());
System.out.println("\t\tPrice: " + quoteB.get_price());
DateInfo[] dates = quoteB.get_dates().get_dateInfo();
for (int i = 0; i < dates.length; i++) {
Calendar cal = dates[i].get_date();
Date date = cal.getTime();
System.out.println("\t\t" + dates[i].get_desc() + ": " + date);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
|
Finally, the Buyer class can be run to get the product information from Supplier A and Supplier B for product IBM ThinkPad T40.
- Select the
Buyerclass in the Package Explorer. - From the top menu, select Run>Run As>Java Application. Upon successful completion, the result appears in the console, as shown in Figure 13 below.
Figure 13. The quote result

Compare Figure 13 with the unit test result in Figure 7, and observe how the array of the date information is represented in each case.
The xsd:dateTime is mapped to the java.util.Calendar in agent process and its client proxy class, but it's a lot more desirable to present the buyer with the concise java.util.Dates result instead of the java.util.Calendar, which includes lots of extra information. A simple conversion is needed if the client is expecting a java.util.Dates, as shown in Listing 8.
Here are some miscellaneous tips for developing the BPEL process for J2EE and .NET:
- The WebSphere Studio Application Developer Integration Edition Version 5.1.1 provides a powerful visual process debugger to step through the code at the BPEL process level.
- You need to intercept and investigate the SOAP messages going to and from the participating Web services, particularly the .NET Web services. There are numerous trace tools that you can use for that. WebSphere provides a utility class
com.ibm.ws.webservice.engine.utils.tcpmonto sniff the HTTP traffic between two points. Choose a tool that you are familiar with. - In many cases, it migh be necessary to turn on the server tracing to look for the root of exceptions.
What determines the success or failure of business process integration through BPEL is the inherent interoperability of the participating Web services. This tip emphasizes that message schemas should be designed carefully, and it demonstrates that both simple and complex Web services can be brought into a business process successfully, regardless of the platforms (J2EE versus .NET). The tip also shows that the WebSphere Studio Application Developer Integrated Edition V5.1.1 provides a powerful BPEL process development environment, convenient XML Schema, and WSDL design tools.
| Description | Name | Size | Download method |
|---|---|---|---|
| Code for sample BPEL business process (Purchasing) | ws-solution.zip | 153 KB | HTTP |
Information about download methods
- Read pertinent specifications on WSDL, SOAP, and other standards:
-
Check out other parts in this series:
- Part 1: WSDL, RPC/encoded style, and WS-I conformance
- Part 2: Managing collections, arrays or even primitive data types
- Part 3: Handling namespace
- The article Understanding the WS-I Test Tools by Peter Brittenham provides an overview of the architecture and functions of WS-I Test Tools.
- See the tutorial Using the WS-I Test Tools with Java technology by Peter Brittenham for step-by-step instructions in using the Java versions of the WS-I test tools.
- Want more? The developerWorks Web Services and SOA zone hosts hundreds of informative articles and introductory, intermediate, and advanced tutorials on how to develop Web services applications.
- Access Web services knowledge, tools, and skills with Speed-start Web services,
which offers the latest Java-based software development tools and middleware
from IBM (trial editions), plus online tutorials and articles, and an online
technical forum.
Wangming Ye is an IBM Certified Enterprise Developer and a Sun Certified Enterprise Architect for J2EE Technology. He began as a developer in the DCE/DFS department at Transarc Corporation (later merged into IBM), and then as one of the main developers of the WebSphere Content Distribution Framework in the WebSphere Edge Server group. He currently provides technical enablement for WebSphere business partners in the WebSphere Competency Center in the IBM Business Partner Technical Enablement organization. You can reach Wangming at yme@us.ibm.com.
Comments (Undergoing maintenance)





