Tag Archives: Camel

Camel and JavaEE REST/SOAP server services


Camel is a great library and a common use case can be to expose as a REST (or SOAP) web service an integration route.

The main advantages are:

  • it is easy to write a client, whatever the technology you use
  • camel can be used as a backend without needing any special environment stuff (compared to JMS, file polling…)

In embedded or spring case it is quite easy to do so:

  • import camel-cxf
  • define the server (either in spring then link it to camel or directly through camel)
  • define you route using cxfrs endpoint

See Camel CxfRs for more details.

The main drawback are:

  • you need to setup the rest endpoint where it is done by the container in a JavaEE container like TomEE for instance
  • you need to use cxf (you can use Jersey or whatever)

Another drawback we can see is you can’t always stick to last versions of camel because it always uses the last version of cxf which can’t be included in JavaEE 6 servers because of the JAXRS (n+1) API changes – JAXRS 2.0 ATM – (otherwise the container is not certificated which makes it pretty useless).

Last point: it is trivial to bridge any part of an application (like a webservice) to camel.

This last statement is true thanks to camel proxy features.

Let’s work with a sample! It will be a CDI application with a rest service as input forwarding the input pojo to a camel route.

Note: of course it will use camel-cdi to be able to get injected CamelContext, endpoints…

To make it even more easy we will create an interface mapping our route contract. In our sample the input (of the rest service) is of type Input and the output of the route (which can be different from the rest service) is an int. So basically here is the interface we need:

public interface CamelDelegate {
    int foo(Input request);
}

Suppose now we have the following route:

from("direct:input")
    .routeId("cdi-route")
    .convertBodyTo(Input.class)
    .choice()
        .when(simple("${body.criteria} == 'A'"))
            .setBody(constant(1))
        .when(simple("${body.criteria} == 'B'"))
            .setBody(constant(10))
        .otherwise()
            .setBody(constant(-1));

We simply need to create a proxy on “direct:input” endpoint. It is done in one line thanks to camel API:

final CamelDelegate camelDelegate = new ProxyBuilder(getCamelContext()).endpoint("direct:input").build(CamelDelegate.class);

So finally the idea is to do it in the REST service. Since we are in CDI we can get injected the CamelContext so we have all is needed:

@Path("rest")
@Singleton @Startup @Lock(LockType.READ)
public class CamelRestService {
    @Inject
    @ContextName("my-ctx")
    private CamelContext context;

    private CamelDelegate camelDelegate;

    @PostConstruct
    void initDelegate() throws Exception {
        camelDelegate = new ProxyBuilder(context).endpoint("direct:input").build(CamelDelegate.class);
    }

    @POST
    @Path("route")
    public Output foo(final Input request) {
        return new Output(camelDelegate.foo(request));
    }

    private static interface CamelDelegate {
        int foo(Input request);
    }
}

So here we are, when you POST on /rest/foo an Input the response is computed by the camel route.

If you love annotations (and if it matches your programming model) you can even remove the route from the RouteBuilder and decorate CDI beans to use Camel Pojo consuming/producing API:

public class PojoBean {
    @Consume(uri = "direct:input-pojo", context = "my-ctx")
    public int process(final Input request) {
        switch (request.getCriteria()) {
            case "A":
                return 1;

            case "B":
                return 10;

            default:
                return -1;
        }
    }
}

In some cases Java beans are more efficient and easier to write and using Camel mapping is pretty easy, you can even use CDI events in your Camel-CDI beans so why not trying it :).

Ensure some @ApplicationScoped beans are eagerly initialized with JavaEE, camel-cdi case


In a CDI application @ApplicationScoped beans are pretty important but the fact is they are often initialized lazily.

It is often fine but not always. An example where it is wrong is using camel-cdi module and an @ApplicationScoped bean as a consumer. In this case camel needs the consumer to be active to be able to consume messages from it (note: and having a consumer which is not @ApplicationScoped doesn’t mean that much IMO). The camel-cdi extension tries to eagerly initialize them but in reality it only initializes the proxy of the bean and not the instance of the bean itself.

Continue reading