Enterprise Java

Using Camel Routes In Java EE Components

I’ve been working with Camel since a while now and I really like it’s simplicity. Using it on top of Java EE always was a little bit of a challenge and one of the recent talks I gave about how to do this and the different methods of bootstrapping Camel in Java EE actually proposes to use the WildFly-Camel Subsystem. In an ongoing series I am going to explore the different ways of doing this and provide a bunch of examples which are still missing from the talk. I’m happy to receive your feedback and requests in the comments or via @myfear on twitter.
 
 

Getting Started With Camel On WildFly 8.2 

The Wildfly-Camel Subsystem provides Apache Camel integration with the WildFly Application Server. It allows you to add Camel Routes as part of the WildFly configuration. Routes can be deployed as part of Java EE applications. Java EE components can access the Camel Core API and various Camel Component APIs. Your Enterprise Integration Solution can be architected as a combination of Java EE and Camel functionality.

Remark: Latest WildFly 9 is expected to be supported by the 3.x release of WildFly-Camel.

Getting Ready 

Download and unzip WildFly 8.2.0.Final to a folder of your choice. Download and unzip the wildfly-camel patch (2.3.0) to the wildfly folder.  Start WildFly with

bin/standalone[.bat|.sh] -c standalone-camel.xml

One of the fastest ways to get up and running is with Docker and the WildFly Camel image. This image comes bundled with WildFly 8.1 and the Camel subsystem already installed.

Defining And Using A Camel Context

The CamelContext represents a single Camel routing rulebase. You use the CamelContext in a similar way to the Spring ApplicationContext. It contains all the routes for your application. You can have as many CamelContexts as necessary, as long as they have different names. WildFly-Camel let’s you define them as a) in the standalone-camel.xml and domain.xml as part of the subsystem definition itself and b) or deploy them in asupported deployment artifact which contains a -camel-context.xml  suffixed file and c) it can be provided as together with it’s routes via a RouteBilder and the CDI integration.

A defined CamelContext can be consumed in two different ways: a) @Injected via Camel-CDI or b) accessed from the JNDI tree.

The Example Context And Route

For the following examples I use a context with an associated route which is provided via CDI and a RouteBuilder. It is an application scoped bean which is automatically started with the application start. The @ContextName annotation gives a specific name to the CamelContext.

@ApplicationScoped
@Startup
@ContextName("cdi-context")
public class HelloRouteBuilder extends RouteBuilder {

    @Inject
    HelloBean helloBean;

    @Override
    public void configure() throws Exception {
        from("direct:start").transform(body().prepend(helloBean.sayHello()).append(" user."));
    }
}

The route itself isn’t exactly challenging. It takes an empty message body from direct:start and prepends the output from a CDI bean-method “sayHello” and appends the string ” user.” to it. For reference, the complete code can be found on my GitHub account. So, all we need to find out next is, how to use this route in the various Java EE component specifications.

Using Camel From CDI

Camel supports CDI since version 2.10. Before and outside the subsystem, it needed to be bootstrapped. This is no longer necessary and you can just use a deployed or defined CamelContext in a @Named CDI bean by simply @Injecting it by name:

@Inject
    @ContextName("cdi-context")
    private CamelContext context;

Using Camel From JSF, JAX-RS and EJBs

hello_jsf

With the knowledge about how to use a CamelContext in CDI, you would assume, that it is easy to just do the same from JSF and alike. This is not true. You actually can’t inject it into either ManagedBeans or even CDI Beans which are bound to a JSF component. Plus it’s not working in EJBs. I haven’t looked into it detailed, but assume it has something to do with scopes. A reasonable workaround and in fact, a better application design is to put the complete Camel logic into a separate CDI bean and just inject this.

@Named
public class HelloCamel {

    @Inject
    @ContextName("cdi-context")
    private CamelContext context;

    private final static Logger LOGGER = Logger.getLogger(HelloCamel.class.getName());

    public String doSomeWorkFor(String name) {

        ProducerTemplate producer = context.createProducerTemplate();
        String result = producer.requestBody("direct:start", name, String.class);
        LOGGER.log(Level.INFO, result);
        return result;
    }
}

The ProducerTemplate interface allows you to send message exchanges to endpoints in a variety of different ways to make it easy to work with Camel Endpoint instances from Java code. In this particular case, it just starts the route and puts a String into the body which represents the name of the component I’m using it from.

The CDI Bean, which acts as a backing-bean for the component just uses it:

@Inject
    HelloCamel helloCamel;

    public String getName() {
        return helloCamel.doSomeWorkFor("JSF");
    }

The return String is “Hello JSF user.” Which also is written to the WildFly server log. The same approach is the best for all the other Java EE components.

Using Camel From EJBs

If you’re using EJBs as your man application component model, it is also very reasonable to just use the JNDI approach:

CamelContext camelctx = 
                (CamelContext) inicxt.lookup("java:jboss/camel/context/cdi-context");

Hawtio – A Camel Console

Another hidden gem in the subsystem is the bundling of the Hawtio console. It is a modular web console for managing your Java stuff and has an Apache Camel plugin which visualizes your contexts and routes. Remember, that it is automatically configured for security and you need to add a management user before you’re able to access it.

AwsDockerReverseProxy

Further Reading & Help

Markus Eisele

Markus is a Developer Advocate at Red Hat and focuses on JBoss Middleware. He is working with Java EE servers from different vendors since more than 14 years and talks about his favorite topics around Java EE on conferences all over the world. He has been a principle consultant and worked with different customers on all kinds of Java EE related applications and solutions. Beside that he has always been a prolific blogger, writer and tech editor for different Java EE related books. He is an active member of the German DOAG e.V. and it's representative on the iJUG e.V. As a Java Champion and former ACE Director he is well known in the community. Follow him on Twitter @myfear.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button