Lessons from the Front Line - Building Interoperable Web Services

Keywords: XML, Java, J2EE, Interoperability

Sameer Tyagi
Senior Java Architect
Sun Microsystems, Inc.
Massachusetts
Massachusetts
United States of America

Biography

Sameer Tyagi works as a Senior Java architect with Sun Microsystems. He remains focused on architecture, design, and implementation of large-scale enterprise applications with Java technology. His publications include industry periodicals and books on Java, Web Services and J2EE technologies


Abstract


The ability to interoperate across disparate vendors, platforms and infrastructure stacks is inherently important to the adoption of Web Services technology. For most organizations, cross platform interoperability and the move to a loosely coupled, Service Oriented Architecture (SOA) is usually the main rationale for adoption of the underlying Web Service technologies. In this paper we will discuss some of the issues and stumbling blocks towards interoperability. We will also demonstrate with an example, how an application developed in Java and deployed in a J2EE 1.4 compatible container can interoperate and be consumed from a different client, developed in C# on the .NET platform.


Table of Contents


1. Interoperability
     1.1 Standardize On Standards
     1.2 Select your vendor carefully
     1.3 Lookout for proprietary extensions
     1.4 Test interoperability
     1.5 Analyze disparate data models
     1.6 Analyze data elements being passed
     1.7 Avoid Serializers and Deserializers
     1.8 Consider the transport issues
          1.8.1 HTTP headers:
          1.8.2 HTTP methods
          1.8.3 HTTP redirection
          1.8.4 HTTP cookies
          1.8.5 HTTP Security
     1.9 Carefully design the service description
     1.10 Portability of client code between vendor implementations
2. WS-I
3. WS-I Basic Profile and Java
4. Interoperability and J2EE
5. Example
Bibliography

1. Interoperability

There are many definitions and descriptions for interoperability. For example

Interoperability, in the context of Web Services can be summarized to mean that the functional characteristics of the service should remain immutable across differing application platforms, programming languages, hardware, operating systems and application data models. Web services by definition should be interoperable and the service consumer should not be tied to the service implementation. Interoperability is key to a successful realization of a SOA for large enterprises that have heterogeneous IT environments, software infrastructures i.e., different operating systems or middleware and cross-enterprise interactions with business partners.

However there are bound to be issues when services use disparate SOAP toolkits for generation and manipulation of the underlying SOAP message, disparate programming languages and dissimilar, often proprietary hardware-software stacks. It is one thing to assume things work seamlessly because the vendors say that they implement the standard specifications, it is another thing to find out midway in development that the service needs to be re-factored or code fixed to address specific interoperability issues that arise because of assorted vendor products. If architects and developers keep some of the subsequent guidelines in mind, they will find that many of the common causes behind those nasty interoperability issues can be tackled transparently, allowing them to focus more on the actual implementation logic and less on the troubleshooting details.

1.1 Standardize On Standards

A common component of virtually all strategies for improving interoperability is the requirement to conform to some set of standards. While many of the advanced components for web services, such as transactions, workflow and security, are still nascent, there appears to be an emerging consensus around the basic building blocks like SOAP, WSDL and UDDI. Rather than specifying how to build systems, standards compliance is now used as a means to leverage disparate implementations and a way to ensure interoperability. However the real issue is that there are no industry-standard testing tools that can identify issues and vendor compliance to Web services specifications. The workaround is to use the profiles described by Web Services Interoperability or WS-I [1] organization described later in this paper.

1.2 Select your vendor carefully

Nothing will affect the development cycle more than the choice of the vendor products. Look out for the implementations conformance history with the specifications. It is fairly common for vendors to conform to a subset of the full SOAP or other XML standards. Interoperability is also affected by implementations depending on the optional aspects of the SOAP specifications. For example sending type information for encoded parameters is optional, however if an implementation assumes that this will be present in messages it receives, it may not interoperate with others that do not send this information. Another example is the use of the SOAPAction header. There is no differentiation between a SOAPAction values of quotes ( "" ) and null in the specifications but some implementations support both whereas others do note quote this value at all for non-null SOAPAction headers.

The application's interoperability will also be affected by how the vendors interpret ambiguous definitions of the SOAP specification and this may vary from vendor to vendor. For example it is not clear how a service should represent an RPC response with a void return and no out parameters. It could be an empty SOAP envelope, an empty SOAP response element, or even an HTTP 204 (No response) code. Another example is that a null value can be represented either by not including that XML element or by an element with the xsi:nil="true". In short choose the vendors and toolkits judiciously. Verify that the standards compliance with the vendors and beware of the word "partial" in the data sheets!

1.3 Lookout for proprietary extensions

Many vendors provide value added features in their products that are labeled as market differentiators. However many, if not all of these features rely on applications using vendor specific API or vendor specific extensions to the SOAP specifications. Architects should avoid building dependencies in the application that utilize any vendor specific extension to the specifications since proprietary mechanisms will only work with that specific vendor product. For example, some J2EE application server vendors provide developers the facility to build conversational Web services; but in reality these services rely on the clients' ability to pass specific or custom SOAP headers and servers' ability to maintain state on the web tier by interpreting those headers. Such services may not interoperate with anything other than the vendors container and may require that clients use the vendors API which may not be available for all platforms.

1.4 Test interoperability

Never assume things will work like they should. It is essential to test interoperability of the service implementation across multiple consumers especially if the service consumers are outside the boundaries of the organization. In real world projects, early risk mitigation in the development cycle is crucial to success. It is therefore important that the test plans should include test cases that address systemic qualities in addition to the functional requirements. For example if a web service is developed to process purchase orders sent by business partners, not only should the test cases validate successful acceptance and business processing of the order, they should include cases where the order is by clients on different development platforms. To help developers some public interoperability tests are also available E.g from the WS-I and White Mesa.

1.5 Analyze disparate data models

When a service is used for application integration between applications that have disparate data models there may be a need to resolve the models by creating an intermediate model. E.g. flutebank.com integrates with unbrokerage.com to provide customers the ability to view their accounts simultaneously online when in any of the portals. The data model for an account as represented in flutebank.com may be quite different form an account in unbrokerage.com. In this scenario, the architects will need to reconcile the models by creating an XML Schema that is acceptable to both parties.

1.6 Analyze data elements being passed

The data type information passed as arguments and return types from the service invocation can impact interoperability. For example in a J2EE 1.4 Web Service there will be two broad categories of data types that are passed between the service and its clients.

1.7 Avoid Serializers and Deserializers

Using custom data types that force the use of custom serializers and deserializers can potentially cause interoperability issues with other implementations. For example, a java.util.List is not defined as a standard data type by the JAX-RPC specifications and may be represented differently by vendor A and B implementation. If Vendor A's client runtime is used to invoke a service deployed in vendor Vendor B's runtime there may be serialization errors because each implementation uses its own XML mapping of that data type. If the mapping is not available, the corresponding serializers and deserializers will need to be written. The good news is that though the early testing efforts of the SOAP-Builders community [9] most of the interoperability problems with the Collection classes in particular have already been ironed out.

Customization of data, protocols and encoding schemes: Architects should be very wary of any code that customizes the messages on the wire. A good example is introduction of compression or security mechanisms in the application layer. The endpoint of such a service cannot be invoked by clients that are not aware of these compression and security algorithms that are used and understood by the service. From a service perspective, there is no standard way to communicate this information (e.g. it cannot be specified in WSDL).

1.8 Consider the transport issues

The underlying transport is the core of any Web Service and while SOAP itself does not depend on the underlying transport, the interoperability of the Web Service does. The HTTP protocol [5] is emerging by far the most popular transport mechanism for SOAP messages. Support for mail based protocols like POP[6],SMTP [7] also seems to be gaining ground with SOAP 1.2. This means that HTTP interoperability must exist between SOAP stacks on which the web service is deployed and consumes. Some common issues at the transport layer are

1.8.1 HTTP headers:

SOAP 1.1 mandates the use of SOAPAction header to the HTTP request. It can be assigned with different values an URL ( SOAPAction="http://foobar.com"), a quoted 'empty' string or can be null. It causes interoperability issues, if a server requires null-value for SOAPAction , and a client cannot send a null value instead it sends a quoted empty string. The workaround is to ensure SOAPAction value is same as the value exposed by the Service provider WSDL and to use a standards compliant toolkit.

1.8.2 HTTP methods

SOAP1.1 allows two methods for HTTP, the HTTP POST method and the HTTP Extension Framework's M-POST method respectively. Using different methods between the communication points can cause issues. The workaround is to only use and rely on the HTTP POST method.

1.8.3 HTTP redirection

With the deployment of proxy based web services management tools, agent based identity management solutions and multiple SOAP nodes HTTP redirection is also a common cause of interoperability. Analyze if the server uses the original HTTP method or redirect using GET and how clients should interpreting HTTP status codes. For example a 4xx series of status codes indicates failure. The workaround is to standardize on using the "307 Temporary Redirect" as per RFC-2616 [7]

1.8.4 HTTP cookies

HTTP cookies are a common mechanism for maintaining state in web based application however cookies do not have well-defined semantics for Web services. They are external to the SOAP Envelope and are not accommodated by either SOAP 1.1 or WSDL 1.1. However some situations may require cookies e.g. load balancing between servers. This can cause issues if the service consumer does not support cookies. The workaround is to design stateless services that do not explicitly rely on service consumers to support cookies. It is worth noting that cookies based state maintenance is supported by JAX-RPC [8].

1.8.5 HTTP Security

Transport layer Security is commonly used to secure the Web service from a message integrity and confidentiality perspective. Even though the client can interpret this from the https:// URL in the WSDL, there is no way for the client to know that the server uses SSL 1.0 or SSL 2.0. There is also no way for the client to know that the web service uses SSL with or without mutual authentication. Web services that need to use transport layer security, should use SSL 1.0 and negotiate certificate requirements out of band with their clients.

1.9 Carefully design the service description

WSDL allows the use of extensions however this requires out-of-band negotiation and development tools consuming WSDL may not understand extensions. The suggested workaround is to avoid the use of WSDL extensions since most use cases can be typically realized without extensions. WSDL allows associating a namespace with a document location using an import statement (modeled after xsd:import where schemaLocation is optional), however it is not completely clear about the significance of the location attribute in wsdl:import . Is it required? What is the content? To avoid interoperability issues, specify a non empty location in wsdl:import . WSDL also allows multiple ports to exist for a single endpoint. However in reality, input messages destined for different wsdl:ports on the same network endpoint may be indistinguishable on the wire and the endpoint may not be able to determine which wsdl:port is being invoked. The workaround is to ensure that a single wsdl:port exists per location during WSDL design. WSDL allows operation name overloading in wsdl:PortType . This can cause tools that generate language specific bindings for the WSDL (e.g. wscompile which generates Java stubs from WSDL) to fail. The recommended workaround is to ensure that distinct names exist for operations in wsdl:portType.

1.10 Portability of client code between vendor implementations

J2EE developers would be familiar with the concept of writing an EJB and creating deploying it transparently in a J2EE server The EJB client can be written with complete transparency and used in any J2SE environment by simply altering configuration properties. This portability of client code does not translate identically in the Web Services environment, especially when using custom data types. For example a JAX-RPC client is not guaranteed to be portable if it uses anything beyond the simple data types. This is tied to the way the serializers and deserializers are written as discussed earlier as well as the non-portability of client side stubs. In simple words, if architects choose vendor A's implementation of JAX-RPC and write client code that uses serializers and deserializers to invoke the service, they should not expect to simply take the client code and use it directly in vendor B's runtime. The serializers and deserializers will need to be ported and vendor B's deployment tools will need to be used to regenerate the stub code. Applications should be designed to abstract away the specificity, minimizing the changes needed.

2. WS-I

The Web Services Interoperability Organization (WS-I) is an industry initiative for Web services that is focused on promoting Web service interoperability across platforms, applications, and programming languages. To quote from the charter "The WS-I organization is dedicated to meeting the needs of Web services developers, so as to enable them to develop and deploy interoperable Web services on the platform and development language of their choosing."

Towards this purpose WS-I maintains a notion of profiles. A profile in WS-I represent a set of industry wide specifications that are grouped together with guidelines for use, or exclusion, of any optional or loosely specified features of those specifications. Contrary to popular belief WS-I is not a standards organization like W3C in that it does not release new technology specifications. It is also not source of WS-Reliability, WS-Security and other WS-* specifications. These have typically been proprietary specifications from single or small groups of companies and a few have been submitted to recognized standards bodies like OASIS etc.

Till date, WS-I has created the Basic Profile 1.0 that profiles the SOAP, WSDL and UDDI specifications as well; the Attachment profile 1.0 that profiles the use of attachments in SOAP messages and the Security profile 1.0 that profiles the use of WS-Security, XML Digital Signatures and XML Encryption for Web services.

Other than the profile, there are three main artifacts that have come out of WS-I. These are the implementation scenarios, testing tools and sample applications respectively. Implementation scenarios outline how Web Services can be used at a high level based on customer requirements and identify the basic interoperability requirements for such interactions.

Interoperability-fig0.png

Figure 1: WS-I Monitor and Analyzer tools

The WS-I provides the Analyzer and Monitor testing tools (Figure 1) in both Java and C# implementations that can be used to log and analyze the service conformance to the WS-I Basic Profile. The Monitor is a message capture and logging tool logs the messages that were sent to and from a Web service.

The Analyzer is used to validate that the Web Service interactions, the WSDL description and UDDI entries conform to the Basic Profile. The output from Analyzer is a report (See Figure 2) that shows whether or not a Web service meets the interoperability guidelines of the WS-I Basic Profile. The report details the specific deviations and failures and developers can determine which requirements were not met. With these tools, developers can ensure that the web services they are developing do not violate any of the interoperability requirements (roughly 156 in number) outlined in the Basic Profile.

WS-I also provides a sample supply chain application that demonstrates how WS-I Basic Profile 1.0 conformant web services might be designed, implemented and deployed.

Interoperability-fig1.png

WS-I Analyzer tool report produced on the messages from the C# client and the WSDL on the Java WSDP. The report shows the conformance of the service to the specific WS-I recommendations.

Figure 2: WS-I Analyzer tool report

3. WS-I Basic Profile and Java

Support for WS-I Basic Profile 1.0 is available as part of JAX-RPC. JAX-RPC 1.1, which is also a part of J2EE 1.4 clearly specifies the support for the different interoperability requirements specified in the Basic Profile. This is important because this means is that not only must J2EE 1.4 containers provide support for this API in the client, web and application server containers but that they must also satisfy all the interoperability requirements from WS-I Basic Profile outlined in JAX-RPC. Developers can now concentrate more on the application and the business problem and less time worrying about the specifics of “on the wire interoperability”.

The Java Web Services Developer Pack (Java WSDP) is an integrated toolkit that allows Java developers to develop, test, and deploy web services quickly and easily. It has an active developer community[17].The Java WSDP which contains the standard implementation (SI) for many of the web services API produced by the JCP also supports the WS-I profiles. The JAX-RPC tools packaged with it generate and consume WS-I compliant WSDL documents and also provide full support for the document/literal and rpc/literal formats. The support includes the validation of the Java code or WSDL using the WS-I testing tools as well as alignment with the Attachment and Security Profiles respectively. The WS-I Attachment Profile defines the interoperability requirements in addition to the WS-I Basic Profile 1.1 and adds support for building interoperable Web services using attachments with SOAP messages. The Security Profile defines the requirements and scenarios for promoting interoperability of secure Web services by addresses digital signatures, encryption and attachment security.

4. Interoperability and J2EE

There are three specifications that tightly integrate JAX-RPC with J2EE. These specifications are J2EE 1.4 (JSR 151), EJB 2.1 (JSR 153) and Web services for J2EE (JSR 109). J2EE 1.4 includes JAX-RPC as a required API, what this means is that all J2EE 1.4 application servers will support JAX-RPC. The EJB 2.1 specifications which are a part of the J2EE 1.4, also define how an EJB can be exposed as a web service and how EJBs can potentially act as web service consumers. The “Implementing Enterprise Web Services” specification lays out the deployment and service requirements for portability of client and server code across containers.

EJB 2.1 allows a stateless session bean to be exposed as a web service by defining a new interface type in addition to the home, local and remote interfaces. The new interface is called an endpoint interface and is essentially the JAX-RPC service definition. EJB developers provide the service definition as the EJB class. The container generates the implementation of the endpoint interface much like it generates the implementation of the EJBObject during deployment. The container exposes the EJB through its service endpoint interface and a WSDL document that clients can use. Once deployed clients use it like any other JAX-RPC service, i.e. clients access this stateless session bean using the JAX-RPC client APIs over an HTTP transport just as the example covered earlier. EJBs can lookup other web services with JNDI using a logical name called a service reference, which maps to a service-ref element in the deployment descriptor, obtains a stub instance for a web service endpoint, and then invoke a method on that endpoint. In this way EJB’s can be consumed by disparate client technologies as well as provide a client view to other Web Services on different platforms (Figure 3).

Interoperability-fig2.png

Figure 3: EJB can be consumed by different clients as well as lookup other web services.

5. Example

The example [18] consists of a document based web service that processes purchase orders where all exchanges with the web service are in the form of XML documents. The sequence diagram is shown in Figure 4. It is important to note that the notion of document based web services is orthogonal to the formatting (e.g. document/rpc ) defined in WSDL [10].

Interoperability-fig3.png

Figure 4: Sequence diagram for interoperability example

The development typically starts with defining the WSDL interface. The WSDL is usually seperated into the abstract and concrete [11] as shown in Example 1 and 2.


<definitions xmlns:tns="urn:AbstractPOService" 
             xmlns="http://schemas.xmlsoap.org/wsdl/"  
             xmlns:ns1="urn:PurchaseOrderDocument"  
             xmlns:ns2="urn:Status" 
             xmlns:ns3="urn:POProcessingFault"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  
             targetNamespace="urn:AbstractPOService"  
             name="AbstractPOService">
 <types>
  <schema xmlns="http://www.w3.org/2001/XMLSchema" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" 
          targetNamespace="urn:AbstractPOService">
  <import schemaLocation="PurchaseOrder.xsd" 
          namespace="urn:PurchaseOrderDocument" id="ns1"/>
  <import schemaLocation="PurchaseOrderStatus.xsd" 
          namespace="urn:Status" id="ns2"/>
  <import schemaLocation="POProcessingProblem.xsd" 
          namespace="urn:POProcessingFault" id="ns3"/>
  </schema>
 </types>
<message name="IPurchaseOrder_acceptPO">
 <part name="parameters" element="ns1:PurchaseOrderDocument"/>
</message>
<message name="IPurchaseOrder_acceptPOResponse">
 <part name="result" element="ns2:Status"/>
</message>
<message name="POProcessingProblem">
  <part name="POProcessingProblem" element="ns3:POProcessingFault"/>
</message>
<portType name="IPurchaseOrder">
   <operation name="acceptPO">
	<input message="tns:IPurchaseOrder_acceptPO"/>
     <output message="tns:IPurchaseOrder_acceptPOResponse"/>
	<fault name="POProcessingProblem"
            message="tns:POProcessingProblem"/>
	</operation>
</portType>
</definitions>

Example 1: Abstract WSDL Description


<definitions xmlns:tns="urn:ConcretePOService"
             xmlns:abs="urn:AbstractPOService"
             xmlns="http://schemas.xmlsoap.org/wsdl/" 
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
             targetNamespace="urn:ConcretePOService" 
             name="POService">
 <import namespace="urn:AbstractPOService" location="Abstract.wsdl"/>
 <binding name="IPurchaseOrderBinding" type="abs:IPurchaseOrder">
  <soap:binding style="document" 
                transport="http://schemas.xmlsoap.org/soap/http"/>
   <operation name="acceptPO">
	<soap:operation/>
	 <input>
	     <soap:body use="literal"/>
      </input>
      <output>
	     <soap:body use="literal"/>
	 </output>
	<fault name="POProcessingProblem">
	  <soap:fault name="POProcessingProblem" use="literal"/>
	 </fault>
	</operation>
   </binding>
   <service name="POService">
    <port name="IPurchaseOrderPort" 
          binding="tns:IPurchaseOrderBinding">
	<soap:address 
          location="http://127.0.0.1:8080/docliteralfromjava/jaxrpc"/>
   </port>
  </service>
</definitions>

Example 2: Concrete WSDL Description

Java WSDP 1.4 is used to demonstrate and deploy this example. Java WSDP contains key technologies, tools, and APIs that simplify web services development using the Java 2 platform. The service endpoint interface (SEI) shown in Example 3, and the outline for the implementation class can be generated using runtime tools as described in the JAX-RPC specifications from the WSDL. The Java WSDP provides the wscompile and wsdeploy tools for this purpose.


 // This class was generated by the JAXRPC SI, do not edit.
// Contents subject to change without notice.
// JAX-RPC Standard Implementation (1.1.2, build R23)
// Generated source version: 1.1.2

package com.examples.docliteral;

public interface IPurchaseOrder extends java.rmi.Remote {
  public com.examples.docliteral.PurchaseOrderStatus 
   acceptPO(com.examples.docliteral.PurchaseOrder parameters) throws   
                         com.examples.docliteral.POProcessingProblem,   
                         java.rmi.RemoteException;
 }

Example 3: Generated SEI interface

The Ant build file and tasks enclosed with the example source can be inspected for further details. The –f:wsi switch passed to wscompile ensures that any the WSDL and generated code is checked for WS-I basic profile conformance.


import com.examples.docliteral.clientbindings.*;
import java.util.Calendar;
import java.math.BigDecimal;


public class WSDLClient {

    public static void main(String[] args) throws Exception {
       String url = "http://localhost:9090/docliteralfromwsdl/jaxrpc";
       if (args.length == 1) {
          url = args[0];
        }
        POService_Impl serviceproxy = new POService_Impl();
        IPurchaseOrder_Stub stub = (IPurchaseOrder_Stub) 
                               (serviceproxy.getIPurchaseOrderPort());
        

       stub._setProperty(javax.xml.rpc.Stub.ENDPOINT_ADDRESS_PROPERTY,
                          url);
       PurchaseOrderStatus result= sendPurchaseOrder(stub);
       System.out.println("Order id is : " + result.getOrderid());
       System.out.println("Timestamp is : " + result.getTimestamp());
    }


    /**
     * Sends a purchaseorder to the service
     */
    private static PurchaseOrderStatus 
                   sendPurchaseOrder(IPurchaseOrder_Stub stub) 
                   throws java.rmi.RemoteException {
       PurchaseOrderStatus result=null;
	   try {
	        Address addrs = new Address("1 Main Street", 
                                         "Beverly Hills", "CA",  
                                         "90210");
             LineItem items[] = new LineItem[]{
                             new LineItem("Copier Paper", new  
                                          BigDecimal(10.00), 2),
	              	      new LineItem("Toner", new  
                                          BigDecimal(920.00), 1)};
             PurchaseOrder order = new PurchaseOrder();
		  order.setCreateDate(Calendar.getInstance());
		  order.setBillTo(addrs);
		  order.setShipTo(addrs);
		  order.setItems(items);
		  order.setPoID("ABC-CO-19282");
		  result = stub.acceptPO(order);
	        } catch (POProcessingProblem e1) {
            System.out.println("Problem processing PO on the web 
                                service : " + e1);
		  }
		   return result;
    }
}

Example 4: JAX-RPC client implementation

With the service successfully deployed, the service client can be written to consume the web service. The run-wsdl-client Ant task compiles and executes the client, and the client source is shown in Example 4.

Just as the wscompile tool in Java WSDP is used to read the WSDL and generate the client side bindings in Java, the WSDL description can now be passed to the Microsoft .NET wsdl.exe compiler in order to generate the client side stubs.

wsdl /language:CS /protocol:SOAP 
 http://localhost:8080/docliteralfromwsdl/jaxrpc?WSDL

This generates the client side stub or proxy called POService. The C# source file POService.cs contains the structures and serialization rules based on the schema and bindings defined in the WSDL. To use this, a Windows DLL needs to be built out of the generated proxy code using the C# compiler, passing it the referenced dlls from the .Net framework.

csc /t:library /r:System.Web.Services.dll /r:System.Xml.dll POService.cs

The next step is to write a client (just like we did in Java) and invoke the acceptPO() method in C#. This is shown in Example 5. It can be seen that the names of the methods in the generated C# proxy is identical to the method name used in the JAX-RPC Web Service and the JAX-RPC client. The C# client code is remarkably similar to the JAX-RPC stub client written earlier due to the syntactic and semantic similarities between the two programming languages. The client code can now be compiled using the C# compile csc and executed.

csc /t:exe /r:POService.dll JAXClient.cs


using System;

namespace PurchaseOrderConsumer{
//Sample client showing consumption of a Java based Document based Web //Service from C# client
class JAXClient {
    // The main entry point for the application.
    [STAThread]
    static void Main(string[] args) {
// Instantiate the stub/proxy
       POService service = new POService();
// Set the endpoint URL to go though our SOAP trace utility
       if (args.Length == 1)
            service.Url = args[0];
       else
       service.Url = "http://localhost:9090/docliteralfromwsdl/jaxrpc";       
       System.Console.WriteLine("Invoking JAX-RPC Client on " +  
                                 service.Url);
// Create an Address
        Address addrs = new Address();
        addrs.street = "1 Main Street";
        addrs.city = "Boston";
        addrs.state = "MA";
        addrs.zipCode = "01829";
// Create a PurcahseOrder
        PurchaseOrder po = new PurchaseOrder();
        po.createDate = new DateTime(2003, 08, 30);
        po.billTo = addrs;
        po.shipTo = addrs;
        po.poID = "99AA";
// Create some Items
        LineItem[] orderitems = new LineItem[1];
        LineItem item = new LineItem();
        item.itemname = "Copy Machine";
        item.price = 100;
        item.quantity = 10;
        orderitems[0] = item;
// Add the Items to the PurchaseOrder
        po.items = orderitems;
// Send the request
	PurchaseOrderStatus status=service.acceptPO(po);
        Console.WriteLine("Payment was scheduled Orderid: " + 
                           status.orderid );
        Console.WriteLine("         Timestpamp: " + status.timestamp );
     }
  }
}

Example 5: C# Client Code.

The outputs from the JAX-RPC and C# Clients are shown in Figure 5 and 6 respectively. Also the SOAP request and response messages over the wire are shown in Example 6 through 9. It can be seen that the response by the service is identical in nature to the JAX-RPC and C# clients. This will always be the case, because from a service’s perspective it is not tied to the implementation on the client side; it only cares about the SOAP message it receives over the wire, which could originate from any possible client, even one sending raw data over sockets.

Interoperability-fig4.png

Figure 5: JAX-RPC Client output

Interoperability-fig5.png

Figure 6: C# Client output


POST /docliteralfromwsdl/jaxrpc HTTP/1.1
Content-Type: text/xml; charset=utf-8
Content-Length: 922
SOAPAction: ""
User-Agent: Java/1.4.2_03
Host: localhost:9090
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"  
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"  
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/"        
              xmlns:ns0="urn:POProcessingFault" 
              xmlns:ns1="urn:PurchaseOrderDocument" 
            xmlns:ns2="urn:Status">
 <env:Body>
     <ns1:PurchaseOrderDocument>
         <billTo>
          <street>1 Main Street</street>
          <city>Beverly Hills</city>
          <state>CA</state>
          <zipCode>90210</zipCode>
        </billTo>
        <createDate>2004-09-02T10:54:49.001-04:00</createDate>
        <items>
          <itemname>Copier Paper</itemname>
          <price>10</price>
          <quantity>2</quantity>
        </items>
        <items>
          <itemname>Toner</itemname>
          <price>920</price>
          <quantity>1</quantity>
        </items>
        <poID>ABC-CO-19282</poID>
        <shipTo>
           <street>1 Main Street</street>
           <city>Beverly Hills</city>
           <state>CA</state>
           <zipCode>90210</zipCode>
         </shipTo>
     </ns1:PurchaseOrderDocument>
   </env:Body>
</env:Envelope>


Example 6: JAX-RPC Client SOAP request


HTTP/1.1 200 OK
X-Powered-By: Servlet/2.4
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 02 Sep 2004 14:54:51 GMT
Server: Sun-Java-System/Application-Server-PE-8.0
1f7
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"  
              xmlns:xsd="http://www.w3.org/2001/XMLSchema"     
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
              xmlns:ns0="urn:POProcessingFault" 
              xmlns:ns1="urn:PurchaseOrderDocument" 
              xmlns:ns2="urn:Status">
<env:Body>
<ns2:Status>
   <orderid>ABC1094136891244</orderid>
   <timestamp>Thu Sep 02 10:54:51 EDT 2004</timestamp>
  </ns2:Status>
</env:Body>
</env:Envelope>
0

Example 7: SOAP response by the service to the JAX-RPC Client


POST /docliteralfromwsdl/jaxrpc HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 1.1.4322.573)
Content-Type: text/xml; charset=utf-8
SOAPAction: ""
Content-Length: 750
Expect: 100-continue
Connection: Keep-Alive
Host: localhost:9090

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
   <PurchaseOrderDocument xmlns="urn:PurchaseOrderDocument">
   <billTo xmlns="">
     <street>1 Main Street</street>
     <city>Boston</city>
     <state>MA</state>
     <zipCode>01829</zipCode>
   </billTo>
  <createDate xmlns="">2003-08-30T00:00:00.0000000-04:00</createDate>
  <items xmlns="">
    <itemname>Copy Machine</itemname>
    <price>100</price>
    <quantity>10</quantity>
   </items>
   <poID xmlns="">99AA</poID>
   <shipTo xmlns="">
     <street>1 Main Street</street>
     <city>Boston</city>
     <state>MA</state>
     <zipCode>01829</zipCode>
   </shipTo>
  </PurchaseOrderDocument>
 </soap:Body>
</soap:Envelope>

Example 8: C# Client SOAP request


HTTP/1.1 100 Continue
HTTP/1.1 200 OK
X-Powered-By: Servlet/2.4
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Transfer-Encoding: chunked
Date: Thu, 02 Sep 2004 14:58:29 GMT
Server: Sun-Java-System/Application-Server-PE-8.0

1f7
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
              xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
              xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" 
              xmlns:ns0="urn:POProcessingFault" 
              xmlns:ns1="urn:PurchaseOrderDocument" 
              xmlns:ns2="urn:Status">
  <env:Body>
   <ns2:Status>
   <orderid>ABC1094137109348</orderid>
   <timestamp>Thu Sep 02 10:58:29 EDT 2004</timestamp>
   </ns2:Status>
 </env:Body>
</env:Envelope>
0

Example 9: SOAP response by the service to the C# Client

In this paper we have examined some of the architectural issues, stumbling blocks, workarounds surrounding interoperability of Web Services and the emergence of WS-I . If you are a developer you should seriously consider using the tools and examining the sample application provided by WS-I. If you’ve already developed and deployed Web Services consider using the Monitor and Analyzer to profile your existing Web Services and determine possible interoperability loop holes. If you’re starting to develop new Web Services consider the benefits of using Java and J2EE as the platform of choice for your architecture, now more than ever because of its support for the WS-I profiles. As interoperability becomes a reality, the value and return on investment offered by an integrable platform like J2EE versus integrated products becomes ever so important. Interoperability is good news for developers and architects. Now they can be finally assured that things may actually work across different platforms and technology stacks as envisioned by the Web Services paradigm.

Bibliography

[1]
WS-I http://www.ws-i.org
[2]
Java Web Services Architecture (ISBN 1558609008, www.theserverside.com/resources/article.jsp?l=JWSA)
[3]
Standards Coordinating Committee. IEEE Standard Glossary of Software Engineering Terminology (IEEE Std 610.12-1990). New York, NY: The Institute of Electrical and Electronics Engineers, 1990.
[4]
National Communications System. Telecommunications: Glossary of Telecommunication Terms (Federal Standard 1037C). Arlington, VA: National Communications System, 1996.http://www.its.bldrdoc.gov/fs-1037/
[5]
Hypertext Transfer Protocol http://www.w3.org/Protocols/rfc2616/rfc2616.html
[6]
Simple Mail Transfer Protocol link http://www.faqs.org/rfcs/rfc821.html
[7]
POP v3 http://www.faqs.org/rfcs/rfc1939.html
[8]
RFC-2616 http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
[9]
JAX-RPC http://java.sun.com/xml/jaxrpc/index.jsp
[10]
SOAP Builders http://groups.yahoo.com/group/soapbuilders/
[19]
Best practices, Patterns and Strategies for Building Document Based Web Services http://java.sun.com/developer/technicalArticles/xml/jaxrpcpatterns/index.html
[12]
WS-I Security Profile http://www.ws-i.org/Profiles/BasicSecurityProfile-1.0-2004-05-12.html
[13]
WS-I Attachment Profile http://www.ws-i.org/Profiles/AttachmentsProfile-1.0.html
[14]
Microsoft .NET SDK http://www.microsoft.com
[15]
Microsoft .NET Framework Redistributable Package version 1.1 Runtime http://msdn.microsoft.com/library/default.asp?url=/downloads/list/netdevframework.asp
[16]
Java WSDP http://java.sun.com/webservices/jwsdp/index.jsp
[17]
Java WSDP Developer Community https://jwsdp.dev.java.net/
[18]
Sample Source Code for Demo Example.zip

XHTML rendition made possible by SchemaSoft's Document Interpreter™ technology.