SeamFramework.orgCommunity Documentation

Chapter 71. Bridging the Gap

71.1. Event Routing
71.1.1. Routes
71.2. Routing CDI Events to JMS
71.2.1. Usage
71.3. CDI Events from JMS Messages
71.3.1. Usage

This chapter is designed to detail how to configure the CDI to JMS event bridge. Routing has two sides, sending of events to JMS destinations and translating received messages from JMS destinations back into CDI events. The sections of this chapter describe how to achieve both.

Simply sending or receiving a message over JMS involves a few players: Connection, Session, Destination, and the message itself. Surely you can inject all required resources and perform the routing yourself but that takes away from the whole reason you're using a tool in the first place!

Routing CDI events to and from JMS can be configured by defining a Route. As you would normally create an observer method for an event you can define a route to control which events get forwarded to what destination. Or conversely, what message types sent to which destinations generate CDI events.

public interface Route {
  public <D extends Destination> Route connectTo(Class<D> d, D destination);
  public Route addQualifiers(Annotation... qualifiers);

  ...
}
                

Routes allows for simple mapping of event types, complete with qualifiers, to a set of destinations. They can be configured by adding qualifiers and providing destinations they should interact with and are created from a RouteManager. Here's a simple route that forwards CDI events on to a queue:

@EventRouting public Route registerMyRoute(RouteManager routeManager)
{
   Queue myQueue = lookupQueue("/jms/MyQueue");
   return routeManager.createRoute(RouteType.EGRESS, MyEvent.class).connectTo(Queue.class, myQueue);
}
                

A RouteManager is a factory object for creating new Routes. An instance of it is injected into every @EventRouting method. Classes with methods that are decorated with EventRouting must meet a few criteria items:

These requirements exist because of when the generation of Routes must happen. There are no CDI beans active within the context. A class identified for routing will automatically be veto'd from the context.

Routes are registered by returning them from a non-bean method annotated with @EventRouting:

@EventRouting public Route myConfig()
{
   return bridge.createRoute(RouteType.INGRESS, MyEvent.class).addDestinationJndiName("/jms/MyTopic");
}
                

Forwarding CDI events to JMS is configured by creating an egress route. Let's say you wanted to forward all MyEvent events with @Bridged qualifier to the queue jms/EventQueue. Simple, register a route:

AnnotationLiteral<Bridged> BRIDGED = new AnnotationLiteral<Bridged>() {};
@EventRouting public Route registerMyEventRoute(RouteManager routeManager)
{
   return routeManager.createRoute(RouteType.EGRESS, MyEvent.class).addQualifiers(BRIDGED).addDestinationJndiName("/jms/EventQueue");
}
            

Similar to egress routes, ingress routes are defined the same way. In this case, they listen for messages on the specified destination(s) and fire events. All of the data will be type safe, assuming you have defined your routes correctly.

Similar to the above example, this creates ingress routes from the Queue jms/EventQueue and fires events based on the MyEvent objects that are carried over the wire.

AnnotationLiteral<Bridged> BRIDGED = new AnnotationLiteral<Bridged>() {};
@EventRouting public Route registerMyEventRoute(RouteManager routeManager)
{
   return routeManager.createRoute(RouteType.INGRESS, MyEvent.class).addQualifiers(BRIDGED).addDestinationJndiName("/jms/EventQueue");
}