System Design

The basic logical flow of the system is depicted in Figure 16.1.

Figure 16.1. The SOAP order submission system's application logic.


One very straightforward way to accomplish this task would be to parse the order database document and iterate through each order element using an API such as DOM or SAX. Then for each order, use a SOAP client implementation to invoke the required SOAP operation on the target server.

This solution would meet the requirements but would require a relatively large amount of custom coding to carry it out. It would also lack flexibility when it comes time to extend or modify either the order collection process or the supplier's SOAP application.

Code Versus Data

One of the most interesting side effects of the adoption of XML as the foundation for an RPC mechanism (such as SOAP) is the blurring of the line between code and data. On one side of our application, we have a data file that contains XML elements with order information. On the other side, we have a SOAP server that is expecting another type of XML document that represents an object method invocation. Wouldn't it be nice if we could transform the static XML-as-data file into the dynamic XML-as-RPC-request messages for the SOAP server?

The good news is that we can. It will require a bit of plumbing code to make the system hang together, but using XSLT to transform our proprietary XML data into well-formed SOAP requests is no more difficult than transforming it into HTML for display to a human being.

The other obstacle that must be overcome is determining how to submit the request to the server. The server requires that the SOAP message be transmitted over a TCP/IP socket using the HTTP protocol. It also expects to be able to return the results of the call as an HTTP response to the client.

To implement this approach, we will need to develop the following:

  • A transformation script that converts the proprietary order records into SOAP client requests.

  • A utility that can “play back” these transformed requests to a SOAP server, and capture the results in a log file.

Roll-Your-Own SOAP Requests

Writing an XSLT script to transform a proprietary order element into a valid SOAP request is not much different from transforming it for presentation as an HTML document. The two pieces of information we need are the structure and content of the source and target document formats.

Listing 16.1 is a sample of an order database document (OrderDB.xml) that needs to be processed.

Listing 16.1. A Sample Order Database Document
<?xml version="1.0" encoding="UTF-8" ?>
<order_database>
 <orders>
  <order>
   <customer_name>Scott</customer_name>
   <credit_card_num>2234 2344 2233 2234</credit_card_num>
   <items>
    <item part_num="SC-938" quantity="1" />
    <item part_num="SC-938" quantity="1" />
    <item part_num="SC-938" quantity="1" />
   </items>
   <email_info>
    <from><[email protected]></from>
    <date>Sat, 14 Jul 2001 16:40:48 -0400</date>
   </email_info>
  </order>
 </orders>
</order_database>

Although this database contains only a single <order> element, in a production environment there will most likely be several orders in a single batch. Based on the ProcessOrder operation that is exposed by the SOAP server built in Chapter 15, each <order> element will need to be transformed into a single SOAP request. Creating the structure for the outbound SOAP request requires a basic understanding of how a SOAP client works.

SOAP Mechanics

Although with the latest incarnation of the SOAP specification HTTP is no longer the sole transport mechanism available to a SOAP client, it is still the most popular. Virtually every SOAP client and server implementation supports transmitting a SOAP request via a HTTP POST operation. The body of the POST request consists of a SOAP envelope that contains the types, meta-information, and arguments necessary to perform the SOAP action on the server. The server then transmits the results of the operation as the body of the HTTP response. Figure 16.2 shows the steps in a typical SOAP request that use a SOAP client library.

Figure 16.2. A typical SOAP exchange using a SOAP client library.


Notice that the SOAP client library insulates the client application from the complexity of constructing the SOAP XML message, performing the HTTP request, reading the response, and parsing out the return value. From the client's perspective, it did a normal object method invocation and received a return value.

Compare this flow with Figure 16.3, which shows how our XSLT-based SOAP client will function.

Figure 16.3. A SOAP exchange using a SOAP “playback” client.


Notice that only the processing within the SOAP client has changed. To the SOAP server, requests appear to be exactly the same as they were when the SOAP client library was making the requests. In this case, the SOAP client has no actual understanding of the SOAP protocol. It simply reads a particular XML element from a document, transmits it to an HTTP server, and then records the results in a separate log file. The logic for constructing the SOAP envelope exists outside of the SOAP client, presumably in an XSLT stylesheet.

The SOAP Envelope

SOAP requests and responses both use the SOAP envelope as the top-level container for transmitting messages back and forth. Listing 16.2 shows a skeleton SOAP request, consisting of an Envelope and a Body element.

Listing 16.2. A Skeleton SOAP Message
<SOAP-ENV:Envelope xmlns:sxml="http://namespaces.strategicxml.com/message/"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
        SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <application-specific-message/>
    </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>

The contents of the Body element depend on the specific action being requested from the SOAP server. These are the three pieces of information that determine what SOAP operation will be performed:

  • The URL where the request is sent (determines the SOAP server configuration that will process the request)

  • The contents of the SOAPAction custom HTTP header

  • The contents of the SOAP message itself

Defining the SOAP Batch Format

To convey this information, we will define our own XML document format that allows multiple SOAP requests to be grouped together for transmission. The grouping element will also contain the target URL of the SOAP server and the value to be passed in the SOAPAction HTTP header. Listing 16.3 shows the basic structure of a SOAP batch document such as we are describing.

Listing 16.3. A SOAP Batch Document
<?xml version="1.0" encoding="utf-8"?>
<soap_batch xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    URI="http://localhost/OrderHandler/OrderHandler.wsdl"
    SOAPAction="http://namespaces.strategicxml.com/action/OrderHandler.ProcessOrder">
  <SOAP-ENV:Envelope ...>
    <!-- SOAP message body goes here -->
</SOAP-ENV:Envelope>
  <SOAP-ENV:Envelope ...>
    <!-- SOAP message body goes here -->
  </SOAP-ENV:Envelope>
. . .
</soap_batch>

This document will serve as the input to our “dumb” SOAP client program.

Implementing a “Dumb” SOAP Client

These are the tasks that need to be performed by our SOAP client:

1.
Parse the incoming SOAP batch document.

2.
Preserve the SOAP URI and SOAPAction attributes of the soap_batch element.

3.
For each SOAP Envelope element, perform an HTTP POST operation to the specified URI using the SOAPAction given. Record the HTTP message results in a specified log file.

Based on the requirement that the resulting program be platform-independent, and the need for XML parsing and HTTP protocol support, Java is a natural selection as the implementation language of this utility.

After Java has been chosen as the implementation language, some thought should be given as to which XML parsing API to use. The two major options that are available are listed here:

  • DOM Document-based: Memory intensive, requires entire document be parsed before processing, provides random access to every element in the document.

  • SAX Event-based: Lightweight, document can be processed as individual elements are recognized, no document data is stored in memory.

Although each technology has its own unique strengths and weaknesses, in this case SAX would appear to be the best alternative. The iterative nature of the application (SOAP Envelope element is read, transmitted, and then discarded) lends itself naturally to an event-based API such as SAX. Also, very large documents can be processed without incurring unreasonable memory usage requirements.

Now that the overall application design has been specified, we can move on to the actual implementation.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.136.186