Gert Vanthienen's blog

Tuesday, January 13, 2009

A better CBR

Implementing a content based router in Camel is very simple. However, this also means that the routing rules are hard-coded in the Camel RouteBuilder.

Building a more dynamic solution is equally simple with the new @RecipientList annotation. You just create bean with a method that returns a (collection of) endpoints. You can off course use other annotations (like the @XPath annotation) to make your work easier.

public class RecipientListService {
@RecipientList
public List getTargets(@XPath("/po/supplier/@id") String id) {
// lookup endpoint(s) in db or config file
}
}

When using Camel inside ServiceMix, you then register this bean in your camel-context.xml file.

<beans>
<camelContext>...

<bean id="RecipientListService" class="be.anova.camel.RecipientListService">
<!-- this is plain Spring so you can inject any db, webservice, ... you need -->
</bean>
</beans>

By using plain Java and a Spring configuration file, we can write any kind of Java code or access any resource (e.g. a database or external config file) to determine the next routing step. This way, we can build a SA that can be reconfigured without redeployment.

An example use case? You can now build a generic PO handling SA. Every time a new supplier wants to receive their PO electronically, you just create a SA with the supplier-specific endpoints and add some config and you're done! You can even keep the config and the endpoints together in a single bundle if you're using ServiceMix 4 and leverage the OSGi registry to hold your configuration data.

And if you wonder what the Camel route itself looks like, it is a simple as it gets:

from("jbi:service:urn:my:service").beanRef("RecipientListService", "getTargets");

Labels: ,