Book Image

Instant Apache Camel Message Routing

By : Bilgin Ibryam
Book Image

Instant Apache Camel Message Routing

By: Bilgin Ibryam

Overview of this book

With new APIs and technologies emerging every day, the need for integrating applications is greater than ever before. With the right tools, integrating applications is not hard. Apache Camel is the leading open source integration and message orchestration framework. Apache Camel, which has a variety of connectors and features numerous well-known integration patterns, has an enormous advantage over home grown integration solutions. Instant Apache Camel Message Routing helps you to get started using the Camel routing engine and Enterprise Integration Patterns. This book will show you how to create integration applications using Apache Camel. You will learn how Camel works and how to leverage the Enterprise Integration Patterns for message routing. Instant Apache Camel Message Routing is a practical and step-by-step guide to Apache Camel and integration patterns. This book will show you how Apache Camel works and how it integrates disparate systems using Enterprise Integration Patterns. The book starts with a high level overview of the Camel architecture before diving into message routing principles. Then, it introduces a number of patterns, complete with diagrams, common use cases, and examples about how to use them with Camel. The book also shows you how to test and monitor Camel applications and cope with failure scenarios.
Table of Contents (7 chapters)

Multicasting messages (Intermediate)


Multicasting is the process of delivering the same message to multiple recipients at the same time. When the list of recipients is specified dynamically it is known as a Recipient List pattern. Camel supports both static and dynamic recipients. In this tutorial, we will specify the recipients as part of the route definition, but the same options apply also for dynamic recipients.

Getting ready

The complete source code for this tutorial is located under the project camel-message-routing-examples/multicasting-messages.

How to do it...

When using a static Recipient List, we hardcode the outbound channels as part of the route definition. We can also specify a custom AggregationStrategy, options for parallel processing, and whether to continue multicasting the message if an error occurs in any of the recipients.

from("direct:start")
    .multicast(new HighestQuoteAggregator())
        .parallelProcessing().stopOnException(false)
        .to("mock:a", "mock:b", "mock:c")
    .end()
    .to("mock:result");

How it works...

When a message reaches multicast, if the parallelProcessing options are not set, by default the message will be processed sequentially from the mock:a, mock:b, and mock:c endpoints. But, notice that this is different from processing a message sequentially in a pipeline style by a Camel route. The reason is that multicast will create a copy of the original Exchange for each recipient and mock:b will not see any changes done by mock:a or mock:c. Each of the recipients will get their own copy of the original incoming Exchange. One thing to keep in mind is that Camel will not do a deep copy and if we have any objects in the message body or headers, they will be shared across all recipients and potentially mutated concurrently. For these scenarios, a good place for making proper object copies is in the onPrepareRef Processor:

.onPrepareRef(new Processor() {
    @Override
    public void process(Exchange exchange) throws Exception {
        Order body = exchange.getIn().getBody(Order.class);
        Order clone = body.deepClone();
        exchange.getIn().setBody(clone);
    }
})

Similarly to Splitter and Aggregator, we can use a custom AggregationStrategy for aggregating replies from all recipients and create the outgoing message from the multicast. The default AggregationStrategy will simply pick up the last reply from the recipients.

Also, notice that we had to specify the end of the multicast definition, otherwise all the remaining endpoints from the route would also be considered as part of the multicast. Then, there are options which are common with the Splitter pattern: executorServiceRef, for custom thread pool, stopOnException, to stop broadcasting a message to the remaining recipients in case of errors, shareUnitOfWork, and so on. Sharing a unit of work allows multicasted Exchanges to report back any failures and propagate the exceptions to the original Exchange.

There's more...

There are two other Camel patterns which allow delivery of messages to multiple recipients: Recipient List which has very similar behavior to multicast but uses expression to choose the recipients dynamically; and Wire Tap which is a much simpler version of multicast and allows sending a copy of the incoming message to one additional recipient.

Dynamic multicasting

Using the Camel Recipient List is very similar to multicast, it supports the same options such as strategyRef, parallelProcessing, stopOnException, onPrepareRef, shareUnitOfWork, streaming, and timeout, which have the same effect. The main advantage of the recipientList statement is that it allows specifying the recipients dynamically using expression:

from("direct:a")
    .recipientList(header("recipients"));

A common way for specifying the recipients is with a header value as in the preceding example. The preceding example assumes that the recipients header is set by a previous step. The expression used in recipientList has to produce a result which is a java.lang.Iterable such as java.util.Collection, java.util.Iterator, array, org.w3c.dom.NodeList, or a comma separated string value. Any other result will be treated as a single value. The values in the collection have to be either endpoints or string which will be converted to Endpoint using URI syntax.

The Recipient List has two additional options: delimiter that let us change the default delimiter (which is comma) for string values; and ignoreInvalidEndpoints that tells whether to ignore unresolved endpoints or throw an exception.

Wire Tap

Wire Tap sends a copy of the incoming message to one separate channel while keeping the final destination of the message unchanged. By default, it will create a copy of the original message and process it using a separate thread pool in a fire-and-forget fashion.

Wire Tap cannot deliver messages to more than one additional destination or use dynamic recipients. Also, it doesn't allow propagating exceptions by sharing a unit of work or stopping when an exception is encountered. It is mainly useful for monitoring, logging, and troubleshooting purposes. It is fully documented on this page http://camel.apache.org/wire-tap.html.