Content Based Routing on Camel

Content based routing (CBR) is considered as a necessary technology for service integration and has been widely used in current enterprise integration software. XML is a intermediary message type which provides the mediation between diverse data structures and formats as messages passing between applications or services. CBR can be thought as a service routing mechanism that determines a service route by analysing the message content at runtime. Camel support CBR using the Content Based Router and it defines a set of DSLs to simplify the usage of this patten .

In Load Balance for existing Messaging Service sample, we have used the Content Based Router. This sample will guide you to creating your processor, registering and using it in Web Console.

Build the sample

You can build a sample as that in Load Balance for existing Messaging Service.

Create a processor

Now we create a validating processor which will check whether the message has been expired. If expired, the processor will throw a validation exception. The processor can be defined as follows:

/**
 * a processor used to validate the message
 */
public class ValidatingProcessor implements Processor {
    public void process(Exchange exchange) throws Exception {
        String body = exchange.getIn().getBody().toString();
        String[] tmp = body.split("<expiredDate>|</expiredDate>");
        if (tmp.length < 3) {
            throw new ValidationException(exchange, "The message has no expired date!");
        }
        
        SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy");
        Date expiredDate = sdf.parse(tmp[1]);
        if (new Date().after(expiredDate)) {
            throw new ValidationException(exchange, "The message has been expired!");
        }
    }
}

Register the processor

We can register the processor in the spring context in two steps.

Now you can run the sample, but it won't do the validation because we haven't configured the route to pass through the processor. You can complete it by editing the applicationContext.xml before running it, but here we want to show you how to do it through Web Console in groovy language.

Use Content Based Router to orchestrate the processors

We should execute the validation before processing the message, so we edit the route1 as follows:

from("file:src/data?noop=true").convertBodyTo(java.lang.String.class)
.processRef("validatingProcessor").to("stream:out").to("activemq:personnel.records")

Now a expired date can be specified in the message, so the validating processor can filter the expired messages. You can add message files with content:

<person user="xueqiang">
  <expiredDate>9-1-2009</expiredDate>
  <firstName>Xueqiang</firstName>
  <lastName>Mi</lastName>
  <city>Shanghai</city>
</person>

When the the message is out of date, a validation exception is thrown. To make it a little elegant, you may use doTry...doCatch...doFinally to wrap it up and specify a queue to store the invalid messages.

from("file:src/data?noop=true").convertBodyTo(java.lang.String.class)
.doTry().processRef("validatingProcessor").to("stream:out").to("activemq:personnel.records")
.doCatch(ValidationException.class).to("mock:invalid").end()

You can define custom exceptions before running, even in Web Console at runtime. However, We don't encourage to create new classes in Web Console since that involves non-treatable inner-classes for Groovy Renderer and you will find it hard to deal with through Web Console.

Simpify your test by using Web Console

To run a test, you can create a file holding the message above and throw it into the directory. However, Web Console can help to simplify your operations. Go to the endpoints page by directing your browser to: http://localhost:8080/endpoints and you can see the file://src/data?noop=true endpoint. Just open it and then select the Send to this endpoint link for inputing your message. Web Console will save your message as a file in the directory: src/data, and camel will process the message file then.