devxlogo

Design Guidelines: Building Web Service Wrappers for an XML-based System

Design Guidelines: Building Web Service Wrappers for an XML-based System

ervice Oriented Architecture (SOA) is an increasingly common buzzword in today’s industry. The benefits of a Web services-oriented framework are well appreciated, but not always well-understood. Enterprises planning to convert their conventional backend applications into Web services often plan to achieve the conversion by creating a Web service wrapper around the conventional backend application. The wrapper acts as an intermediary for the conventional application by exposing a Web service interface to the client. This article discusses design considerations for such wrappers that can make them both extensible and flexible, concentrating on conventional applications that take XML as input.

Introducing a Sample Application
To illustrate, consider a simple XML-based billing application as a sample scenario. This application is the conventional application for which the Web service wrapper needs to be developed. It takes XML as input. The sample XML input for the billing application is:

 
Figure 1. Sample Billing Application: The initial sample billing application accepts XML via Java RMI calls, and creates a billing record.
            abcde      PrivilegedUser      12/05/2004      120$   

Using this input, the billing application creates a billing record. You can assume that the billing application is hosted on the company’s intranet. Currently, the applications that use this billing application do so by making a Java RMI call, passing the XML string as an input parameter. Figure 1 shows the structure of the billing application before adding the Web service wrapper.

A Web Service Wrapper for the Application
Because the billing application is a JAVA RMI application, it’s difficult to expose the application outside the intranet without raising security concerns. Exposing the billing application as a Web service makes it available to clients outside the intranet using standard Protocols such as HTTP and SOAP.

 
Figure 2. Sample Billing Application with Web Service Wrapper: Adding the Web services wrapper affects the external and potentially the internal calling applications by exposing billing application functionality through standard SOAP calls.

The function of the Web service wrapper at a very high level is to listen for Simple Object Access Protocol (SOAP) calls and then call the billing application with the appropriate input XML. Figure 2 shows how the Web service wrapper fits into the application architecture.

Functions of the Wrapper
The basic functions of the wrapper are to:

  1. Listen for incoming SOAP calls.
  2. Prepare messages before invoking the billing application
  3. Invoke the billing application.

Listening for SOAP Calls
After developing the wrapper, you need to deploy it as a SOAP service running in an application server. Usually application servers have tools that help in packaging the Web service wrapper and deploying it as a SOAP service. The application server then handles the details of listening for incoming requests and invoking the wrapper appropriately.

Message Preparation
The billing application needs an XML document to process, which calling applications send via RMI. This model works fine as long as the calling applications are inside the intranet, but without opening a port through the firewall, external applications don’t have access to the application. However, after creating the Web service wrapper, external applications can also access the billing application. For many clients, it would be asking a lot to get them to build external calling applications that construct appropriate XML documents for the billing application and send those to the Web service wrapper. This is where the wrapper proves its effectiveness.

Rather than relying on client applications to construct appropriate XML billing messages, you can simply expose wrapper methods that let clients pass appropriate parameters. The wrapper uses the parameter values to construct appropriate XML documents and send those to the billing application. That simplifies the external interface considerably. Using this architecture, external calling applications can call the billing application methods with the appropriate parameters and the wrapper internally constructs the XML.

XML Schema to Method Mapping
To simplify the invocation of the Web service, so that clients need only pass the required values as parameters to the method rather than a complete XML document, you need to design the wrapper carefully, identifying the methods and parameters to be exposed in such a way that they’re flexible and easy for external calling applications to use.

The easiest way to achieve this is to identify the methods and the parameters from the XML schema of the billing application’s input XML. The XML Schema defines all the information about the billing application’s XML document input. It contains details such as the element names, sequences, and default values. So, if the wrapper creates the input XML based on the schema, it is guaranteed to be in functional compliance with the billing application. Using the schema helps in defining the methods for the wrapper. Inside these methods the wrapper constructs input XML and passes that to the billing application. Using the simple schema shown below for the billing application’s XML input, here’s how you might define methods for the wrapper.

                                                                                            

The XML schema defines four elements, of which two ( and ) are optional (minOccurs=0). Note that all the elements must follow the sequence specified in the schema. Based on this information, the wrapper can have the following method definitions.

   makeBillWithUserCategoryAndDate(String userId,      String userCategory,String date,String charge)      makeBillWithDate(String userId,String date,String charge)      makeBillWithUserCategory(String userId,String       userCategory,String charge)      makeBill(String userId,String charge)      makeBillWithXML(String XML)

The parameters of these methods reflect the fact that some of the elements in the XML Schema are optional. By creating several methods with different parameters, users are not forced to send values for the optional date and userCategory elements. In other words, an external calling application that doesn’t need a date or userCategory value in the billing record can use the makeBill(String userId,String charge) method, which doesn’t require the optional values.

One version of the methods listed above takes a single XML input parameter?makeBillWithXML(String XML). This method has been included to allow backward compatibility.

After creating the method definitions, the next step is to write the code that creates the appropriate input XML. The pseudo code below shows the XML creation process for two of the defined method versions.

   makeBillWithUserCategoryAndDate(String userId,      String userCategory,String date,String charge)   {      String inputXml=         "  "      inputXml=inputXml + "" + userId + ""      inputXml = inputXml + "" +          userCategory + ""      inputXml = inputXml + "" + date+ ""      inputXml = inputXml + "" + charge+ ""      inputXml = inputXml + ""            //send this XML to the Billing Application   }

Note that the code maintains the sequence of the elements as required by the schema.

   makeBill(String userId,String charge)   {      String inputXml=         "  "      inputXml=inputXml + "" + userId + ""      inputXml = inputXml + "" + charge+ ""      inputXml = inputXml + ""            //send this XML to the Billing Application   }

Now, the XML is ready to be sent to the billing application.

Invoking the Billing Application
After creating the required XML, the wrapper must send it to the billing application. Currently the billing application is a Java-RMI application, so the wrapper needs to make a Java-RMI call with the constructed input XML. But in the future, you might want to change the RMI-based billing application to a JMS-based billing application. If not designed carefully, this change would necessitate code changes in the Web service wrapper. Because the wrapper accepts data from multiple?and potentially external?clients, you should avoid changing it, if possible. So, it’s advisable to use an approach that uses a configurable transportation protocol handler. To achieve a configurable transportation protocol handler, you’ll need:

  • A configuration file
  • A protocol interface
  • A protocol handler factory class
  • Several interface implementations

These implementations will work as different protocol handlers such as RMIProtocolHandler and JMSProtocolHandler.

High Level Design for a Configurable Protocol Handler
Figure 3 shows the architectural relationship of wrapper, the billing application, and the items listed above

 
Figure 3. Action Sequence: The figure shows the logical sequence of actions to achieve a configurable method for handling various transportation protocols.

Each of the components shown in Figure 3 is discussed below.

Configuration File
The configuration file contains the information about the protocol handler to be used along with other configuration information. For example, here’s a sample protocol handler entry:

      ...      ...       RMIHandler        ...      ...

Protocol Handler Interface
The protocol handler interface defines a method. In this case, the interface needs only an invoke() method that accepts the XML created by the wrapper as an input parameter.

   invoke(String inputXml)

Protocol Handler classes
Each protocol handler class implements the ProtocolHandlerInterface thereby implementing the invoke(String inputXml) method. For example, here’s the basic level pseudo code for the RMIProtocolHandler and the JMSProtocolHandler:

   // Please note that exception handling in the code has    // been left out for clarity.RMIProtocolHandler implements ProtocolHandlerInterface   {      invoke (String inputXML)      {         // "registryLocation" is the RMI Registry location containing the          // remote Billing service object         obj = Naming.lookup(registryLocation);          obj.bill(inputXML);            }   }         JMSProtocolHandler implements ProtocolHandlerInterface   {      invoke (String inputXML)      {         connectionFactory = (ConnectionFactory)             JndiContext.lookup("QueueConnectionFactory");                  //"destName" is the JNDI binding name for the Billing service         dest = (Queue) jndiContext.lookup(destName);         connection = connectionFactory.createConnection();         session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);         producer = session.createProducer(dest);         message = session.createTextMessage();          message.setText(inputXML);         producer.send(messasge);      }   }

Protocol Handler Factory
This factory class has a getProtocolHandler(String protocolName) method that returns an instance of the ProtocolHandler class as a ProtocolHandlerInterface object depending on what protocol was passed to it as parameter.

The basic level pseudo code for the method is listed below:

   ProtocolHandlerInterface getProtocolHandler(String protocolName)   {      if(protocolName.equals("RMIHandler")      {         return new RMIProtocolHandler();      }   else if (protocolName.equals("JMSHandler")      {         return new JMSProtocolHandler();      }   }

When the interface and handler classes are ready, you can use them in the Web service wrapper to invoke the billing application as shown in the following pseudo code.

After the XML is created,

   {      // XML Creation      open(configFile);      String  protocol = readValueOf("");      ProtocolHandlerInterface phi =          ProtocolHanderFactory.getProtocolHandler(protocol);      phi.invoke(inputXML);   }

Having the ProtocolHandlerFactory.getProtocolHandler() method return a Handler class into a ProtocolHandlerInterface variable helps to decouple the wrapper class from the Handler implementation class?in other words, the wrapper doesn’t need to know or care whether the Handler is an RMI Handler or a JMS Handler. This also makes it easier to extend the Web service wrapper to support other protocol mechanisms. For example, you could add a JNDI Handler or a SOAP Handler in the future, if the need arises by simply creating another protocol handler class and modifying the configuration file and ProtocolHandlerFactory class.

To summarize, the action sequence to invoke the billing application is:

  1. The Web service wrapper reads the config file to get a protocol object to use.
  2. The wrapper then calls the Protocol Handler Factory to get the appropriate protocol handler.
  3. The wrapper calls the invoke(String inputXML) method on the interface, passing the XML document constructed from the calling application’s parameter values.
  4. The protocol handler class prepares the transport appropriately and calls the billing application.

Using the architecture shown in this article, a Web service wrapper can construct the required XML and can make use of the appropriate transport protocol to talk to the application. The only remaining step is to deploy your Web service wrapper to an application server as a SOAP service, and you’re ready to expose internal applications to the world as Web services.

Advantages of this Framework

  1. The Web service wrapper is extensible in terms of the variety of transport Protocols that can be supported.
  2. The Web service wrapper is extensible in terms of the number of methods as its methods are based on the cardinality of the XML Schema.
  3. This approach clearly separates the domain of application developers (such as the billing application developers) from that of Web service experts, so that they can work independently of each other.
  4. After deployment, the organization can exploit all the standard features of Web services, such as Web service security, publishing the WSDL in a UDDI registry, or using tools to generate client side stub code, etc.

Design Flexibility

 
Figure 4. Three Distinct Wrapper Parts: The first part maps schema to methods. The second prepares XML for the application, and the third invokes the actual application using a protocol handler.

The greatest advantage of this design comes from its extensibility and flexibility. Dissecting the Web service wrapper, you can see in Figure 4 that it contains three distinct pieces. The first piece is the one that maps schema to methods. The second prepares XML for the application, and the third talks to the actual application using a protocol handler.

In the future, some generic or third-party tools are likely to emerge that you you’ll be able to use to map XML schema directly to methods. When that happens, you’ll be able to plug these tools into the system easily in the place of the custom “Schema to Method Mapping” functionality described in this article. Because the pieces of the wrapper are isolated, the rest of the system will be undisturbed by such changes.

The framework design is extensible because it’s independent from the number or type of transport protocols that can be supported. New protocol handlers can be integrated with the system as required without too much effort.

Finally, because the design is based on Services Oriented Architecture (SOA) principles, you can integrate other functionality such as security into the system with ease.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist