Implementing PublishSubscribe

Implementing Publish/Subscribe

To implement the sample, you will build an event service with the proper operations to subscribe for events and publish events. The implementation matches the structure described in the previous section. Next, you will build a subscriber and see how to register for events with the event service. Finally, you will build a simple program to publish events that the event service will forward on to the subscribers.

Implementing the Event Service

The event service implemented in this section is an extremely simple example that lacks many of the features desired for a robust, enterprise application. The subscriptions are stored in java.util.Vector instances within a java.util.Hashtable instance keyed on event topic. Subscribers register the URL that the event service can use for binding. The publish operation iterates through subscribers registered for a particular topic and delivers the event to each subscriber. Listing 12-1 is the code that implements the event service.

Listing 12-1: Event Service Implementation
start example
 public class EventService {     public EventService() {     }     public void addSubscriber(String topic, String subscriptionUrl){         Vector subscribers = null;         subscribers = (Vector)topics.get(topic);         if(subscribers==null){             subscribers = new Vector(2);             topics.put(topic, subscribers);         }         if(!subscribers.contains(subscriptionUrl)){             try {                 URL url = new URL(subscriptionUrl);                 subscribers.add(url);             } catch (MalformedURLException mue){                 mue.printStackTrace();             }         }     }     public void removeSubscriber(String topic, String subscriptionUrl) {         Vector subscribers = null;         subscribers = (Vector)topics.get(topic);         if(subscribers!=null){             subscribers.remove(subscriptionUrl);         }     }     public void publish(String topic, String data){         Vector subscribers = null;         subscribers = (Vector)topics.get(topic);         if(subscribers!=null){             for(int i=0 ; i<>subscribers.size() ; i++){                 try {                     SubscriberService service =                         new SubscriberServiceLocator(); com.servicefoundry.books.webservices.eventservice.stubs.Subscriber                           port = service.getSubscriber(                                (URL)subscribers.elementAt(i)                           );                           port.update(topic, data);                       } catch (Exception e){                           e.printStackTrace();                       }                   }               }         }         protected Hashtable topics = new Hashtable(2); } 
end example

The only part of particular interest in the event service code is the publication method. For each registered subscriber, you construct a new service locator for the subscriber, retrieve the URL from the vector of subscribers registered for a particular event, and call the update method on the subscriber. Of course, by now you realize that the port instance variable is actually an architecture adapter representing the subscriber's Web Service.

Once created, you deploy the Java implementation of the event service through Apache Axis. At this point, subscribers and publishers have access to the event service. The service is entirely generic in nature and can therefore represent any event and pass it on to the proper subscribers.

A Simple Subscriber and Its Registration with the Event Service

The event service in the previous section assumed a subscriber interface that contains an update method, as described earlier in the chapter. Listing 12-2 illustrates a simple subscriber implementation that contains the update method that the event service calls when a publisher publishes an event that matches your topic. In this case, it includes a simple main method that registers the subscriber, after it is deployed as a Web Service, with the event service.

Listing 12-2: A Simple Subscriber
start example
 public class SubscriberTest implements Subscriber {     private static String topic =         "";     private SubscriberTest() {     }     public void update(String eventId, String data) {         System.out.println("Received an event: "+eventId);         System.out.println("Data: "+data);     }     public static void main(java.lang.String[] args) {        try {            EventServiceService service =                new EventServiceServiceLocator();            EventService port = service.getEventService();            port.addSubscriber(topic,                "http://localhost:8080/axis/services/Subscriber");        } catch(Exception e){            e.printStackTrace();        }     } } 
end example

You saw in Listing 12-1 how the event service calls the update method. The main method in the subscriber is relatively interesting. In it, you use an architecture adapter to register the URL of a deployed subscriber Web Service and an event topic with the EventService Web Service. You could also register a single subscriber for multiple topics with the event service. This one-to-many relationship is important to remember for EventService implementations because including the topic identifier with a specific event helps to enable the one-to- many relationship. With the event identifier contained in the event itself, the client can create custom logic based on the event identifier.

This example code does not put any assumptions on the data passed to the subscriber. The most likely scenario is that the subscriber receives an XML data stream from the publisher. Also, remember that the contract between the publisher and subscriber for the formatted data is implicit and even somewhat fragile. One of the downsides of using an event service is the inability to generate type-safe notification mechanisms tailored to a particular event type.

Once deployed using Apache Axis, all of the necessary Web Services are available and waiting for a publisher to deliver events. Logically, you consider the subscriber Web Service as part of a client program, along with the Apache Tomcat service that Apache Axis runs in and the Apache Axis container itself. This is a heavy weight to bear simply to register for an event or two from a publisher.

Publishing an Event to the Event Service

The publisher is the only one of the three concrete implementations that does not have to be a Web Service. The simple publisher example for this chapter, shown in Listing 12-3, is a main program that creates an architecture adapter to the event service and calls the publish operation on the event service Web Service.

Listing 12-3: Publishing an Event to the Event Service
start example
 public class Publisher {     private static String topic =         "";     private static String data = "orderId:updated";     public static void main(String args[]) {         try {             EventServiceService service =                 new EventServiceServiceLocator();             EventService port = service.getEventService();             port.publish(topic, data);         } catch(Exception e){             e.printStackTrace();         }     } } 
end example

The data static instance variable contains the information that the subscriber expects upon receiving the event. There is little information passed here ”just an identifier and information about what occurred. Again, some publishers may have much more data to pass to their subscribers, and there may be cases where there is less. For example, if the publisher had information about aWeb Service that changed state, the publisher could send binding information to clients who identify the changed Web Service. In this case, subscribers could then attach directly to the changed Web Service to request more information.

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

Similar book on Amazon © 2008-2017.
If you may any questions please contact us: