When it comes to connecting applications together that were written for different vendors' platforms, potentially in different programming languages and on different operating systems, web services technology promises to be of great help. Generally speaking, "web services" are pieces of software that can be accessed by sending them messages formatted in XML over a network. XML is not tied to a particular programming language or operating system, thus it can be used as a protocol for information exchange between heterogeneous systems. The Web Services Definition Language (WSDL) can be used to describe the interface a web service offers, again based on XML.
Once the basic infrastructure is in place, new opportunities arise for connecting different platforms and environments in order to implement business processes. However, since the technology and its underlying specifications and standards are relatively new, care must be taken to ensure that different vendor platforms communicate properly.
The application that was chosen for this demonstration implements a purchase order scenario. In this scenario, a potential buyer (that is, the "Customer") retrieves a catalog of products offered by a particular buyer and selects which products will be purchased in which quantities. When a purchase is complete, an order is sent to the supplier with the types and amounts of products that the buyer requested.
The supplier will then check if the requested products are available to be shipped to the customer. This is achieved by querying the warehouse. If there is insufficient stock to fulfill the order, the order's status is set appropriately and an error is returned. If the available stock is sufficient, the supplier will then check the customer's credit to execute the purchase. Each buyer is associated with a particular bank that can provide information about the account status, as well as deduct the required funds from that account.
Finally, assuming that the bank account status is good, the supplier sends a request to the warehouse to ship the order. The customer, in the meantime, can check on the status of a particular order with the supplier, or retrieve an invoice for a confirmed shipment.
The participating vendors in the application to date are IBM, Amberpoint, IONA, and webMethods. This list may change as time evolves. The configuration files and WSDL definitions are kept on a site run by xmethods.net at http://www.xmethods.net/wsid/online.
In order to allow testing of various constellations, roles are defined that can be configured to run on different machines, provided by the different vendors that participate in the demo. Each of the participants in the application scenario described above, namely Customer, Supplier, Warehouse and Bank, is implemented as a web service. These services can run on the same machine or on different machines, with different implementations, showing the value of web services technology in a heterogeneous environment.
Figure 1 shows the roles that are involved in the application and the respective operations that they support.
Figure 1. Roles and operations

(Figure 1 is Copyright © XMethods and has been used with permission).
Which implementation of a role is used when running the application is determined by a set of XML files that describe combinations of, for example, a particular warehouse service with a particular supplier. This way, any permutation of role implementations by the different vendors can be configured. The XML configuration files are kept in a central place and, typically, cannot be changed. A future enhancement to the application may allow changes to be made locally.
As mentioned earlier, each of the roles in the purchase scenario is implemented as a web service. This means it is represented by a service interface defined in WSDL. Each service encapsulates specific business functionality that can be invoked through a common mechanism, namely SOAP over HTTP.
One goal of the application is to allow the use of different service implementations, to test and demonstrate interoperability between different web services environments. This means that each of the participating vendors provides an implementation for each service. Which service is actually used when you run the application is decided at runtime. All of the service implementations support the same abstract interface, so that clients can invoke each of them in the exact same way. As a side effect of this, you can see how to build a client to a wb service without hardcoding the location of that service.
WSDL supports the separation of interface and implementation by providing different elements that contain this information. The interface is described in the <portType> element, which defines the operations that the service offers. For example, the test application has a Warehouse service with three operations, namely checkAvailability, shipRequest, and shipConfirm. The WSDL document for the Warehouse service defines these operations in a portType, as well as the data types that are used by these operations in an XML Schema. Listing 1 shows the complete WSDL definition of the Warehouse service.
Listing 1. WSDL definition of the Warehouse service
<?xml version="1.0" encoding="UTF-8"?> <definitions name="IWarehouse" targetNamespace="http://www.xmethods.net/ws-demo/" xmlns:tns="http://www.xmethods.net/ws-demo/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:xsd=http://www.w3.org/2001/XMLSchema xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"> <types> <schema xmlns=http://www.w3.org/2001/XMLSchema targetNamespace="http://www.xmethods.net/ws-demo/" xmlns:tns="http://www.xmethods.net/ws-demo/"> <complexType name="PO"> <sequence> <element name="header" nillable="true" type="tns:POHeader"/> <element name="lines" nillable="true" type="tns:ArrayOfPOLine"/> </sequence> </complexType> <complexType name="POHeader"> <sequence> <element name="PONumber" nillable="false" type="string"/> <element name="timestamp" nillable="false" type="dateTime"/> <element name="supplierID" nillable="false" type="string"/> <element name="customerID" nillable="false" type="string"/> <element name="notes" nillable="true" type="string"/> <element name="numberOfLines" nillable="false" type="int"/> <element name="subtotal" nillable="false" type="float"/> <element name="shipToLine1" nillable="false" type="string"/> <element name="shipToLine2" nillable="true" type="string"/> <element name="shipToLine3" nillable="true" type="string"/> <element name="shipToCity" nillable="false" type="string"/> <element name="shipToState" nillable="false" type="string"/> <element name="shipToPostalCode" nillable="false" type="string"/> <element name="shipToCountry" nillable="true" type="string"/> </sequence> </complexType> <complexType name="POLine"> <sequence> <element name="lineNumber" nillable="false" type="int"/> <element name="itemNumber" nillable="false" type="string"/> <element name="itemName" nillable="false" type="string"/> <element name="quantity" nillable="false" type="int"/> <element name="unitOfMeasure" nillable="false" type="string"/> <element name="unitPrice" nillable="false" type="float"/> <element name="lineTotal" nillable="false" type="float"/> </sequence> </complexType> <complexType name="ArrayOfPOLine"> <complexContent> <restriction base="soapenc:Array"> <attribute ref="soapenc:arrayType" wsdl:arrayType="tns:POLine[]"/> </restriction> </complexContent> </complexType> </schema> </types> <message name="checkAvailability0SoapIn"> <part name="po" type="tns:PO"/> </message> <message name="checkAvailability0SoapOut"> <part name="Result" type="xsd:boolean"/> </message> <message name="shipRequest1SoapIn"> <part name="po" type="tns:PO"/> <part name="confirmURL" type="xsd:string"/> </message> <message name="shipRequest1SoapOut"/> <portType name="IWarehouseSoap"> <operation name="checkAvailability" parameterOrder="po"> <input name="checkAvailability0SoapIn" message="tns:checkAvailability0SoapIn"/> <output name="checkAvailability0SoapOut" message="tns:checkAvailability0SoapOut"/> </operation> <operation name="shipRequest" parameterOrder="po confirmURL"> <input name="shipRequest1SoapIn" message="tns:shipRequest1SoapIn"/> <output name="shipRequest1SoapOut" message="tns:shipRequest1SoapOut"/> </operation> </portType> <binding name="IWarehouseSoap" type="tns:IWarehouseSoap"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="checkAvailability"> <soap:operation soapAction="" style="rpc"/> <input name="checkAvailability0SoapIn"> <soap:body use="encoded" namespace="http://www.xmethods.net/ws-demo/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output name="checkAvailability0SoapOut"> <soap:body use="encoded" namespace=http://www.xmethods.net/ws-demo/ encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> <operation name="shipRequest"> <soap:operation soapAction="" style="rpc"/> <input name="shipRequest1SoapIn"> <soap:body use="encoded" namespace="http://www.xmethods.net/ws-demo/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </input> <output name="shipRequest1SoapOut"> <soap:body use="encoded" namespace="http://www.xmethods.net/ws-demo/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/> </output> </operation> </binding> </definitions> |
Note how the used data types are declared in an XML Schema within the <types> element. Again, this provides a way to define data that is independent of any programming language or platform. Each programming language has its own way of mapping these definitions into its particular format.
The endpoint definition, that is, the address at which a particular service can be accessed, is stored in the <service> element in WSDL, and within this element, specifically, in the <port> element.
Different web services environments provide different kinds of APIs to invoke a service. In this case, I take advantage of the Apache Axis open source implementation, which supports the "Java API for XML based RPC," or JAX-RPC. This API provides a mechanism by which a client can dynamically select the address of a web service and then send requests to it. The example implementation uses this mechanism to invoke the different service implementations by the various vendors -- including the one that is locally installed on the WebSphere Application Server.
JAX-RPC allows the wrapping of a web service invocation into a so-called "proxy" or "stub" class (see Figure 2). This class exposes an interface that maps the abstract service interface, and thus hides the details of a web service invocation from the client. This approach is also commonly used in traditional J2EE applications, where remote Enterprise JavaBeans are accessed through a client proxy that offers the EJB's methods locally to its clients. Our application includes proxies for all of the involved services. They can be used regardless of which service implementation is actually called at runtime.
Figure 2. Service proxy and service implementation

Service/endpoint configuration
The application can be configured to select different implementations of the required services at runtime. Which implementation is used is defined through a number of XML configuration files that specify the dependencies and addresses of these services. For example, the mapping of a warehouse to a particular supplier is defined in a file called warehousemaps.xml (see Listing 2).
Listing 2. Example warehousemaps.xml file
<?xml version="1.0" encoding="UTF-8"?> <warehouseMaps> <map> <supplier>e2a-supplier</supplier> <warehouse>e2a-warehouse</warehouse> </map> <map> <supplier>ibm-supplier</supplier> <warehouse>ibm-warehouse</warehouse> </map> <map> <supplier>wm-supplier</supplier> <warehouse>wm-warehouse</warehouse> </map> </warehouseMaps> |
In this example, the IBM provided supplier will use the IBM warehouse implementation. Similarly, the mapping of a Customer to a specific Bank implementation is defined in a file called creditmaps.xml.
The concrete endpoints of each service implementation are defined in the roles.xml file. It assigns a URL to each endpoint id (which is used in the mapping files mentioned above), which is then used by the code at runtime to send requests to the appropriate service implementation.Listing 3 shows some sample entries in the roles.xml file that describe the IBM supplied service endpoints.
Listing 3. Example roles.xml file
<role participant="ibm"> <type>supplier</type> <id>ibm-supplier</id> <endpoint>http://dwdemos.alphaworks.ibm.com/wsid/services/supplier</endpoint> </role> <role participant="ibm"> <type>customer</type> <id>ibm-customer</id> </role> <role participant="ibm"> <type>bank</type><id>ibm-bank</id> <endpoint>http://dwdemos.alphaworks.ibm.com/wsid/services/bank</endpoint> </role> <role participant="ibm"> <type>warehouse</type> <id>ibm-warehouse</id> <endpoint>http://dwdemos.alphaworks.ibm.com/wsid/services/warehouse</endpoint> </role> |
To run the actual application, you need to start with an entry page that implements the Customer role described above. To access the IBM provided Customer, go to the URL: http://www-106.ibm.com/developerworks/demos/wsid/index.html and select the hyperlink to the Customer page. This implementation of the Customer runs on an IBM WebSphere Application Server, version 4. Figure 3 shows the Customer page.
Figure 3. WSID Customer page
| XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width. |
From this initial screen, you can select which customer and supplier you want to test. The IDs shown in Figure 3 map the ones defined in the roles.xml file that I mentioned earlier. The warehouse and bank implementations can be derived from the supplier definition, and they are defined in the warehousemaps.xml and creditmaps.xml files, respectively. Note that you can also specify "local" for both customer and supplier. What this means is specific to each vendors' implementation -- in this case, it means that you are using the IBM provided supplier. The second article in this series will show you how to run the application on your own local WebSphere installation. In that case, specifying "local" for the supplier will direct you to the locally installed supplier service.
After you have selected the customer and supplier ID that you want to use, you can fetch the catalog for the selected supplier by clicking the "Get Catalog" button. The result of this is shown in Figure 4.
Figure 4. Example supplier catalog
| XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width. |
Now enter information about which products in which quantities you want to purchase and click on the "Send PO" button. This will cause the supplier web service to check with the warehouse and the bank services, and then confirm or reject the order. If the order is confirmed, a summary page is shown, similar to Figure 5.
Figure 5. Example purchase order
| XML error: The image is not displayed because the width is greater than the maximum of 580 pixels. Please decrease the image width. |
Use the "Get Invoice" button to view the invoice that was generated for your particular order, use the "Get Status" button to check if the order has been shipped yet (depending on the service implementation, there may be a delay from when an order is confirmed to when it gets shipped).
Feel free to run the application several times, with different customer/supplier combinations. The result should always be the same, regardless of which vendor's implementation you choose. You can also list all of your invoices, the defined endpoints and role mappings by clicking on the respective buttons on the Customer page.
The application described here was designed to show and verify a certain level of interoperability between web services implementations of various vendors. The Web Services Interoperability organization (WS-I) was initiated to document criteria and test tools that ensure interoperability of web services across vendors. One of the concrete work products of WS-I is the Basic Profile. A basic profile narrows the scope of certain specifications to a reasonable set of rules and guidelines that are best suited to help interoperability. A draft of the first basic profile was recently published. One future work item of the purchase order application is to follow exactly the rules laid out in this profile. However, it may still go beyond the defined rules, to show that a higher degree of interoperability can be accomplished. Most significantly, the WS-I basic profile mandates the use of literal encoding of SOAP request and response messages. The application shown here also uses SOAP encoding. Given this, you can learn many things about the boundaries of how well the different implementations work together. Moreover, there are a number of newer standards and specifications in the web services world that are currently evolving, like the WS-Coordination and WS-Transaction specifications. Future versions of this demonstration should certainly involve these newer technologies when they become available in the various vendors' offerings.
Web services technology can help achieve higher degrees of automation and integration between heterogeneous platforms and applications. The application shown in this article, while only a demonstration, shows that different platforms and programming languages can be integrated in real-life scenarios using web services technology. An abstract service interface, as described in WSDL, is used to create a layer of abstraction that allows a client written in, say, Java programming language, to access a service implemented in, say, C++.
To ensure that the web services offerings created by different vendors work well together, rules and guidelines must be documented. This will make it easier to implement new business processes without having to create additional layers of integration software. The Web Services Interoperability organization plays a crucial role in this respect, and the demo application shown here can act as a basis for including new technologies and specifications as they evolve into products over time.
- See the Web Services Interoperability demo and download the code.
- Check out the second part in web services interoperability, Part 2
- See the WSID XMethods Homepage.
- Learn more about Web Services Interoperability.
- Check out the Apache Axis package.
- Read an introduction to JAX-RPC, including the specification itself.
- View this listing of all current open standards and specifications that define the web services family of protocols.
André Tost works as a Solution Architect in the WebSphere Business Development group, where he helps IBM's Strategic Alliance partners integrate their applications with WebSphere. His special focus is on web services technology throughout the WebSphere product family. Before his current assignment, he spent ten years in various development and architecture roles in IBM software development, most recently for the WebSphere Business Components product. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.




