Implementing an Event Monitor


Generally, new applications with only inward facing dependencies do not require event monitors. Event monitors are often necessary when there are external dependencies to an application where the new application's design cannot influence the interface to the external dependency. This scenario is common in enterprise application integration scenarios, as well as scenarios where there is a wide variance between architectures, such as device management where a component architecture must interact with a storage appliance.

For this chapter's sample implementation, you will start with the business process built in Chapter 8, "Exploring the Business Process Pattern," and wrapped with a business process management interface in Chapter 9, "Exploring the Asynchronous Business Process." Business processes and the manager allow clients to query the status of a particular business process while the business process works in a separate thread (and entirely separate computer).

As a Java-based client application, you can use the generic event monitor structure virtually off the shelf. Figure 10-5 illustrates the class diagram for the event monitor portion of the application. The ProductOrderImpl class is your architecture adapter that translates Java-based method requests to the Web Service implementing the order creation process (actually, this is more of a logical abstraction of the monitoring process; you must actually monitor the order creation process through the business process manager).

click to expand
Figure 10-5: Event monitor implementation class diagram

ProductOrderEventMonitor is the primary class that drives contact with the Web Service, retrieves relevant information, and funnels that information to the snapshot class for comparison of data between time slices. The information snapshot, now OrderStatusInfoSnapshot , encapsulates equality tests between the previous status and the status retrieved by the order monitor. If the status changes between monitoring cycles, the order monitor will use the Java Observable implementation class provided by the Java class libraries. The order monitor itself runs in a thread created by the application program consuming the monitor.

In terms of pattern implementation, the event monitor is relatively straightforward. Two pieces of code expose the bulk of the event monitor functionality: the invocation of the order monitor and the interaction with the order business process.

Invoking the Event Monitor

You will first tackle how to invoke the order event monitor. The next section, "Monitoring the Web Service for Status Changes," explains what occurs within the event monitor after the application spawns the event monitor thread and registers an interest in changes detected by the event monitor.

Invoking the order event monitor, in this scenario, is a simple constructor call. Once the new object instance is in hand, two interfaces on the class drive your next actions. First, the event monitor implements the Runnable interface, making the event monitor easy to dispatch into a thread that allows the event monitor to process changes independent of the primary application thread. Second, because the thread is separate from your own thread, you use the Observable interface to register an interest in any detected changes. Listing 10-1 illustrates this scenario.

Listing 10-1: Application Invocation of an Event Monitor
start example
 ProductOrderEventMonitor em =     new ProductOrderEventMonitor(orderId, 5000); em.addObserver(c); Thread t = new Thread(em); t.start(); 
end example
 

All of the interactions between the client of the event monitor and the event monitor itself take place within the Java language and, in fact, in the same Java Virtual Machine. You first create an instance of the event monitor passing in an order identifier. The order identifier originated outside of the piece of code, likely saved when you created the product order.

You then add your own instance, c , as an observer of changes that the event monitor detects. You register through the interfaces exposed by the Observable implementation that the event monitor subclasses. Next, you create a new thread and start it, allowing the event monitor to poll the product order status every five seconds independent of your own thread of control.

Upon receiving an event of interest, the event monitor calls back to your own object instance, c , through the Observer interface method that the class implements. Listing 10-2 shows a simple implementation of a callback method that fulfills the Observer contract.

Listing 10-2: Callback Method on the Observer Interface and Client to the Event Monitor
start example
 public void update(java.util.Observable observable, Object obj) {     System.out.println("Received update");     OrderStatusInfoSnapshot info = (OrderStatusInfoSnapshot)obj;     System.out.println("Status changed to: "+info.getData()); } 
end example
 

Listing 10-2 simply prints the data that the event monitor flagged as changed and returned to you through the second parameter on the update method. In practice, the contents of the second parameter are fixed by contract by the event monitor. Clients have to understand the contents of the second parameter and whether it contains a structured document or a specific Java class type.

Monitoring the Web Service for Status Changes

Once the application created the event monitor and started the thread that the event monitor runs within, it starts monitoring the target Web Service. Using the architecture adapters generated by Axis makes implementing the event monitor straightforward. In fact, ignoring the setup code, the event monitor appears to be a simple loop that queries a Java class for information. Listing 10-3 illustrates the setup and a simple algorithm for polling the target business process for the latest status of the process.

Listing 10-3: Setting Up and Monitoring a Business Process
start example
 public void run() {     try {         ProductOrderImplService service =              new ProductOrderImplServiceLocator();         ProductOrderImpl port = service.getProductOrder();         OrderStatusInfoSnapshot snapshot = new OrderStatusInfoSnapshot();         OrderStatusInfoSnapshot currentData =              new OrderStatusInfoSnapshot();         while(true){             int status = port.getStatus(orderId);             currentData.setData(status);             if(!snapshot.equals(currentData)){                 snapshot.setData(status);                 setChanged();                 notifyObservers(snapshot);             }             try {                 Thread.sleep(frequencyInMillis);             } catch (InterruptedException ie) {             }         }     } catch(Exception e){         e.printStackTrace();     } } 
end example
 

Listing 10-3 first sets up the architecture adapter, sets up an object instance of the ProductOrderImpl class generated by Axis, and then creates a baseline OrderStatusInfoSnapshot to compare new and old values. Once these object instances are set up, you go into a loop to check the target business process identified by orderId that you passed in the order identifier when you created the event monitor.

Each check of the status then determines if the current data is different from the last version of the data with the equals method on the information snapshot. If the data changed, equals returns false and you notify the observers of the change. Notice that you send a copy of the snapshot to the observers so that they will have a copy of the new data and not have to call back to the event monitor to retrieve the data. At the end of the loop, the code puts the thread to sleep for the allotted amount of time before polling the target business process again.




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