My name is Zemian Deng, and I am a Senior Application Engineer working at Oracle for the Enterprise Knowledge Management product. NOTE: The views expressed on my blog and social network are my own and do not necessarily reflect the views of my employer. Zemian is a DZone MVB and is not an employee of DZone and has posted 84 posts at DZone. You can read more from them at their website. View Full User Profile

Exploring Apache Camel Core - Direct Component

09.12.2013
| 4306 views |
  • submit to reddit

Apache Camel allows you to create multiple Route's within a single CamelContext space. The directcomponent in Camel would allow you to bridge messages between these Route's. To demonstrate this, I will create few routes and pass messages between them.

package camelcoredemo;

import org.slf4j.*;
import org.apache.camel.*;
import org.apache.camel.builder.*;
import org.apache.camel.main.Main;
import java.io.*;

public class DirectDemoCamel extends Main {
    static Logger LOG = LoggerFactory.getLogger(DirectDemoCamel.class);
    public static void main(String[] args) throws Exception {
        DirectDemoCamel main = new DirectDemoCamel();
        main.enableHangupSupport();
        main.addRouteBuilder(createRouteBuilder1());
        main.addRouteBuilder(createRouteBuilder2());
        main.addRouteBuilder(createRouteBuilder3());
        main.run(args);
    }
    // The file poller route
    static RouteBuilder createRouteBuilder1() {
        return new RouteBuilder() {
            public void configure() {
                from("file://target/input?preMove=staging&move=.processed")
                .process(new Processor() {
                    public void process(Exchange msg) {
                        CamelContext camelContext = msg.getContext();
                        ProducerTemplate producer = camelContext.createProducerTemplate();
                        File file = msg.getIn().getBody(File.class);
                        boolean specialFile = file.getName().toString().endsWith("_SPECIAL.dat");
                        if (specialFile)
                            producer.send("direct:specialRoute", msg);
                        else
                            producer.send("direct:normalRoute", msg);
                    }
                });
            }
        };
    }
    // The special file processing route
    static RouteBuilder createRouteBuilder2() {
        return new RouteBuilder() {
            public void configure() {
                from("direct:specialRoute")
                .process(new Processor() {
                    public void process(Exchange msg) {
                        LOG.info("Processing special file: " + msg);
                    }
                });
            }
        };
    }
    // The normal file processing route
    static RouteBuilder createRouteBuilder3() {
        return new RouteBuilder() {
            public void configure() {
                from("direct:normalRoute")
                .process(new Processor() {
                    public void process(Exchange msg) {
                        LOG.info("Processing normal file: " + msg);
                    }
                });
            }
        };
    }
}

Here I have created 3 Route's and re-used the file component I have introduced in the past. The first Routepolls a directory, and then based on the name of the file found, we send it to either to special or normal Routefor processing. Because these Route's are separated, we need a bridge channel to pass the messages through, hence it's what the direct component does. The usage is simply use any unique name within theCamelContext, and it will serve as a direct memory queue to pass messages. You may read from or send to these queues. So as you can see, the direct component let you easily breakup a complex route workflow into smaller part.

In above demo, I have also introduced a bit of Camel core features: ProducerTemplate. Within aCamelContext you may create an instance of ProducerTemplate and it will allow you to send any messages to any endpoints dynamically at runtime. Usually you would probably want to store this producer object as member field instead of per each message processing. But for demo purpose, I will leave it as simple as that, and leave you as exercise to explore more on your own.

There are more options availabe from Direct component that you may explore. Try it out with a Route and see it for yourself.

Published at DZone with permission of Zemian Deng, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)