Using the Camel Undertow component with the WildFly Camel Subsystem



A nice addition to the WildFly Camel Subsystem 3.1.0 release is the camel-undertow component.

This is useful for WildFly because we can leverage the existing Undertow HTTP engine and enable Camel to configure HTTP Handlers into it. This gives us the capability to produce and consume HTTP messages.

Standalone Camel Undertow Vs WildFly Camel Undertow

There are some minor differences between configuring Camel Undertow for standalone Camel Vs WildFly Camel in relation to consumer endpoints.

Standalone Camel Undertow lets you do:

from("undertow://localhost:7766/foo/bar")

This configuration starts an embedded Undertow server on localhost bound to port 7766.

For WildFly Camel, this would not be allowed. Since WildFly is already running an Undertow HTTP engine, it makes sense to reuse this, rather than create a new Undertow instance. This has advantages such as being able to take advantage of WildFly’s native security mechanisms, graceful shutdown etc.

Therefore, we are restricted to consuming from the port that has been configured within the WildFly socket-binding configuration (usually 8080).

Example

Undertow consumer

An Undertow HTTP consumer would look like:

public class UndertowConsumerRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("undertow:http://localhost:8080/hello")
        .transform(simple("Hello ${in.header.name}"))
    }
}

When the Camel application is deployed, you should see a message output to the console logs like:

Add Camel endpoint: http://127.0.0.1:8080/hello

Now you can open a web browser and navigate to http://127.0.0.1:8080/hello?name=James. You should see a response output as ‘Hello James’.

Undertow producer

The producer acts as an HTTP client to make requests to a specified HTTP endpoint. Here’s an example that creates your own IP address lookup service by outputting the response from ipinfo.io.

public class UndertowProducerRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("undertow:http://localhost:8080/whatsmyip")
        .to("undertow:http://ipinfo.io/ip")
    }
}

Browse to http://127.0.0.1:8080/whatsmyip and you should see your IP address.

Undertow with the Camel REST DSL

The Undertow component can also be used with the Camel REST DSL. It’s useful to combine this with the camel-swagger-java dependency for endpoint documentation.

public class RESTRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
      restConfiguration()
        .component("undertow")
        .contextPath("camel/rest")
        .apiContextPath("/api-doc")
        .host("localhost")
        .port(8080);

      rest("/hello")
        .get("/{name}").description("GET name")
          .to("direct:get")
        .post("/{name}").description("POST name")
          .to("direct:post")
        .put("/{name}").description("PUT name")
          .to("direct:put");
        .delete("/{name}").description("DELETE name")
          .to("direct:delete");

      from("direct:get").transform(simple("GET ${header.name}"));
      from("direct:post").transform(simple("POST ${header.name}"));
      from("direct:put").transform(simple("PUT ${header.name}"));
      from("direct:delete").transform(simple("PUT ${header.name}"));
    }
}

You can then use a HTTP client such as cURL to send requests using each of the HTTP verbs that the above example can handle:

  curl -v http://localhost:8080/camel/rest/hello/James
  curl -v -X POST http://localhost:8080/camel/rest/hello/James
  curl -v -X PUT http://localhost:8080/camel/rest/hello/James
  curl -v -X DELETE http://localhost:8080/camel/rest/hello/James

To see the swagger markup you can browse to http://localhost:8080/camel/rest/api-doc.

Conclusion

Hopefully this has been a good introduction to the Camel Undertow component on the WildFly Camel Subsystem. Doubtless, it’ll continue to evolve and improve.

I’d like to see more Camel components use Undertow as their HTTP engine, as it’d enabled them to better integrate with WildFly. Stay tuned for progress in this area.