10.5. Message Dispatcher
Overview
The message dispatcher pattern, shown in Figure 10.4, “Message Dispatcher Pattern”, is used to consume messages from a channel and then distribute them locally to performers, which are responsible for processing the messages. In a Apache Camel application, performers are usually represented by in-process endpoints, which are used to transfer messages to another section of the route.
Figure 10.4. Message Dispatcher Pattern
You can implement the message dispatcher pattern in Apache Camel using one of the following approaches:
JMS selectors
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 Apache Camel application. This provides a significant efficiency advantage.
In Apache Camel, 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 Apache Camel 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, Apache Camel 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.
JMS selectors in ActiveMQ
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.
Content-based router
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 Apache Camel, 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 Section 8.1, “Content-Based Router”.