Using a Faux Implementation


The sample implementation you will use is, again, related to your Web Service implementation of the Publish/Subscribe pattern. One of the potential failures of the event service produced in Chapter 12, "Implementing the Publish/Subscribe Pattern," is its heavyweight client-side requirements for using the EventService Web Service. Recall that the client must implement a Web Service subscriber and that you deployed this subscriber using Apache Axis. This created a problem communicating with a stand-alone application because the Web Service lives in the same process as the Apache Axis engine in the examples. You could use the Connector pattern from Chapter 13, "Exploring the Physical Tiers Pattern," to connect your Web tier to your Application tier , but the heavy client installation remains for the deployment of your Subscriber Web Service.

Instead of creating a separate Web tier for hosting your Subscriber , you can use the Faux Implementation pattern to bring the behavior and interface of the Web Service paradigm directly into your Java application. There are many ways to do this; one way is to simply open a server socket and allow the Web Services environment to communicate into your server socket. You take the SOAP message off the socket and return an appropriate response to the service that is attempting to invoke an operation through your socket.

You need to consider the following on the client implementation:

  • FauxImplementationTest: The main Java program that a user instantiates from the command line

  • FauxWebServiceSubscriber: A class that listens on a socket for incoming Web Service requests

  • Subscriber: The Web Services Description Language (WSDL) interface to the Subscriber Web Service that the event service expects to call

Figure 14-5 shows the relationships between the classes. Notice that FauxWebServiceSubscriber instance implements the Runnable interface, allowing it to run within its own thread in your main application. Also, notice that there is no direct inheritance of the Subscriber interface. Because Web Services rely on SOAP and not a semantic interface to bind to, you do not actually implement an update method or the Subscriber interface. Instead, your FauxWebServiceSubscriber instance must be able to take the SOAP message sent by the EventService Web Service off of a socket and parse it appropriately.

click to expand
Figure 14-5: Sample faux implementation class structure

There is another interesting twist to the class diagram in Figure 14-5. The Subscriber is not a Java interface. The Subscriber is the WSDL containing the SOAP message definition for the message that you read off the socket connection that the event service makes with your program. In effect, FauxWebServiceSubscriber takes the architecture adapter that exchanges the information between the Web Service architecture and your Java architecture and places it inside your own Java architecture.

To understand what FauxWebServiceSubscriber must do, it is useful to look at live SOAP messages exchanged between the event service and a full subscriber. After you examine the SOAP message, you will construct your own subscriber and register it with the event service.

Using the SOAP Messages to Receive and Send

It is worth taking a quick look at sample messages exchanged between one of your original subscribers and the event service when the event service publishes a message to a subscriber. (I include the Hypertext Transfer Protocol (HTTP) headers in the exchange because you will read the information from a raw socket and the HTTP headers indicate information about the message.)

The first message, the one that your subscriber receives, contains the HTTP header, the information about the update operation ( ns1:update ), the SOAP envelope, and two parameters (the topic of the event and the data associated with the event). Listing 14-1 shows the SOAP message.

Listing 14-1: SOAP Message Received by a Subscriber
start example
 POST /axis/services/Subscriber HTTP/1.0 Content-Type: text/xml; charset=utf-8 Accept: application/soap+xml, application/dime, multipart/related, text/* User-Agent: Axis/beta3 Host: localhost Cache-Control: no-cache Pragma: no-cache SOAPAction: "" Content-Length: 572 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/    xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body>  <ns1:update soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/   xmlns:ns1="http://localhost:8080/axis/services/Subscriber">  <eventId      xsi:type="xsd:string">com.servicefoundry.books.events.ProductOrderUpdate  </eventId>  <data xsi:type="xsd:string">orderId:updated<>/data> </ns1:update> </soapenv:Body> </soapenv:Envelope> 
end example
 

The message returned from the subscriber, and the one you have to emulate after successfully reading the message sent, contains an HTTP header and an indication that this is a response to the update request ( ns1:updateResponse ). It does not contain any additional data because the return from an update operation is void. Listing 14-2 shows the response SOAP message.

Listing 14-2: Response SOAP Message from the Subscriber
start example
 HTTP/1.1 200 OK Content-Type: text/xml; charset=utf-8 Date: Fri, 17 Jan 2003 01:56:35 GMT Server: Apache Coyote/1.0 Connection: close <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/    xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body>  <ns1:updateResponse      soapenv:encodingStyle=http://schemas.xmlsoap.org/soap/encoding/      xmlns:ns1="http://localhost:8080/axis/services/Subscriber"/>  </soapenv:Body> </soapenv:Envelope> 
end example
 

There are a variety of ways to read the incoming message, parse the data, and create a response. The important part of the interaction is that you appear to be a valid Web Service target on the receiving end. To do this, you will likely go through some trial and error, just as in this example. The sample messages in Listing 14-1 and 14-2 should help.

Implementing the Subscriber

Once you have a feel for how the interactions between the event service and a subscriber take place, you can build a simple client that takes care of your Web Service interactions. A client instantiates the class shown in Listing 14-3, FauxWebServiceSubscriber , with an object reference to itself. The FauxWebServiceSubscriber instance listens on the socket, accepts a request from that socket, and subsequently returns a message to the server on the same socket. The callback parameter simply allows the client to communicate to the application that spawned the thread containing the listening code.

Listing 14-3: Listening for a SOAP Message
start example
 public class FauxWebServiceSubscriber implements Runnable {     JTextArea ivTextArea = null;     int port = 9091;     FauxWebServiceSubscriber(JTextArea textArea) {         ivTextArea = textArea;     }     FauxWebServiceSubscriber(int port, JTextArea textArea) {         ivTextArea = textArea;         this.port = port;     }     public void run() {         while (true) {             try {                 ServerSocket srv = new ServerSocket(port);                 // Wait for connection from client.                 Socket socket = srv.accept();                 String message = readMessage(socket);                 sendResponse(socket, message);                 ivTextArea.setText(message);             } catch (IOException e) {         }     } } String readMessage(Socket socket) throws IOException {    // read the SOAP message off the socket and parse }    void sendResponse(Socket socket, String message) throws IOException {       // create a response message and write it to the socket    } } 
end example
 

A Java application instantiates the FauxWebServiceSubscriber class and spawns it as a thread. Thus, Java's Thread class will execute the run method. This method waits on a server socket and accepts requests from clients . These requests defer reading the message off the socket and defer responding to the message on the same socket to helper methods. The code in these helper methods becomes quite complex; you can review it from the download package if you are interested in socket and networking code.

There are many ways you can choose to implement your lightweight client. You could go further into the Web Service world by using a lightweight HTTP server or even using Apache's SOAP processor. Each lightens the burden on your client and does things in a way that the original event service did not expect.

The raw socket connection is, perhaps, the most fragile mechanism for implementing the faux implementation. The burden for exception handling and errors falls onto you, rather than onto third-party software. In fact, by the time your subscriber is robust, you will end up implementing many of the mechanisms that already exist in Apache Axis or the Apache SOAP implementations .

Deploying the Faux Implementation

Deployment for this subscriber is much simpler than the previous subscriber examples. There are no Web Services to deploy; instead, you simply run your application, spawn the socket listener built in the previous section, and register your socket with the event service, as shown in Listing 14-4.

Listing 14-4: Registering with the Event Service
start example
 try {    Thread t =new Thread(       new FauxImplementationListener(ivTextArea));    t.start();    EventServiceService service =       new EventServiceServiceLocator();    EventService port =service.getEventService();    port.addSubscriber(topic,       "http://localhost:9091/FauxSubscriber"); }catch (Exception re){    re.printStackTrace(); } 
end example
 
Note  

Listing 14-4 has a graphical portion of the code that is not shown. That code, which is in the downloaded sample code, pops up a text area that the subscriber uses to dump messages to, as in previous chapters.




Web Service Patterns
Web Services Patterns: Java Edition
ISBN: 1590590848
EAN: 2147483647
Year: 2003
Pages: 190

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net