|
Comments
|
Today's Top SOA Links
Web Services Web Services Invocation Framework, part 2
Web Services Invocation Framework, part 2
By: Boris Lublinsky
Jul. 23, 2003 12:00 AM
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
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
Using the Native JMS Provider - 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(); 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:
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 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 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 After implementing the service, the WSIF client code is run again, producing the same result as seen earlier.
Using JNDI to Store Service Information 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 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 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 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 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 Reader Feedback: Page 1 of 1
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
|||||||||||||||||||||||||||