Bridging islands of enterprise software

WSIF offers enterprise Java systems a bridge to any component or service, regardless of implementation or location

Every enterprise software system must tie together numerous existing software systems and codebases. Such systems might need to access existing Enterprise JavaBeans (EJB) components, legacy code in Java, or Web services over SOAP. Such dependencies make enterprise software systems brittle. They tend to break when external systems change location or when implementation technologies change. Basing all your components and solutions on SOAP is not always the answer because a SOAP-based implementation has penalties. Web Services Invocation Framework (WSIF) is the answer. It provides your Java codebase total freedom for such platform and location vagaries.

Simply put, WSIF is a client-side invocation framework. It is a simple Java codebase with an API that sits between your client code and the services your code must access. It provides a layer of abstraction to decouple client code from access to a service, as well as its location and underlying implementation. Thereby, your Java code can access both SOAP and non-SOAP-based services in a transport-, language-, and platform-independent fashion. As will be demonstrated in examples below, with WSIF, you will find that your code does not need to change or be recompiled when the service implementation changes from Java classes to EJB, or to SOAP-based services, or to even .Net and COM-based (Component Object Model) services.

WSIF also provides location independence. A service's actual location is externalized in a configuration file. This allows your client code's access location to change with no code modifications or recompilation.

Just to give you an idea about WSIF's power, the following Java StockQuote client code will not change when the actual service provider moves from Java to EJB or to SOAP; the required interface remains.

                        ...   
// Create a service factory.
WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
// Parse WSDL.
WSIFService service =
factory.getService('c://stockquoteservice.wsdl',
                  null,
                  null,
                  "http://mycompany.stockquote/",
                  "net.xmethods.services.stockquote.StockQuotePortType");
// Create the service stub, StockQuote.class is class generated by WSDL2Java for StockQuote service WSIF configuration file.
StockQuote service = (StockQuote) service.getStub(StockQuote.class);
// Do the invocations.
string symbol = "IBM";
string result = service.getQuote(symbol);
system.out.println("Price for " + symbol + " is " + result);
...
                   

Benefits of WSIF

An enterprise application usually consists of numerous pieces of software services developed over many years in assorted languages on various platforms with different protocols—pieces that must work together to provide business and operational functionality. These pieces constantly change: A service previously available as Java class may change to a Java Message Service-based implementation. Or a service that used a particular version of a SOAP implementation may be upgraded, leaving your code with a deprecated API. Or a service available as an EJB component internally within a company is outsourced to an external vendor and is now available as a SOAP-based service.

The other volatile aspect of these services is location. A service that may have been available locally may suddenly be moved to servers on the other side of the globe. As a practice, experienced designers have learned to externalize the location of such services; however, enforcing such rigors in a large and complex enterprise solution developed and maintained by a global fleet of designers and developers proves difficult.

Typically, SOAP is touted as panacea for such pain points. SOAP has been a unifying protocol, but its implementation, from a practical perspective, has limitations. First, not all services may be enabled as SOAP-based services. There could be significant cost implications in enabling all the services developed over the years as SOAP-based services. Second, using SOAP has performance implications. Benchmarking comparisons indicate that SOAP calls using Apache Axis have several hundred times more latency than Java RMI (remote method invocation) calls (see "Latency Performance of SOAP Implementations" (IEEE Cluster Computing and the Grid, 2002)). Considering the performance impact, it would be unreasonable to expect Java clients to use SOAP for accessing EJB components to gain platform and location independence.

WSIF, modeled after WSDL (Web Services Description Language), is more suitable for alleviating such problems. For a given service, WSIF uses a WSDL-based XML file so that custom wrappers for new or existing Java and EJB objects are not needed. WSDL provides definitions of services: it defines the interface consisting of functions, parameters, return values, and exceptions and the binding consisting of the service's implementation specification and location. WSDL was designed with extensibility in mind. In a typical SOAP-based Web service, the binding is almost always soap:binding. WSDL provides plug-ins to other bindings such as Java and EJB. WSIF exploits this specific WSDL extensibility. I describe more on this extensibility in later sections.

Using WSIF

There are two invocation models for using the WSIF API: stub invocation or dynamic invocation. The stub model relies on stubs at the client side; service functions are invoked on these stubs. This approach offers a more natural way of programming and has the benefits of compiler-checked code. The dynamic model programmatically constructs service calls. This model suits those applications that want a more abstract view of a service.

To better understand these invocation models, let's look at an example that provides a stock price. The service StockQuote has a single call, getQuote(), that expects a string. Let's first look at a stub invocation:

                        ...
// Create a service factory.
1.  WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
// Parse WSIF WSDL file that contains exact StockQuote service and StockQuote port-type.
2. WSIFService service =
3. factory.getService('c://stockquoteservice.wsdl',
4.                  "http://mycompany.stockquote/",
5.                  "net.xmethods.services.stockquote.StockQuoteService",
6.                  "http://mycompany.stockquote/",
7.                  "net.xmethods.services.stockquote.StockQuotePortType");
// Create the service stub, StockQuote.class is a class generated by WSDL2Java for 
// StockQuote service WSIF configuration file.
8. StockQuote stub = (StockQuote) service.getStub(StockQuote.class);
// Call the function to get the stock price.
9. string symbol = "IBM";
10. float result = stub.getQuote(symbol);
11. system.out.println("Price for " + symbol + " is " + result);
...
                   

On Line 1, an instance of a WSIF factory is created, which initializes the WSIF framework if it has not already initialized.

On Lines 2 through 7, the WSIF factory retrieves instances of specific services. The WSIF factory is supplied the WSIF-WSDL file location, service namespace, service name, port-type namespace, and port-type name. The service namespace and service name can be left as null if the WSDL file contains only one service definition and location. The WSIF parses the WSIF-WSDL file to create instances of services requested.

On Line 8, a stub instance is retrieved. Calls are made against this stub. Stub classes can be created using the WSDL2Java tool, an industry-standard tool for generating Java proxies and skeletons for services with WSDL descriptions. WSIF uses client-side proxies generated using the following command: %java org.apache.axis.wsdl.WSDL2Java (WSIF-WSDL-file-URL).

On Line 10, an actual call is made against the stub. Here, the WSIF framework internally maps to the appropriate port-type implementation specified in the WSIF-WSDL file and places a call to the endpoint. The value returns to your client code.

Now let's look at a dynamic invocation:

                        ...
// Create a service factory.
1. WSIFServiceFactory factory = WSIFServiceFactory.newInstance();
// Parse WSIF WSDL file that contains exact StockQuote service and StockQuote 
// port-type.
2. WSIFService service =
3. factory.getService('c://stockquoteservice.wsdl',
4.                  "http://mycompany.stockquote/",
5.                  "net.xmethods.services.stockquote.StockQuoteService",
6.                  "http://mycompany.stockquote/",
7.                  "net.xmethods.services.stockquote.StockQuotePortType");
// Get the port.
8. WSIFPort port = service.getPort();
// Create the operation.
9. WSIFOperation operation = port.createOperation("getQuote");
                    
// Create the input, output, and fault messages for the operation.
10. WSIFMessage input = operation.createInputMessage();
11. WSIFMessage output = operation.createOutputMessage();
12. WSIFMessage fault = operation. createFaultMessage();
// Populate the input message.
13. String symbol = "UIS"
14. input.setObjectPart("symbol", symbol);
// Do the invocation.
15. operation.executeRequestResponseOperation(input, output, fault); 
// Extract the result from output message.
16. float result = output.getFloatPart("result")
...
                   

In the dynamic invocation, Lines 1 through 7 match the code in the stub invocation. On Line 8, a port is created for the service; on Line 9, a specific operation of interest is created. On Lines 10, 11, and 12, input, output, and fault messages are created. For the getQuote() operation, we have string input and string output. The input values are set in Line 14, and finally, on Line 15, the operation is invoked. On Line 16, the stock price value is retrieved.

Using WSIF step by step

  1. Download the WSIF framework from Apache.
  2. Run wsif-2.0\classpath.bat to set appropriate classpath. This script also sets the classpath for samples included in the download. You may need to modify this file depending on your development environment.
  3. Create a WSIF-WSDL file for your service provider. For SOAP-based applications, you could use its WSDL as a starting point. For Java and EJB applications, you could use Java2WSDL. And, for adventurous types, you could create WSDL by hand.
  4. Run WSDL2Java to create Java stubs for the WSDL.
  5. Modify WSDL to include WSIF extensions for Java, EJB, etc., depending on type of service provider.
  6. Place WSIF-WSDL file and stubs in your application's directory path.
  7. Start using WSIF in your application.

WSIF and service-oriented architecture

SOA-based services must adhere to three basic tenets:

  • Interface contract is platform-independent
  • Service can be dynamically located and invoked
  • Service is self contained

WSIF takes your code a few steps closer to service-oriented architecture:

  • WSIF's WSDL-based interface description of services provides platform-independent interface definitions in portType.
  • The WSIF framework automatically locates component locations specified in the WSDL-based XML configuration file. The choice of implementation can be deferred until runtime.
  • Being a client-side framework, WSIF cannot make a service self contained; however, WSIF works best with self-contained services and does not require state management between calls.

WSIF Java extension and WSDL

Let's walk through a structure of WSDL to see how WSIF extends WSDL. WSDL is an XML file with four main sections:

  1. Definitions
  2. Types
  3. Bindings
  4. Services

WSIF extends WSDL's bindings and services sections to specify WSIF providers. Bindings allow plug-ins of various providers. Thus, WSIF has providers for Java, EJB, SOAP, J2EE Connector Architecture, etc. These providers enable the invocation of corresponding services.

We will take a publicly available WSDL file at http://services.xmethods.net to understand various sections of WSDL and how WSIF extends such a file. For a more detailed explanation of WSDL, please see Resources. The WSDL delayed-quote service file is available here: http://services.xmethods.net/soap/urn:xmethods-delayed-quotes.wsdl.

Definitions

Let's look at the first two lines of the delayed-quote service WSDL file downloaded from the site above. This is the definitions section of the WSDL file:

                        <definitions name="net.xmethods.services.stockquote.StockQuote" 
   targetNamespace="http://www.themindelectric.com/wsdl/net.xmethods.services.
   stockquote.StockQuote/">
                   

The definitions section is WSDL's root element and is a container for all other WSDL elements. It holds all necessary information about the service and its attributes. The definitions element's targetNamespace attribute is required and points to a URI that demarcates this WSDL file's namespace. The WSIF service definition requires the addition of a few namespaces as indicated below. targetNamespaces differentiate definitions from element declarations in different vocabularies. This means various elements defined in this WSDL file belong to the http://www.themindelectric.com/wsdl/net.xmethods.services namespace.

1 2 Page 1
Page 1 of 2