The message dispatcher pattern, shown in Figure 9.4, is used to consume messages from a channel and then distribute them locally to performers, which are responsible for processing the messages. In a Fuse Mediation Router application, performers are usually represented by in-process endpoints, which are used to transfer messages to another section of the route.
You can implement the message dispatcher pattern in Fuse Mediation Router using one of the following approaches:
If your application consumes messages from a JMS queue, you can implement the message
dispatcher pattern using JMS selectors. A JMS selector is a predicate
expression involving JMS headers and JMS properties. If the selector evaluates to
true
, the JMS message is allowed to reach the consumer, and if the selector
evaluates to false
, the JMS message is blocked. In many respects, a JMS
selector is like a filter
processor, but it has the additional advantage that the filtering is implemented
inside the JMS provider. This means that a JMS selector can block messages before they are
transmitted to the Fuse Mediation Router application. This provides a significant efficiency
advantage.
In Fuse Mediation Router, you can define a JMS selector on a consumer endpoint by setting the
selector
query option on a JMS endpoint URI. For example:
from("jms:dispatcher?selector=CountryCode='US'").to("cxf:bean:replica01"); from("jms:dispatcher?selector=CountryCode='IE'").to("cxf:bean:replica02"); from("jms:dispatcher?selector=CountryCode='DE'").to("cxf:bean:replica03");
Where the predicates that appear in a selector string are based on a subset of the SQL92
conditional expression syntax (for full details, see the JMS specification). The
identifiers appearing in a selector string can refer either to JMS headers or to JMS
properties. For example, in the preceding routes, the sender sets a JMS property called
CountryCode
.
If you want to add a JMS property to a message from within your Fuse Mediation Router application, you can do so by setting a message header (either on In message or on Out messages). When reading or writing to JMS endpoints, Fuse Mediation Router maps JMS headers and JMS properties to, and from, its native message headers.
Technically, the selector strings must be URL encoded according to the
application/x-www-form-urlencoded
MIME format (see the HTML specification). In practice, the
&
(ampersand) character might cause difficulties because it is used to
delimit each query option in the URI. For more complex selector strings that might need to
embed the &
character, you can encode the strings using the
java.net.URLEncoder
utility class. For example:
from("jms:dispatcher?selector=" + java.net.URLEncoder.encode("CountryCode='US'","UTF-8")). to("cxf:bean:replica01");
Where the UTF-8 encoding must be used.
You can also define JMS selectors on ActiveMQ endpoints. For example:
from("activemq:dispatcher?selector=CountryCode='US'").to("cxf:bean:replica01"); from("activemq:dispatcher?selector=CountryCode='IE'").to("cxf:bean:replica02"); from("activemq:dispatcher?selector=CountryCode='DE'").to("cxf:bean:replica03");
For more details, see ActiveMQ: JMS Selectors and ActiveMQ Message Properties.
The essential difference between the content-based router pattern and the message dispatcher pattern is that a content-based router dispatches messages to physically separate destinations (remote endpoints), and a message dispatcher dispatches messages locally, within the same process space. In Fuse Mediation Router, the distinction between these two patterns is determined by the target endpoint. The same router logic is used to implement both a content-based router and a message dispatcher. When the target endpoint is remote, the route defines a content-based router. When the target endpoint is in-process, the route defines a message dispatcher.
For details and examples of how to use the content-based router pattern see Content-Based Router.