Chapter 12. Diverting messages and splitting message flows
In AMQ Broker, you can configure objects called diverts that enable you to transparently divert messages from one address to another address, without changing any client application logic. You can also configure a divert to forward a copy of a message to a specified forwarding address, effectively splitting the message flow.
12.1. How message diverts work
Diverts enable you to transparently divert messages routed to one address to some other address, without changing any client application logic. Think of the set of diverts on a broker server as a type of routing table for messages.
A divert can be exclusive, meaning that a message is diverted to a specified forwarding address without going to its original address.
A divert can also be non-exclusive, meaning that a message continues to go to its original address, while the broker sends a copy of the message to a specified forwarding address. Therefore, you can use non-exclusive diverts for splitting message flows. For example, you might split a message flow if you want to separately monitor every order sent to an order queue.
Multiple diverts can be configured for a single address. When an address has both exclusive and non-exclusive diverts configured, the broker processes the exclusive diverts first. If a particular message has already been diverted by an exclusive divert, the broker does not process any non-exclusive diverts for that message. In this case, the message never goes to the original address.
When a broker diverts a message, the broker assigns a new message ID and sets the message address to the new forwarding address. You can retrieve the original message ID and address values via the _AMQ_ORIG_ADDRESS
(string type) and _AMQ_ORIG_MESSAGE_ID
(long type) message properties. If you are using the Core API, use the Message.HDR_ORIGINAL_ADDRESS
and Message.HDR_ORIG_MESSAGE_ID
properties.
You can divert a message only to an address on the same broker server. If you want to divert to an address on a different server, a common solution is to first divert the message to a local store-and-forward queue. Then, set up a bridge that consumes from that queue and forwards messages to an address on a different broker. Combining diverts with bridges enables you to create a distributed network of routing connections between geographically distributed broker servers. In this way, you can create a global messaging mesh.
12.2. Configuring message diverts
To configure a divert in your broker instance, add a divert
element within the core
element of your broker.xml
configuration file.
<core> ... <divert name= > <address> </address> <forwarding-address> </forwarding-address> <filter string= > <routing-type> </routing-type> <exclusive> </exclusive> </divert> ... </core>
- divert
-
Named instance of a divert. You can add multiple
divert
elements to yourbroker.xml
configuration file, as long as each divert has a unique name. - address
- Address from which to divert messages
- forwarding-address
- Address to which to forward messages
- filter
- Optional message filter. If you configure a filter, only messages that match the filter string are diverted. If you do not specify a filter, all messages are considered a match by the divert.
- routing-type
Routing type of the diverted message. You can configure the divert to:
-
Apply the
anycast
ormulticast
routing type to a message - Strip (that is, remove) the existing routing type
- Pass through (that is, preserve) the existing routing type
-
Apply the
Control of the routing type is useful in situations where the message has its routing type already set, but you want to divert the message to an address that uses a different routing type. For example, the broker cannot route a message with the anycast
routing type to a queue that uses multicast
unless you set the routing-type
parameter of the divert to MULTICAST
. Valid values for the routing-type
parameter of a divert are ANYCAST
, MULTICAST
, PASS
, and STRIP
. The default value is STRIP
.
- exclusive
-
Specify whether the divert is exclusive (set the property to
true
) or non- exclusive (set the property tofalse
).
The following subsections show configuration examples for exclusive and non-exclusive diverts.
12.2.1. Exclusive divert example
Shown below is an example configuration for an exclusive divert. An exclusive divert diverts all matching messages from the originally-configured address to a new address. Matching messages do not get routed to the original address.
<divert name="prices-divert"> <address>priceUpdates</address> <forwarding-address>priceForwarding</forwarding-address> <filter string="office='New York'"/> <exclusive>true</exclusive> </divert>
In the preceding example, you define a divert called prices-divert
that diverts any messages sent to the address priceUpdates
to another local address, priceForwarding
. You also specify a message filter string. Only messages with the message property office
and the value New York
are diverted. All other messages are routed to their original address. Finally, you specify that the divert is exclusive.
12.2.2. Non-exclusive divert example
Shown below is an example configuration for a non-exclusive divert. In a non-exclusive divert, a message continues to go to its original address, while the broker also sends a copy of the message to a specified forwarding address. Therefore, a non-exclusive divert is a way to split a message flow.
<divert name="order-divert"> <address>orders</address> <forwarding-address>spyTopic</forwarding-address> <exclusive>false</exclusive> </divert>
In the preceding example, you define a divert called order-divert
that takes a copy of every message sent to the address orders
and sends it to a local address called spyTopic
. You also specify that the divert is non-exclusive.
Additional resources
For a detailed example that uses both exclusive and non-exclusive diverts, and a bridge to forward messages to another broker, see Divert Example (external).