| By Boris Lublinsky | Article Rating: |
|
| July 23, 2003 12:00 AM EDT | Reads: |
23,326 |
The Web Services Invocation Framework (WSIF) is an architecture and programming model that - unlike today's most popular Web services APIs, JAX-RPC and JAXM - supports RPC and messaging invocation of Web services in a single programming model.
In Part 1 of this series I introduced WSIF and described its architecture and programming model. In this article I will discuss more advanced topics of WSIF programming, such as usage of different providers, JNDI bindings, asynchronous service invocation, and messaging.
Using the EJB Provider
After creating the basic Web service implementation, I attempted to use the same WSIF client code (see Listing 2) for EJB transport. Note: All of the code for this article can be downloaded from www.sys-con.com/websphere/sourcec.cfm. The only required change for switching from SOAP/HTTP communications to a straight EJB invocation was a change in the binding and service definition portions of the WSDL file (see Listing 1) as shown in Listing 3. This file uses WSDL extensions defined by WSIF. Extensions in the binding portion of the WSDL file are as follows:
Extensions in the service portion of the WSDL file include the ejb:address clause, which is used for specifying EJB location. This clause contains four major elements:
After implementing changes to the WSDL as defined in Listing 3, the WSIF client code (see Listing 2) is run, producing the same result as execution of the simple WSIF client in Part 1:
WSIF factory created
WSIF service created
WSIF types map created
WSIF port created
WSIF operation created
WSIF input message created
Successfully added name and address
Successful lookup of name 'Jack' in addressbook
The address found was:
streetNum=1
streetName=The Waterfront
city=Some City
state=NY
zip=47907
phoneNumber=areaCode=765
exchange=494
number=4900
Using the Native JMS Provider
WSIF supports two types of JMS providers - SOAP over JMS using the Axis SOAP provider, and the native JMS provider. I evaluated the JMS provider first. Similar to the EJB provider, this file uses WSDL extensions defined in WSIF, as shown in Listing 4. The binding portion of the WSDL file uses the following extensions:
- Transport type: Used for service invocation. In this case transport type has to be http://schemas.xmlsoap.org/soap/jms.
- Message type: Defines the JMS message type used for message invocation. The only supported message type is TextMessage, which corresponds to the JMS text message.
Extensions in the service portion of the WSDL file include the jms:address clause, which specifies JMS addressing. This clause contains five required elements:
In addition to these, a number of additional JMS property elements can be specified. The one that I have used is JMSReplyTo property, which defines the JNDI name of the reply destination object and can be specified either in the WSDL file or programmatically through the message context, as follows:
WSIFMessage context = operation.getContext();
context.setObjectPart( WSIFConstants.CONTEXT_JMS_PREFIX +
"JMSReplyTo","jms\\mOutput");
operation.setContext(
context );
If this property is not set, and the JMS provider is used for request/reply interaction with the service, the provider will create a temporary queue for reply messages.
After implementing changes to the WSDL, as defined in Listing 4, the WSIF client code in Listing 2 was run, producing the following request message:
streetNum=1 streetName=The Waterfront city=Some City
state=NY zip=47907
phoneNumber=areaCode=765 exchange=494 number=4900
The reason the message looks so strange is that for XML formatting to work correctly, special formatters have to be implemented for every Java class used in the service parameters. If the WSIF runtime cannot find these formatters, the content of each message part is stringified. Unless WSAD v5 Integration Edition is used, these files have to be written by hand. I've used WSAD v5 to generate two formatter files (see Listings 5 and 6), used for XML serialization of the Java classes Address and Phone.
The two formatters are loaded dynamically by the WSIF environment based on their fully qualified name. WSIF implementation assumes the following:
Implementing Service for the Native JMS Provider
With the native XML encoding, WSIF allows for a very straightforward implementation of the service provider. A very simple provider implementation is presented in Listing 8. Most of the code implements a standard JMS listener. The WSIF-specific code starts in the onMessage method. The native JMS provider sets three JMS properties on the outgoing JMS message:
In addition, if the service invocation is request/reply, the JMSReplyTo property is set by the provider with the destination object, to which the reply needs to be sent.
The onMessage implementation receives the incoming message and retrieves the parameters described earlier. Based on the value of the WSDLOperation property, the appropriate method is invoked. This method will process the request and produce a reply message, which is then sent back to the destination object. Before the message is sent back, the correlation ID of the outgoing method is set to the value of the ID of the initial message. This is required, because the service consumer is listening on the queue using a correlation ID-based selector.
The implementation of the method is very straightforward because WSIF implementation classes can be used for both processing incoming messages and building outgoing messages. In order to do this, the class constructor has to create the service and appropriate port exactly the way the client does. Based on the port, the service method gets a formatter, which allows unmarshaling of the incoming request and its conversion into a WSIF message. When this is done, Java objects can be extracted from the WSIF message the same way as with the client. After operations on data are executed, WSIFOperation can be instantiated, which allows the creation of an outgoing message that can be marshaled by the formatter class.
After implementing a service (see Listing 8), the WSIF client code was run again, producing the result shown earlier.
Using an Axis JMS Provider
As an alternative to the native JMS provider, an Axis JMS provider can be used. The advantage of this provider is that it sends true SOAP messages over JMS. In order to support the Axis JMS provider, binding and service definitions options for my original WSDL file have to be modified, as shown in Listing 9. This file uses WSDL extensions defined by WSIF. In the binding section I use soap:binding, the same as in the original file, but in addition, I specify http://schemas.xmlsoap.org/soap/jms as a transport.
Extensions in the service portion of the WSDL file include the jms:address clause, which is used to specify JMS addressing (including additional JMS properties), similar to the native JMS case. The only additional JMS property specified in this case is the SOAPAction property, which serves the same purpose as SOAPAction in the HTTP header. This parameter can be set in the JMS Axis implementation and used for any desired purpose. After implementing changes to the WSDL as defined in Listing 9, the WSIF client code was run, producing a true SOAP request message, as shown in Listing 10.
Implementing Service for the Axis JMS Provider
Creating a service implementation for the Axis JMS provider is more complex because WSIF does not provide the same level of support for the service implementation in this case that it does for the native JMS provider. For my implementation (see Listing 11) I used a direct invocation of the Axis engine from the JMS listener. In order to use this approach, a constructor of the JMS listener creates a configured instance of the Axis engine, which is responsible for routing of the request and invoking the service implementation (see Listing 12). Listing 13 shows the configuration file for AxisServer.
After implementing the service, the WSIF client code is run again, producing the same result as seen earlier.
Using JNDI to Store Service Information
As explained above, WSIF implementation relies on reading and processing WSDL files for building the runtime service model. In all of the examples discussed, I have used HTTP-based access to the WSDL documents. This approach forces client applications to hard-code exact locations (URLs) of the WSDL documents. This approach is not practical because in a real-world environment these files can move.
Alternative approaches for locating these files use either UDDI-based or JNDI-based registries. WSIF implementations provide built-in hooks for JNDI support. For JNDI-based access I used the JNDIHelper class, provided as part of WSIF distribution in the test/jndi directory. The code for binding WSDL to the JNDI and accessing service using JNDI is presented in Listings 14 and 15. One thing to keep in mind is that this code does not put WSDL into JNDI. The only thing that is stored in the JNDI is the WSDL location (URL), which means that the Web server that the JNDI information refers to has to be up and running for successful service invocation.
Setting Up Custom SOAP Headers Using WSIF
WSIF provides a very simple mechanism for implementing custom SOAP headers. I set custom headers using the Axis JMS provider; Listing 16 shows the code for populating of custom headers. WSIF allows populating both HTTP and SOAP headers through the operation context; SOAP headers for this operation have to be expressed as an ArrayList of XML elements. In my simple example, the headers were built by parsing the hard-coded sample XML snippet. In real-world applications these elements will be created dynamically using existing Java APIs for XML. After the code (see Listing 16) was added, the WSIF client was run again, producing a SOAP request message with custom headers, as shown in Listing 17.
Listing 18 presents a code snippet for extracting the SOAP headers from the reply. Again, the reply headers are extracted from the operation context. Because operation context is shared between request and response, SOAP headers for both will be in the context. The appropriate part name (org.apache.wsif.soap.ResponseHeaders) has to be specified for extracting the response SOAP headers.
Using WSIF for Sending XML Documents
WSIF provides a simple mechanism to take arbitrary XML documents as SOAP messages. I sent custom XML documents using the Axis JMS provider. This approach allows emulating basic behavior of the JAXM using WSIF APIs. In order to implement this scenario, I modified the original WSDL (see Listing 1) to:
Listing 19 shows the resulting XML. In order to populate a message part with the XML document, a document tree element has to be set as a value of an appropriate body part (see Listing 20). Analogous to the custom headers scenario, discussed earlier, documents are built by parsing the hard-coded sample XML snippets. In real-world applications these documents will be created dynamically using existing Java APIs for XML. After the code (Listing 20) was added, the WSIF client was run, producing a SOAP request message as shown in Listing 21.
Implementing Message-Based Service
Service implementation in this case is very similar to the service implementation for the Axis JMS provider. In fact, I use the Axis engine for request routing in this case as well. Although the engine does not do much in this case, I decided to use it because of the request chains implementations provided.
Implementation of the JMS listener in this case (see Listing 21) is very similar to the Axis JMS provider implementation, with the difference that because document-style messaging does not contain any routing information I had to implement my own routing schema. I am using the SOAPAction parameter to define this information. Service implementation for this case is presented in Listing 22, and the Axis server configuration file is shown in Listing 23.
Asynchronous Service Invocation Using WSIF
It is often desirable to invoke a long-running service using the request/reply programming model. Many middleware products, including JMS, support an asynchronous request/reply programming model in which a requester sends a request, provides a callback object, and continues processing. When a reply comes back, a callback object is invoked to process the result of the service invocation.
In Web services programming practice, this model is often emulated through two one-way service invocations - one sending a request for service execution and another returning a reply. Although this approach works in principle, it puts an additional burden on the programmer to match replies to the original requests.
WSIF simplifies this programming model implementation by providing built-in support for asynchronous request/reply. In addition to the executeRequestResponseOperation method, which provides synchronous (blocking) operations invocation, the WSIFOperation class supports the executeRequestResponseAsync method, allowing for asynchronous (nonblocking) method invocation.
In order to implement asynchronous method invocations, two classes need to be implemented:
With these two classes in place, built-in WSIF support is responsible for invoking the appropriate instance of the Callback class, making implementation of asynchronous request/reply very straightforward. Additional WSIF facilities allow for control of the asynchronous reply timeout.
Modification of the basic WSIF client, necessary for asynchronous request/ reply implementation, is shown in Listing 26. After applying these changes and running the code, the same result, shown earlier, was produced.
Conclusion
The evaluation of WSIF presented in this article aims to better explain WSIF usage and to highlight some of its capabilities. WSIF is an extremely powerful set of Web services invocation APIs, supporting both RPC- and messaging-style invocation of Web services. A comparison of WSIF with other Web services invocation frameworks - JAX-RPC and JAXM - is presented in Table 1.
Published July 23, 2003 Reads 23,326
Copyright © 2003 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Boris Lublinsky
Boris Lublinsky is an Enterprise Architect at CNA Insurance where he is involved in design and implementation of CNA’s integration strategy, building application frameworks and implementing service-oriented architecture for the company Prior to this he was Director of Technology at Inventa Technologies, where he was overseeing and actively participating in engagements in EAI and B2B integration implementations and development of large-scale web applications. While a Technical Architect at Platinum Technology and SSA, Boris was involved in component-based systems development and design and implementation of execution platforms for component-based systems. In all, he has over 25 years experience in software engineering and technical architecture.
- Cloud People: A Who's Who of Cloud Computing
- State and Local Governments Adopt Microsoft Dynamics CRM to Improve Citizen Service Delivery
- Cloud Expo New York: Rethink IT and Reinvent Business with IBM SmartCloud
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- ACI Worldwide Empowers Financial Institutions to Increase Efficiency of Card Issuing and Account Management
- Cimtrek announces the general release of its Lotus Notes migrator for Microsoft’s SharePoint platform
- Commander of U.S. Cyber Command and National Security Agency Director, General Keith Alexander, To Keynote Day One of Black Hat USA 2013
- MicroStrategy Announces General Availability of MicroStrategy 9.3.1
- Velocity Technology Solutions Introduces IBM Power Systems Universal Cloud Services at COMMON 2013
- AMAX Launches StorMax(TM) CFS, powered by IBM(R) General Parallel File System(TM) (GPFS(TM))
- MicroStrategy Announces General Availability of MicroStrategy 9.3.1
- Cloud Expo New York: Security for Cloud Computing
- Cloud People: A Who's Who of Cloud Computing
- State and Local Governments Adopt Microsoft Dynamics CRM to Improve Citizen Service Delivery
- Cloud Expo New York: Rethink IT and Reinvent Business with IBM SmartCloud
- SUSE Receives Common Criteria Security Certifications
- LivePerson Scheduled to Participate in Upcoming Investor Conferences
- Session Topics: 12th Cloud Expo / Cloud Expo New York
- ACI Worldwide Empowers Financial Institutions to Increase Efficiency of Card Issuing and Account Management
- Cimtrek announces the general release of its Lotus Notes migrator for Microsoft’s SharePoint platform
- Commander of U.S. Cyber Command and National Security Agency Director, General Keith Alexander, To Keynote Day One of Black Hat USA 2013
- MicroStrategy Announces General Availability of MicroStrategy 9.3.1
- Velocity Technology Solutions Introduces IBM Power Systems Universal Cloud Services at COMMON 2013
- IBM Picks Mobile for Its Next Big Growth Play
- Java vs C++ "Shootout" Revisited
- Where Are RIA Technologies Headed in 2008?
- WebSphere Application Server Java Dumps
- Unveiling the java.lang.Out OfMemoryError
- How To Deploy Scalable WebSphere Applications Using "Maven" Build Tool
- Breaking News: New Internal IBM Report Says "Another Flawed Study"
- Profiles for WebSphere Application Server 6.0
- Last Exclusive JDJ Interview With "IBM's" John A. Swainson, Now CA's Newly Appointed CEO
- Automated Deployment of Enterprise Application Updates
- Developing Java and Web Services Applications on Rational Application Developer V6
- Your Guide to Portal Clustering in WebSphere Portal Server 5.1
- How to Create a Simple Java J2ME Application for BlackBerry




























