IBM Cloud Authors: Elizabeth White, Yeshim Deniz, Pat Romanski, Liz McMillan, Stefan Bernbo

Related Topics: IBM Cloud

IBM Cloud: Article

Web Services Invocation Framework, part 2

Web Services Invocation Framework, part 2

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:

  • ejb:binding type: Denotes that the EJB provider should be used for service invocation.
  • format:typeMapping: Defines mapping between SOAP definition (XML serialization types) and Java types. This clause is used for defining Java types/classes corresponding to both basic and complex data types.

    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:

  • className: Used for specifying fully the qualified name of the home interface of the EJB
  • jndiName: Used for specifying the JNDI name of the EJB's home interface
  • initialContextFactory: Used for specifying the fully qualified name of the JNDI initial context factory as required by initial context creation
  • jndiProviderURL: Used for specifying the JNDI provider URL as required by initial context creation

    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:
    streetName=The Waterfront
    city=Some City

    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:

  • jms:binding type: Defines that the native JMS provider should be used for service invocation. This binding type has two parameters.
    - 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.
  • format:typeMapping clause: Defines the serialization style used by the provider. The only supported mapping type for this provider is encoding="XML".

    Extensions in the service portion of the WSDL file include the jms:address clause, which specifies JMS addressing. This clause contains five required elements:

  • jndiDestinationName: Used for specifying the JNDI name of the JMS destination object.
  • destinationStyle: Used for specifying type of JMS destination object. Allowable values are "queue" and "topic".
  • jndiConnectionFactoryName: Used for specifying the JNDI name of the JMS connection factory object.
  • initialContextFactory: Used for specifying the fully qualified name of the JNDI initial context factory as required by initial context creation.
  • jndiProviderURL: Used for specifying the JNDI provider URL as required by initial context creation.

    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 +
    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:

  • The package name for the formatter class is the package name for the parameter class appended by the .jms.xml extension.
  • The name of the file is the parameter class name appended by FormatHandler. After these classes were added, the WSIF client code was run, producing the XML request message shown in Listing 7.

    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:

  • WSDLOperation: Operation name, corresponding to the WSDL operation name
  • WSDLInput: Name of the input message as defined in WSDL
  • WSDLOutput: Name of the output message as defined in WSDL

    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:

  • Eliminate all of the type definitions
  • Modify message definitions to be single-part messages
  • Change style to the document everywhere that RPC-style invocation was used
  • Change encoding to literal
  • Remove the encoding attribute from the SOAP body in the binding definitions

    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:

  • Listener class: Allows listening for asynchronously delivered replies (see Listing 24)
  • Callback class: Invoked when an asynchronous reply is delivered (see Listing 25)

    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.

    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.

  • 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.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.

    IoT & Smart Cities Stories
    In his general session at 19th Cloud Expo, Manish Dixit, VP of Product and Engineering at Dice, discussed how Dice leverages data insights and tools to help both tech professionals and recruiters better understand how skills relate to each other and which skills are in high demand using interactive visualizations and salary indicator tools to maximize earning potential. Manish Dixit is VP of Product and Engineering at Dice. As the leader of the Product, Engineering and Data Sciences team at D...
    When talking IoT we often focus on the devices, the sensors, the hardware itself. The new smart appliances, the new smart or self-driving cars (which are amalgamations of many ‘things'). When we are looking at the world of IoT, we should take a step back, look at the big picture. What value are these devices providing. IoT is not about the devices, its about the data consumed and generated. The devices are tools, mechanisms, conduits. This paper discusses the considerations when dealing with the...
    Bill Schmarzo, Tech Chair of "Big Data | Analytics" of upcoming CloudEXPO | DXWorldEXPO New York (November 12-13, 2018, New York City) today announced the outline and schedule of the track. "The track has been designed in experience/degree order," said Schmarzo. "So, that folks who attend the entire track can leave the conference with some of the skills necessary to get their work done when they get back to their offices. It actually ties back to some work that I'm doing at the University of San...
    Bill Schmarzo, author of "Big Data: Understanding How Data Powers Big Business" and "Big Data MBA: Driving Business Strategies with Data Science," is responsible for setting the strategy and defining the Big Data service offerings and capabilities for EMC Global Services Big Data Practice. As the CTO for the Big Data Practice, he is responsible for working with organizations to help them identify where and how to start their big data journeys. He's written several white papers, is an avid blogge...
    Dynatrace is an application performance management software company with products for the information technology departments and digital business owners of medium and large businesses. Building the Future of Monitoring with Artificial Intelligence. Today we can collect lots and lots of performance data. We build beautiful dashboards and even have fancy query languages to access and transform the data. Still performance data is a secret language only a couple of people understand. The more busine...
    If a machine can invent, does this mean the end of the patent system as we know it? The patent system, both in the US and Europe, allows companies to protect their inventions and helps foster innovation. However, Artificial Intelligence (AI) could be set to disrupt the patent system as we know it. This talk will examine how AI may change the patent landscape in the years to come. Furthermore, ways in which companies can best protect their AI related inventions will be examined from both a US and...
    Enterprises have taken advantage of IoT to achieve important revenue and cost advantages. What is less apparent is how incumbent enterprises operating at scale have, following success with IoT, built analytic, operations management and software development capabilities - ranging from autonomous vehicles to manageable robotics installations. They have embraced these capabilities as if they were Silicon Valley startups.
    Chris Matthieu is the President & CEO of Computes, inc. He brings 30 years of experience in development and launches of disruptive technologies to create new market opportunities as well as enhance enterprise product portfolios with emerging technologies. His most recent venture was Octoblu, a cross-protocol Internet of Things (IoT) mesh network platform, acquired by Citrix. Prior to co-founding Octoblu, Chris was founder of Nodester, an open-source Node.JS PaaS which was acquired by AppFog and ...
    The deluge of IoT sensor data collected from connected devices and the powerful AI required to make that data actionable are giving rise to a hybrid ecosystem in which cloud, on-prem and edge processes become interweaved. Attendees will learn how emerging composable infrastructure solutions deliver the adaptive architecture needed to manage this new data reality. Machine learning algorithms can better anticipate data storms and automate resources to support surges, including fully scalable GPU-c...
    Cloud-enabled transformation has evolved from cost saving measure to business innovation strategy -- one that combines the cloud with cognitive capabilities to drive market disruption. Learn how you can achieve the insight and agility you need to gain a competitive advantage. Industry-acclaimed CTO and cloud expert, Shankar Kalyana presents. Only the most exceptional IBMers are appointed with the rare distinction of IBM Fellow, the highest technical honor in the company. Shankar has also receive...