Wednesday, February 4, 2009

Using Camel ProducerTemplate in a POJO

I am enjoying Apache Camel immensely. My productivity in terms of delivering enterprise grade services has increased dramatically. No doubt that the quality of my deliverables has also increased. All of this with no compromise to performance...

In the case of having deployed about 3 Camel based applications (containers for services) and a couple of non-Camel ESB applications, I think that one of the major ESB benefits is the de-coupling the service implementation from the transport. This of course allows the service code to be written as a POJO and with dependency injection, DAOs and a few other patterns, the resulting service has a clean focus on the business logic.

I recently had to implement a service that initialised a biometric device. Initialisation comprised of communicating several messages over a TCP connection to each biometric device. In the first instance I used Camel's ProducerTemplate to send my messages. This all worked fine and of course meets that goal of separating out the transport delivery from the business logic. However I now had a Camel dependency in my otherwise pure POJO service. This did not satisfy my design goal of ensuring that the service remained a POJO so that I could be free with my ESB choice (not that I see myself moving from Camel for any reason!).

To avoid this Camel dependency I created and used my own ProducerTemplate interface. This is merely a proxy to Camel's and only has the methods I need from my service. It looks like this:

public interface ProducerTemplate {
Object sendBody(String endpoint, Object body);

I then pass a ProducerTemplate instance and its endpoint details to the invocation of my service along with any other parameters the service needs:

void process(ProducerTemplate producerTemplate, String deviceEndpoint,
Collection fingerprints)

Note that the ProducerTemplate is passed in on each invocation of the service. This is because the template can potentially change between service invocations.

My Camel container project includes the project housing the above POJO. The container defines and instantiates its ProducerTemplate that forwards calls on to Camel's ProducerTemplate. The result is that I now have a POJO based service that interacts with other services in a non-Camel dependent manner.


James Strachan said...

Great post! Thanks for your kind works on Apache Camel.

You can use more concrete interfaces for your own ProducerTemplate instances if you like and Camel will map the parameters to the API.

You can also get camel to do the injection of the interface for you & binding it to a named endpoint using the @Produce annotation.

More details in this area in the hiding middleware section

Christopher said...

Hi James,

Thank you for the feedback. I really like the look of the @Produce annotation but if I use it, I'm dependent on Camel. @Produce is provided by Camel of course.

May be I should reconsider whether being dependent on Camel for my POJOs is an ok thing.

Kind regards,