Tom Donohue Tom Donohue

Using Apache Camel Bean annotations in a Talend Route: An Example

Using Camel Bean annotations in a Talend Route. This example shows how to dynamically determine a list of endpoints for a message at runtime.

Apache Camel provides an alternative way of accessing some functionality through Java annotations. This can be a more flexible way of accessing Camel functionality, enabling more complex problems to be solved.

One example, the @RoutingSlip annotation, allows you to create a dynamic Routing Slip by writing your own custom Java method.

This allows you to dynamically decide where a message should be routed to next, perhaps based on the content of the message or some other property. Most importantly it externalises the responsibility of determining where the message should go.

This makes it more flexible than the built-in cRoutingSlip Talend component, where the recipient list is set at design-time.

Example: using Camel’s RoutingSlip annotation in a Talend Route

The following example demonstrates using the @RoutingSlip Camel annotation to develop a custom Java method that dynamically routes a message a runtime based on its content. Before doing this exercise, you should already understand the cRoutingSlip component and the principle behind the Routing Slip enterprise integration pattern.

Create a Bean in Talend Studio

In Studio, ensure the Mediation perspective is selected. Then in the navigator, create a Bean.

tos_create_bean

Import the appropriate class from Camel

In the Java code for your Bean, import the relevant class for the Annotation that you wish to use; e.g. to use the @RoutingSlip annotation, you should import:

import org.apache.camel.RoutingSlip;

Create and annotate your method

Now implement your method as required. In this example, we create a method slip, which will be annotated as a Routing Slip EIP. At runtime, a message will be passed to the method, its content will be inspected and will be routed accordingly.

The method should return a list of Camel URIs as an ArrayList. By adding the annotation @RoutingSlip, Camel knows that the method acts as a Routing Slip and does the rest.

Each Endpoint must be a valid Camel URI. In this example, we will specify JMS URIs. For this, you will need to create a JMS connection factory in the usual way by dragging one onto the Route canvas. The default name given is cJMSConnectionFactory1, so we use this in the endpoint:

cJMSConnectionFactory1:queue:queue_name

As an alternative, we could modify this URI by creating a more generically-named connection factory, using Spring configuration or otherwise.

You could also easily use any other endpoint – http:, file:, direct: – or even a SQL endpoint.

The finished class looks something like this:

The code above checks to see whether the message starts with the string "premium". If so, it routes the message to our premium queue, otherwise it is routed to the standard queue.

Add the Bean into the Route

Drag a cBean component onto the canvas with the following settings:

  • Type: New Instance
  • Bean class: beans.CustomRoutingSlipBean.class
  • Specify the method: ticked, method name: slip

This will route the message directly to the annotated slip method.

Connect to the rest of your Route

You should end up with a Route like this:

  • A JMS connection factory – to connect to ActiveMQ
  • A JMS endpoint – to receive the incoming message
  • A cBean component to route the message to the beans.CustomRoutingSlipBean class.

tos_cbean_routingslip

Now run the Route.

We run the Route, inject a test message using the ActiveMQ test console, and then watch as the message is correctly routed into the premium queue:

Observing a dynamically routed message


Why do it this way?

Coming from a Java background, my preference is to keep things clean and isolated. If we can encapsulate some reusable business logic or functionality in a Java method, all the better.

By enclosing the routing logic in a Java method in this way:

  • We can update the slip method in future – for example, to add new endpoints, or to dynamically populate the endpoints from a database query – without affecting the route directly.
  • We can expose this same logic to other Routes (as a plain Java method), without having to duplicate code.
  • We separate the routing logic from the Route.

Possible uses for this example:

  • Route a message based on its content or header value: just add more statements to your Java class as required.
  • Use information in a database to determine the destination for a message at runtime: initiate a database connection (or inject one using Spring) and query a database to find a list of endpoints for a message.
  • Process a message in various different ways depending on when it is received: e.g. route a message to a web service during the day, but at night-time place it on a JMS queue.

Try using this example as a starting point to explore other uses of Camel annotations in your projects. Let me know what you think of this tutorial in the comments section below!

Comments

What do you think? You can use Markdown in your comment.

To write code, indent each line with 4 spaces. Or, to paste a lot of code, you can put it in pastebin.com and share the link in your comment.