Event-driven services in SOA

Design an event-driven and service-oriented platform with Mule

1 2 3 Page 3
Page 3 of 3
                    

package com.jeffhanson.mule;

import org.mule.umo.*; import org.mule.extras.client.MuleClient; import org.mule.impl.endpoint.MuleEndpoint; import org.mule.config.QuickConfigurationBuilder;

import java.util.HashMap; import java.util.Map;

public class EventManagerFactory { private static HashMap instances = new HashMap();

/** * Retrieves the event manager instance for a given protocol. * * @param protocol The protocol to use. * @return EventManager The event manager instance. */ public static EventManager getInstance(String protocol) { EventManager instance = (EventManager)instances.get(protocol);

if (instance == null) { instance = new EventManagerImpl(protocol); instances.put(protocol, instance); }

return instance; }

/** * A concrete implementation for a simple event manager. */ private static class EventManagerImpl implements EventManager { private UMOManager manager = null; private QuickConfigurationBuilder builder = null; private MuleClient eventClient = null; private String protocol = null; private MuleEndpoint receiveEndpoint = null; private MuleEndpoint sendEndpoint = null;

private EventManagerImpl(String protocol) { this.protocol = protocol; }

/** * Starts this event manager. */ public void start() { try { builder = new QuickConfigurationBuilder(); manager = builder.createStartedManager(true, protocol + "tmp/events"); eventClient = new MuleClient(); receiveEndpoint = new MuleEndpoint(protocol + "tmp/events/receive"); sendEndpoint = new MuleEndpoint(protocol + "tmp/events/send"); } catch (UMOException e) { System.err.println(e); } }

/** * Stops this event manager. */ public void stop() { try { manager.stop(); } catch (UMOException e) { System.err.println(e); } }

/** * Retrieves the protocol this event manager uses. * @return */ public String getProtocol() { return protocol; }

/** * Registers a service to receive event messages. * * @param serviceName The name to associate with the service. * @param implementation Either a container reference to the service * or a fully-qualified class name * to use as the component implementation. */ public void registerService(String serviceName, String implementation) throws EventException { if (!manager.getModel().isComponentRegistered(serviceName)) { try { builder.registerComponent(implementation, serviceName, receiveEndpoint, sendEndpoint); } catch (UMOException e) { throw new EventException(e.toString()); } } }

/** * Unregisters a service from receiving event messages. * * @param serviceName The name associated with the service to unregister. */ public void unregisterService(String serviceName) throws EventException { try { builder.unregisterComponent(serviceName); } catch (UMOException e) { throw new EventException(e.toString()); } }

/** * Sends an event message synchronously to a given service. * * @param serviceName The name of the service to which the event * message is to be sent. * @param payload The content of the event message * @return Object The result, if any. * @throws EventException on error */ public Object sendSynchronousEvent(String serviceName, Object payload) throws EventException { try { if (!manager.getModel().isComponentRegistered(serviceName)) { throw new EventException("Service: " + serviceName + " is not registered."); }

String transformers = null; Map messageProperties = null; UMOMessage result = eventClient.sendDirect(serviceName, transformers, payload, messageProperties); if (result == null) { return null; } return result.getPayload(); } catch (UMOException e) { throw new EventException(e.toString()); } catch (Exception e) { throw new EventException(e.toString()); } }

/** * Sends an event message asynchronously. * * @param serviceName The name of the service to which the event * message is to be sent. * @param payload The content of the event message. * @return FutureMessageResult The result, if any * @throws EventException on error */ public FutureMessageResult sendAsynchronousEvent(String serviceName, Object payload) throws EventException { FutureMessageResult result = null;

try { if (!manager.getModel().isComponentRegistered(serviceName)) { throw new EventException("Service: " + serviceName + " is not registered."); }

String transformers = null; Map messageProperties = null; result = eventClient.sendDirectAsync(serviceName, transformers, payload, messageProperties); } catch (UMOException e) { throw new EventException(e.toString()); }

return result; } } }

The Mule framework dispatches messages by the payload's data type. The event framework can exploit this payload-based dispatching mechanism by defining generic event methods to act as event receivers in the services registered with the event manager. The following class defines one of these services with three overloaded event methods named receiveEvent():

                    

package com.jeffhanson.mule;

import java.util.Date;

public class TestService { public void receiveEvent(String eventMessage) { System.out.println("\n\nTestService.receiveEvent(String) received " + "event message: " + eventMessage + "\n\n"); }

public void receiveEvent(Integer eventMessage) { System.out.println("\n\nTestService.receiveEvent(Integer) received " +"event message: " + eventMessage + "\n\n"); }

public void receiveEvent(Date eventMessage) { System.out.println("\n\nTestService.receiveEvent(Date) received " + "event message: " + eventMessage + "\n\n"); } }

The event manager's client application sends three events to the test service to test each receiveEvent() method. The client application follows:

                    

package com.jeffhanson.mule;

import org.apache.log4j.Logger; import org.apache.log4j.Level; import org.apache.log4j.BasicConfigurator;

import java.util.Date;

public class EventClient { static Logger logger = Logger.getLogger(EventClient.class);

public static void main(String[] args) { // Set up a simple configuration that logs on the console. BasicConfigurator.configure(); logger.setLevel(Level.ALL);

try { EventManager eventManager = EventManagerFactory.getInstance("vm://"); eventManager.start();

String serviceName = TestService.class.getName(); String implementation = serviceName;

eventManager.registerService(serviceName, implementation);

Object result = eventManager.sendSynchronousEvent(serviceName, "A test message");

if (result != null) { System.out.println("Event result: " + result.toString()); }

result = eventManager.sendSynchronousEvent(serviceName, new Integer(23456));

if (result != null) { System.out.println("Event result: " + result.toString()); }

result = eventManager.sendSynchronousEvent(serviceName, new Date());

if (result != null) { System.out.println("Event result: " + result.toString()); }

eventManager.stop(); } catch (EventException e) { System.err.println(e.toString()); } } }

The Mule platform's simplifications and abstractions that the preceding framework provides enable you to send and receive synchronous and asynchronous events across layers of an architectural stack without knowing the details of the underlying event system. The use of the Factory pattern and SOA principles are exploited to facilitate a loosely-coupled and extensible design.

Summary

Designing an effective event-driven software system can grow complex when services and processes need to interact across multiple tiers and protocols. However, a service-oriented architecture built around a properly designed event-management layer using standard industry patterns can reduce or even eliminate these problems.

The Mule platform provides APIs, components, and abstractions that can be used to build a powerful, robust, event-driven system that is scalable and highly-maintainable.

Jeff Hansonhas more than 18 years of experience in the software industry. He has worked as a senior engineer for the Windows OpenDoc project and as lead architect for the Route 66 framework at Novell. He is currently the chief architect for eReinsure.com, building Web services frameworks and platforms for J2EE-based reinsurance systems. Hanson has also authored numerous articles and books including Pro JMX: Java Management Extensions (Apress, November 2003; ISBN: 1590591011) and Web Services Business Strategies and Architectures (Wrox Press, August 2002; ISBN: 1904284132).

Learn more about this topic

1 2 3 Page 3
Page 3 of 3