by Will Dinyes (Red Hat)

I've been developing in Java since the late 90s, and I can't tell you how much of that time has been spent writing and maintaining code that is incredibly uninteresting. Boiler plate code to handle exceptions, repetitive utility classes to stand up and shut down database connections, the same 8 lines of code, copy and pasted into project after project, to manage JNDI look-ups of EJBs back in the pre-CDI days.

Over time, I've been happy to see my coding become more interesting. That is, over the last few years, I've been able to spend more time writing code that advances the actual project, rather than just making sure it can find the database and manage it cleanly. Hibernate solved that. Then tools like Forge solved the project scaffolding problem. Then CDI solved coupling. What was left?

Integration of services. That's what.

I spent a lot of time writing converters and so forth to accept messages from third parties, to put them into the right bucket for processing, and then to output back to the caller, or to whatever final destination the message had. There are plenty of JSRs out there, and plenty of implementations of them, to manage, say, easily standing up a RESTful interface for collecting messages. But once the message was in my hands, I had to spend an awful lot of coding time turning, say, XML into an Object.

Then came Camel.

Camel is a rule-based routing and transport mediation engine that combines the ease of basic POJO development with the clarity of the standard enterprise integration patterns (EIPs). Can you string method calls together? Of course you can, you've been doing it since the second day of Java class back in college. But these EIPs are where Camel shines brightest. By providing implementations of common use cases, like splitters, aggregators, and content-based routers, Camel provides us with an out-of-the-box solution to even the most complicated processes.

Here's an example where we're trying to handle malformed bit of message from a user in the classic Java Exception way:

 String line = null;
 boolean read = false;
 boolean saved = false;
 int count = 0;
 while (!read && !saved && count < 5) {
 try {
      FileReader file = new FileReader("in/order.txt");
      BufferedReader reader = new BufferedReader(file);
      line = reader.readLine();
      reader.close();
      read = true;

      line = line.replaceAll(",", ";");
      FileWriter writer = new FileWriter("out/order.txt");
      writer.write(line);
      writer.flush();
      writer.close();
      saved=true;
 } catch (IOException e) {
      count++;
      if(count==5){
          throw new Exception("Not able to process file");
      }
 }

That hurt, just writing it. Look at all that overhead! And it's not exactly flexible, what if I need to read or write something other than order.txt?

Now, let's solve all that with Camel:

errorHandler(defaultErrorHandler().maximumRedeliveries(5));
 from("file:in")
 .transform(body().regexReplaceAll(",", ";"))
 .to("file:out");

Yup, that's it. It's not doing anything less than the above cumbersome code, and in fact, it's doing so much more: it's not linked to a particular file, but rather will process any files it finds in the in directory. It's not focused on just I/O errors, but on any error that might arise. The errorHandler call in this case is resetting the error handler for the entire context of this particular route, and it took me exactly one line of code.

That's what I mean when I say my job is now far more efficient. I spend my time writing code to move the project forward, to make it's services better, rather than just coding to keep the lights on. If you leverage Camel in your code today, or you'd like to, after seeing how much easier developing services will be, come take Camel Development with Red Hat Fuse (JB421), and see all the ways Camel can make you glad to be a developer again.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License