© 2016 The original authors.

Provides Apache Camel integration with the WildFly Application Server.

The WildFly-Camel subsystem allows you to add Camel Routes as part of the WildFly configuration. Routes can be deployed as part of JavaEE applications. JavaEE components can access the Camel Core API and various Camel Component APIs.

Your Enterprise Integration Solution can be architected as a combination of JavaEE and Camel functionality.

1. Getting Started

This chapter takes you through the first steps of getting WildFly-Camel and provides the initial pointers to get up and running.

Download the Distribution

WildFly-Camel is distributed as

  1. WildFly Patch - wildfly-camel-patch

  2. Docker Image - wildflyext/wildfly-camel

Installing the Camel Subsystem

Simply unpack the provided patch into the a supported WildFly installation. For possible WildFly target versions, see the compatibility page.

Standalone Server

In your WildFly home directory run …​

 $ bin/standalone.sh -c standalone-camel.xml
 ...
12:20:52,997 INFO  [org.wildfly.extension.camel] (MSC service thread 1-3) Activating Camel Subsystem
12:20:53,821 INFO  [org.wildfly.extension.camel] (MSC service thread 1-5) Bound camel naming object: java:jboss/camel/CamelContextRegistry
12:20:58,211 INFO  [io.hawt.jmx.JmxTreeWatcher] (ServerService Thread Pool -- 76) Welcome to Hawtio 2.4.0
12:20:58,536 INFO  [org.wildfly.extension.camel] (ServerService Thread Pool -- 76) Add Camel endpoint: http://127.0.0.1:8080/hawtio
12:20:58,624 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
12:20:58,626 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
12:20:58,626 INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: WildFly Core 7.0.0.Final started in 11286ms

Domain Mode

Similarly, for the WildFly Domain Mode run …​

$ bin/domain.sh -c domain-camel.xml

Enable Camel Subsystem

The patch does not modify existing configuration files. Instead it comes with a number of additional configurations files that end in -camel.xml.

To add the Camel subsystem to existing configurations you can run the following command.

$ java -jar ${JBOSS_HOME}/jboss-modules.jar -mp ${JBOSS_HOME}/modules org.wildfly.extras.config --configs camel --enable
Processing config for: camel
Writing 'layers=fuse' to: .../wildfly-15.0.1.Final/modules/layers.conf
Enable camel configuration in: .../wildfly-15.0.1.Final/standalone/configuration/standalone.xml
Enable camel configuration in: .../wildfly-15.0.1.Final/standalone/configuration/standalone-full.xml
Enable camel configuration in: .../wildfly-15.0.1.Final/standalone/configuration/standalone-full-ha.xml
Enable camel configuration in: .../wildfly-15.0.1.Final/standalone/configuration/standalone-ha.xml
Enable camel configuration in: .../wildfly-15.0.1.Final/domain/configuration/domain.xml

There are currently four triggers that can be used to enable Camel for a deployment

  1. a deployment that contains a *-camel-context.xml descriptor

  2. a deployment that contains a type annotated with @CamelAware

  3. a deployment that contains a type annotated with @ContextName

  4. a deployment that contains a type annotated with @ImportResource

Docker Image

The easiest and most portable way to run WildFly-Camel is to use the wildflyext/wildfly-camel distribution.

$ docker run --rm -ti -p 8080:8080 -p 9990:9990 -e WILDFLY_MANAGEMENT_USER=admin -e WILDFLY_MANAGEMENT_PASSWORD=admin wildflyext/wildfly-camel

Maven Archetypes

To get started with writing Camel JEE applications, there are two Maven archetypes that can generate either a Camel Spring XML or Camel CDI application.

To generate a Camel CDI application, run the following from the command line.

mvn archetype:generate -DarchetypeGroupId=org.wildfly.camel.archetypes \
                       -DarchetypeArtifactId=wildfly-camel-archetype-cdi \
                       -DarchetypeVersion=12.0.0 \
                       -DgroupId=com.mycompany \
                       -DartifactId=my-camel-cdi-application

To generate a Camel Spring XML application, run the following from the command line.

mvn archetype:generate -DarchetypeGroupId=org.wildfly.camel.archetypes \
                       -DarchetypeArtifactId=wildfly-camel-archetype-spring \
                       -DarchetypeVersion=12.0.0 \
                       -DgroupId=com.mycompany \
                       -DartifactId=my-camel-spring-application

Instructions on how to build, test and run the project can be found within the generated README files.

2. Compatibility

The WildFly compatibility matrix

20.0.0.Final

12.0

18.0.1.Final

11.0, 11.1

16.0.0.Final

10.0, 10.1, 10.2, 10.3

15.0.1.Final

9.1

15.0.0.Final

9.0

14.0.1.Final

8.0

13.0.0.Final

7.0

12.0.0.Final

6.0, 6.1

11.0.0.Final

5.0, 5.1

10.1.0.Final

4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9

10.0.0.Final

4.0, 4.1, 4.2

9.0.2.Final

3.2, 3.3

9.0.1.Final

3.1

9.0.0.CR1

3.0

8.2.0.Final

2.1, 2.2, 2.3

8.1.0.Final

2.0

3. Features

This chapter provides the necessary information about WildFly-Camel features.

Camel Context Definitions

Camel Contexts can be configured in standalone-camel.xml and domain.xml as part of the subsystem definition like this

<subsystem xmlns="urn:jboss:domain:camel:1.0">
   <camelContext id="system-context-1">
     <![CDATA[
     <route>
       <from uri="direct:start"/>
       <transform>
         <simple>Hello #{body}</simple>
       </transform>
     </route>
     ]]>
   </camelContext>
</subsystem>

Camel Context Deployments

You can deploy camel contexts to WildFly with a -camel-context.xml suffix as:

  • a standalone XML file

  • a part of another supported deployment

A deployment may contain multiple -camel-context.xml files.

A deployed Camel context is CDI injectable like this

@Resource(lookup = "java:jboss/camel/context/mycontext")
CamelContext camelContext;
[discrete]
### Management Console

By default, access to management consoles is secured. Therefore, you need to setup a Management User first.

$ bin/add-user.sh

What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)

The Hawt.io console should show the camel context from subsystem configuration.

hawtio camel 01

Arquillian Test Support

The WildFly-Camel test suite uses the WildFly Arquillian managed container. This can connect to an already running WildFly instance or alternatively start up a standalone server instance when needed.

A number of test enrichers have been implemented that allow you to have these WildFly-Camel specific types injected into your Arquillian test cases.

@ArquillianResource
CamelContextFactory contextFactory;

@ArquillianResource
CamelContextRegistry contextRegistry;

4. Configuration

This chapter provides the necessary information about the Camel Subsystem and Deployment Configuration.

Camel Subsystem Configuration

The Camel Subsystem Configuration may contain static system routes. However, the system starts the route automatically.

<subsystem xmlns="urn:jboss:domain:camel:1.0">
   <camelContext id="system-context-1">
     <![CDATA[
     <route>
       <from uri="direct:start"/>
       <transform>
         <simple>Hello #{body}</simple>
       </transform>
     </route>
     ]]>
   </camelContext>
</subsystem>

Camel Deployment Configuration

If you want to modify the default configuration of your Camel deployment, you can edit either the WEB-INF/jboss-all.xml or META-INF/jboss-all.xml configuration file in your deployment.

Use a <jboss-camel> XML element within the jboss-all.xml file to control the camel configuration.

Disabling the Camel Subsystem

If you do not want to add the camel subsystem into your deployment, set the enabled="false" attribute on the jboss-camel XML element.

Example jboss-all.xml file:

<jboss umlns="urn:jboss:1.0">
  <jboss-camel xmlns="urn:jboss:jboss-camel:1.0" enabled="false"/>
</jboss>

Selecting Components

If you add nested <component> or <component-module> XML elements, then instead of adding the default list of Camel components to your deployment, only the specified components will be added to your deployment.

Example jboss-all.xml file:

<jboss umlns="urn:jboss:1.0">
  <jboss-camel xmlns="urn:jboss:jboss-camel:1.0">
    <component name="camel-ftp"/>
    <component-module name="org.apache.camel.component.rss"/>
  </jboss-camel>
</jboss>

5. JavaEE Integration

This chapter provides the necessary information about the integration points with JavaEE.

5.1. CDI

The Camel CDI component provides an auto-configuration for Apache Camel, using CDI as dependency injection framework. However, it is based on convention-over-configuration. It implements the standard camel bean integration so that you can use the Camel annotations easily in CDI beans.

For more information about CDI, refer to the cdi documentation.

The following example describes how you can consume and assosciate the Camel Context with a route.

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

    @Override
    public void configure() throws Exception {
    	from("direct:start").transform(body().prepend("Hi"));
    }
}
@Inject
@ContextName("cdi-context")
private CamelContext camelctx;

5.1.1. Importing XML DSL configuration

Camel CDI integration enables you to import existing XML DSL files via the @ImportResource annotation:

@ImportResource("camel-context.xml")
class MyBean {
}

The location of the imported file must be present on the deployment classpath. Placing the file into locations such as WEB-INF will not work. However, WEB-INF/classes will work fine.

5.2. EJB

Management support is provided through the ejb component which integrates with the EJB3 subsystem.

CamelContext camelctx = new DefaultCamelContext();
    camelctx.addRoutes(new RouteBuilder() {
        @Override
        public void configure() throws Exception {
            from("direct:start").to("ejb:java:module/HelloBean");
        }
    });

5.3. JAXB

JAXB support is provided through the Camel JAXB data format.

Camel supports unmarshalling XML data to JAXB annotated classes and marshalling from classes to XML. The following demonstrates a simple Camel route for marshalling and unmarshalling with the Camel JAXB data format class.

5.3.1. JAXB Annotated class

@XmlRootElement(name = "customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer implements Serializable {

    private String firstName;
    private String lastName;

    public Customer() {
    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

5.3.2. JAXB Class XML representation

<customer xmlns="http://org/wildfly/test/jaxb/model/Customer">
    <firstName>John</firstName>
    <lastName>Doe</lastName>
</customer>

5.3.3. Camel JAXB Unmarshalling

WildFlyCamelContext camelctx = contextFactory.createCamelContext(getClass().getClassLoader());

final JaxbDataFormat jaxb = new JaxbDataFormat();
jaxb.setContextPath("org.wildfly.camel.test.jaxb.model");

camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .unmarshal(jaxb);
    }
});
camelctx.start();

ProducerTemplate producer = camelctx.createProducerTemplate();

// Send an XML representation of the customer to the direct:start endpoint
Customer customer = producer.requestBody("direct:start", readCustomerXml(), Customer.class);
Assert.assertEquals("John", customer.getFirstName());
Assert.assertEquals("Doe", customer.getLastName());

5.3.4. Camel JAXB Marshalling

WildFlyCamelContext camelctx = contextFactory.createCamelContext();

final JaxbDataFormat jaxb = new JaxbDataFormat();
jaxb.setContextPath("org.wildfly.camel.test.jaxb.model");

camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .marshal(jaxb);
    }
});
camelctx.start();

ProducerTemplate producer = camelctx.createProducerTemplate();
Customer customer = new Customer("John", "Doe");
String customerXML = producer.requestBody("direct:start", customer, String.class);
Assert.assertEquals(readCustomerXml(), customerXML);

5.4. JAX-RS

JAX-RS support is provided by Camel CXF-RS.

5.4.1. CXF-RS Producer

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <cxf:rsClient id="cxfProducer"
                  address="http://localhost:8080/rest"
                  serviceClass="org.wildfly.camel.examples.cxf.jaxrs.GreetingService" />

    <camelContext id="cxfrs-camel-context" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="direct:start" />
            <setHeader headerName="operationName">
                <simple>greet</simple>
            </setHeader>
            <setHeader headerName="CamelCxfRsUsingHttpAPI">
                <constant>false</constant>
            </setHeader>
            <to uri="cxfrs:bean:cxfProducer" />
        </route>
    </camelContext>
</beans>

5.4.2. CXF-RS Consumer

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <cxf:rsServer id="cxfConsumer"
                  address="http://localhost:8080/rest"
                  serviceClass="org.wildfly.camel.examples.cxf.jaxrs.GreetingService" />

    <camelContext id="cxfrs-camel-context" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="cxfrs:bean:cxfConsumer" />
            <setBody>
                <constant>Hello world</constant>
            </setBody>
        </route>
    </camelContext>
</beans>

5.4.3. JAX-RS Consumer with the Camel REST DSL

The Camel REST DSL gives the capability to write Camel routes that act as JAX-RS consumers. The following RouteBuilder class demonstrates this.

@Startup
@ApplicationScoped
@ContextName("rest-camel-context")
public class RestConsumerRouteBuilder extends RouteBuilder {
  @Override
  public void configure() throws Exception {

    // Use the camel-undertow component to provide REST integration
    restConfiguration().component("undertow")
      .contextPath("/rest").port(8080).bindingMode(RestBindingMode.json);

    rest("/customer")
      // GET /rest/customer
      .get()
        .produces(MediaType.APPLICATION_JSON)
        .to("direct:getCustomers")
      // GET /rest/customer/1
      .get("/{id}")
        .produces(MediaType.APPLICATION_JSON)
        .to("direct:getCustomer")
      // POST /rest/customer
      .post()
        .type(Customer.class)
        .to("direct:createCustomer");
      // PUT /rest/customer
      .put()
        .type(Customer.class)
        .to("direct:updateCustomer");
      // DELETE /rest/customer/1
      .delete("/{id}")
        .to("direct:deleteCustomer");
  }
}

By setting the binding mode, Camel can marshal and unmarshal JSON data either by specifying a 'produces()' or 'type()' configuration step.

  • The REST DSL configuration starts with restConfiguration().component("undertow").

  • The WildFly-Camel Subsystem only supports the camel-servlet and camel-undertow components for use with the REST DSL. However, it does not work if you configure the other components.

5.4.4. Security

Refer to the JAX-RS security section.

5.4.5. Code examples on GitHub

An example Camel CXF application is available on GitHub.

5.5. JAX-WS

WebService support is provided through the CXF component which integrates with the WildFly WebServices subsystem that also uses Apache CXF.

5.5.1. JAX-WS CXF Producer

The following code example uses CXF to consume a web service which has been deployed by the WildFly web services subsystem.

JAX-WS web service

The following simple web service has a simple 'greet' method which will concatenate two string arguments together and return them.

When the WildFly web service subsystem detects classes containing JAX-WS annotations, it bootstraps a CXF endpoint. In this example the service endpoint will be located at http://hostname:port/context-root/greeting.

// Service interface
@WebService(name = "greeting")
public interface GreetingService {
    @WebMethod(operationName = "greet", action = "urn:greet")
    String greet(@WebParam(name = "message") String message, @WebParam(name = "name") String name);
}

// Service implementation
public class GreetingServiceImpl implements GreetingService{
    public String greet(String message, String name) {
        return message + " " + name ;
    }
}
Camel route configuration

This RouteBuilder configures a CXF producer endpoint which will consume the 'greeting' web service defined above. CDI in conjunction with the camel-cdi component is used to bootstrap the RouteBuilder and CamelContext.

@Startup
@ApplicationScoped
@ContextName("cxf-camel-context")
public class CxfRouteBuilder extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("direct:start")
        .to("cxf://http://localhost:8080/example-camel-cxf/greeting?serviceClass=" + GreetingService.class.getName());
    }
}

The greeting web service 'greet' requires two parameters. These can be supplied to the above route by way of a ProducerTemplate. The web service method argument values are configured by constructing an object array which is passed as the exchange body.

String message = "Hello"
String name = "Kermit"

ProducerTemplate producer = camelContext.createProducerTemplate();
Object[] serviceParams = new Object[] {message, name};
String result = producer.requestBody("direct:start", serviceParams, String.class);

5.5.2. Camel CXF JAX-WS Consumer

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cxf="http://camel.apache.org/schema/cxf"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <cxf:cxfEndpoint id="cxfConsumer"
                     address="http://localhost:8080/webservices/greeting"
                     serviceClass="org.wildfly.camel.examples.cxf.jaxws.GreetingService" />

    <camelContext id="cxfws-camel-context" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="cxf:bean:cxfConsumer" />
            <to uri="log:ws" />
        </route>
    </camelContext>

</beans>

5.5.3. Security

Refer to the JAX-WS security section.

5.5.4. Code examples on GitHub

Example JAX-WS applications are available on GitHub.

5.6. JMS

Messaging support is provided through the JMS component which integrates with the WildFly Messaging (ActiveMQ Artemis) subsystem.

Integration with other JMS implementations is possible through configuration of vendor specific resource adapters, or if not available, by using the JBoss Generic JMS resource adapter.

5.6.1. WildFly JMS configuration

You can configure the WildFly messaging subsystem through the standard WildFly XML configuration files. For example, standalone.xml or domain.xml.

For the examples, that follow you use the embedded ActiveMQ Artemis in memory instance. You first configure a new JMS queue on the messaging subsystem by adding the following XML configuration to the jms-destinations section.

<jms-queue name="WildFlyCamelQueue">
  <entry name="java:/jms/queue/WildFlyCamelQueue"/>
</jms-queue>

Alternatively you could use a CLI script to add the queue.

$ jms-queue add --queue-address=WildFlyCamelQueue --entries=queue/WildFlyCamelQueue,java:/jms/queue/WildFlyCamelQueue

Also, you can create a messaging-deployment configuration within a custom jms.xml deployment descriptor. See section 'Deployment of -jms.xml files' within the WildFly messaging subsystem documentation for more information.

5.6.2. Camel route configuration

The following JMS producer and consumer examples make use of WildFly’s embedded ActiveMQ Artemis server to publish and consume messages to and from destinations.

The examples also use CDI in conjunction with the camel-cdi component. JMS ConnectionFactory instances are injected into the Camel RouteBuilder through JNDI lookups.

JMS Producer

The DefaultJMSConnectionFactory connection factory is injected into the RouteBuilder from JNDI. Under the WildFly XML configuration, you can find the connection factory, within the messaging subsystem.

Next a timer endpoint runs every 10 seconds to send an XML payload to the WildFlyCamelQueue destination that has been configured earlier.

@Startup
@ApplicationScoped
@ContextName("jms-camel-context")
public class JmsRouteBuilder extends RouteBuilder {

  @Resource(mappedName = "java:jboss/DefaultJMSConnectionFactory")
  private ConnectionFactory connectionFactory;

  @Override
  public void configure() throws Exception {
    JmsComponent component = new JmsComponent();
    component.setConnectionFactory(connectionFactory);

    getContext().addComponent("jms", component);

    from("timer://sendJMSMessage?fixedRate=true&period=10000")
    .transform(constant("<?xml version='1.0><message><greeting>hello world</greeting></message>"))
    .to("jms:queue:WildFlyCamelQueue")
    .log("JMS Message sent");
  }
}

A log message will be output to the console each time a JMS message is added to the WildFlyCamelQueue destination. To verify that the messages really are being placed onto the queue, you can use the WildFly administration console.

jms queue browse
JMS Consumer

To consume JMS messages the Camel RouteBuilder implementation is similar to the producer example.

As before, the connection factory is discovered from JNDI, injected and set on the JMSComponent instance.

When the JMS endpoint consumes messages from the WildFlyCamelQueue destination, the content is logged to the console.

@Override
public void configure() throws Exception {
  JmsComponent component = new JmsComponent();
  component.setConnectionFactory(connectionFactory);

  getContext().addComponent("jms", component);

  from("jms:queue:WildFlyCamelQueue")
  .to("log:jms?showAll=true");
}
JMS Transactions

To enable Camel JMS routes to participate in JMS transactions, some additional configuration is required. Since camel-jms is built around spring-jms, you need to configure some Spring classes to enable them to work with WildFly’s transaction manager and connection factory. The following code example demonstrates how to use CDI to configure a transactional JMS Camel route.

The camel-jms component requires a transaction manager of type org.springframework.transaction.PlatformTransactionManager. Therefore, you start by creating a bean extending JtaTransactionManager. Note that the bean is annotated with @Named to allow the bean to be registered within the Camel bean registry. Also note that the WildFly transaction manager and user transaction instances are injected using CDI.

@Named("transactionManager")
public class CdiTransactionManager extends JtaTransactionManager {

  @Resource(mappedName = "java:/TransactionManager")
  private TransactionManager transactionManager;

  @Resource
  private UserTransaction userTransaction;

  @PostConstruct
  public void initTransactionManager() {
    setTransactionManager(transactionManager);
    setUserTransaction(userTransaction);
  }
}

Next, you need to declare the transaction policy that you want to use. Again, use the @Named annotation to make the bean available to Camel. The transaction manager is also injected so that a TransactionTemplate can be created with the desired transaction policy. PROPAGATION_REQUIRED in this instance.

@Named("PROPAGATION_REQUIRED")
public class CdiRequiredPolicy extends SpringTransactionPolicy {
  @Inject
  public CdiRequiredPolicy(CdiTransactionManager cdiTransactionManager) {
    super(new TransactionTemplate(cdiTransactionManager,
      new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)));
  }
}

Now you can configure our Camel RouteBuilder class and inject the dependencies needed for the Camel JMS component. The WildFly XA connection factory is injected together with the transaction manager that has been configured earlier.

In this example RouteBuilder, whenever any messages are consumed from queue1, they are routed to another JMS queue named queue2. Messages consumed from queue2 result in JMS transaction being rolled back using the rollback() DSL method. This results in the original message being placed onto the dead letter queue(DLQ).

@Startup
@ApplicationScoped
@ContextName("jms-camel-context")
public class JMSRouteBuilder extends RouteBuilder {

  @Resource(mappedName = "java:/JmsXA")
  private ConnectionFactory connectionFactory;

  @Inject
  CdiTransactionManager transactionManager;

  @Override
  public void configure() throws Exception {
    // Creates a JMS component which supports transactions
    JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
    getContext().addComponent("jms", jmsComponent);

    from("jms:queue:queue1")
      .transacted("PROPAGATION_REQUIRED")
      .to("jms:queue:queue2");

    // Force the transaction to roll back. The message will end up on the Wildfly 'DLQ' message queue
    from("jms:queue:queue2")
      .to("log:end")
      .rollback();
  }
Remote JMS destinations

It is possible for one WildFly instance to send messages to ActiveMQ Artemis destinations configured on another WildFly instance through remote JNDI.

Some additional WildFly configuration is required to achieve this. First an exported JMS queue is configured.

Only JNDI names bound in the java:jboss/exported namespace are considered as candidates for remote clients, so the queue is named appropriately.

You must configure the queue on the WildFly client application server andWildFly remote server.

<jms-queue name="RemoteQueue">
  <entry name="java:jboss/exported/jms/queues/RemoteQueue"/>
</jms-queue>

Before the client can connect to the remote server, user access credentials need to be configured. On the remote server run the add user utility to create a new application user within the 'guest' group. This example has a user with the name 'admin' and a password of 'secret'.

The RouteBuilder implementation is different to the previous examples. Instead of injecting the connection factory, you need to configure an InitialContext and retrieve it from JNDI ourselves.

The configureInitialContext method creates this InitialContext. Notice that you need to set a provider URL which should reference your remote WildFly instance host name and port number. This example uses the WildFly JMS http-connector, but there are alternatives documented here.

Finally the route is configured to send an XML payload every 10 seconds to the remote destination configured earlier - 'RemoteQueue'.

@Override
public void configure() throws Exception {
  Context initialContext = configureInitialContext();
  ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("java:jms/RemoteConnectionFactory");

  JmsComponent component = new JmsComponent();
  component.setConnectionFactory(connectionFactory);

  getContext().addComponent("jms", component);

  from("timer://foo?fixedRate=true&period=10000")
  .transform(constant("<?xml version='1.0><message><greeting>hello world</greeting></message>"))
  .to("jms:queue:RemoteQueue?username=admin&password=secret")
  .to("log:jms?showAll=true");
}

private Context configureInitialContext() throws NamingException {
  final Properties env = new Properties();
  env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
  env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, "http-remoting://my-remote-host:8080"));
  env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", "admin"));
  env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", "secret"));
  return new InitialContext(env);
}

5.6.3. Security

Refer to the JMS security section.

5.6.4. Code examples on GitHub

An example camel-jms application is available on GitHub.

5.7. JMX

You can provide management support through the JMX component which integrates with the WildFly JMX subsystem.

CamelContext camelctx = contextFactory.createWildflyCamelContext(getClass().getClassLoader());
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        String host = InetAddress.getLocalHost().getHostName();
        from("jmx:platform?format=raw&objectDomain=org.apache.camel&key.context=" + host + "/system-context-1&key.type=routes&key.name=\"route1\"" +
        "&monitorType=counter&observedAttribute=ExchangesTotal&granularityPeriod=500").
        to("direct:end");
    }
});
camelctx.start();

ConsumerTemplate consumer = camelctx.createConsumerTemplate();
MonitorNotification notifcation = consumer.receiveBody("direct:end", MonitorNotification.class);
Assert.assertEquals("ExchangesTotal", notifcation.getObservedAttribute());

5.8. JNDI

JNDI integration is provided by a WildFly specific CamelContext as shown below:

InitialContext inictx = new InitialContext();
CamelContextFactory factory = inictx.lookup("java:jboss/camel/CamelContextFactory");
WildFlyCamelContext camelctx = factory.createCamelContext();

From a WildFlyCamelContext you can obtain a preconfigured Naming Context

Context context = camelctx.getNamingContext();
context.bind("helloBean", new HelloBean());

which can then be referenced from Camel routes.

camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").beanRef("helloBean");
    }
});
camelctx.start();

5.9. JPA

JPA integration is provided by the Camel JPA component. You can develop Camel JPA applications by providing a persistence.xml configuration file together with some JPA annotated classes.

5.9.1. Example persistence.xml

In the following example, you can use the WildFly in-memory ExampleDS datasource which is configured within the WildFly standalone.xml configuration file.

<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

    <persistence-unit name="camel">
        <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
        <class>org.wildfly.camel.test.jpa.model.Customer</class>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.show_sql" value="true"/>
        </properties>
    </persistence-unit>

</persistence>

5.9.2. Example JPA entitiy

@Entity
@Table(name = "customer")
public class Customer implements Serializable {
    @Id
    @GeneratedValue
    private Long id;
    private String firstName;
    private String lastName;

    public Customer() {
    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Long getId() {
        return id;
    }

    public void setId(final Long id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

5.9.3. Camel JPA endpoint / route configuration

Having configured JPA, you can make use of CDI to inject an EntityManager and UserTransaction instance into your RouteBuilder class or test case:

@PersistenceContext
EntityManager em;

@Inject
UserTransaction userTransaction;

Now to configure the Camel routes and JPA endpoint:

WildFlyCamelContext camelctx = contextFactory.createCamelContext(getClass().getClassLoader());

EntityManagerFactory entityManagerFactory = em.getEntityManagerFactory();

// Configure a transaction manager
JtaTransactionManager transactionManager = new JtaTransactionManager();
transactionManager.setUserTransaction(userTransaction);
transactionManager.afterPropertiesSet();

// Configure the JPA endpoint to use the correct EntityManagerFactory and JtaTransactionManager
final JpaEndpoint jpaEndpoint = new JpaEndpoint();
jpaEndpoint.setCamelContext(camelctx);
jpaEndpoint.setEntityType(Customer.class);
jpaEndpoint.setEntityManagerFactory(entityManagerFactory);
jpaEndpoint.setTransactionManager(transactionManager);

camelctx.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
    from("direct:start")
    .to(jpaEndpoint);
}
});

camelctx.start();

Finally, you can send a 'Customer' entity to the 'direct:start' endpoint and then query the ExampleDS datasource to verify that a record was saved.

Customer customer = new Customer("John", "Doe");
ProducerTemplate producer = camelctx.createProducerTemplate();
producer.sendBody("direct:start", customer);

// Query the in memory database customer table to verify that a record was saved
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Long> query = criteriaBuilder.createQuery(Long.class);
query.select(criteriaBuilder.count(query.from(Customer.class)));

long recordCount = em.createQuery(query).getSingleResult();

Assert.assertEquals(1L, recordCount);

6. Camel Components

This chapter provides information about supported camel components.

6.1. camel-activemq

Camel ActiveMQ integration is provided by the activemq component.

The component can be configured to work with an embedded or external broker. For Wildfly / EAP container managed connection pools and XA-Transaction support, the ActiveMQ Resource Adapter can be configured into the container configuration file.

6.1.1. WildFly ActiveMQ resource adapter configuration

Download the ActiveMQ resource adapter rar file. The following steps outline how to configure the ActiveMQ resource adapter.

  1. Stop your WildFly instance.

  2. Download the resource adapter and copy to the relevant WildFly deployment directory. For standalone mode:

    cp activemq-rar-5.11.1.rar ${JBOSS_HOME}/standalone/deployments/activemq-rar.rar
  3. Configure the WildFly resource adapters subsystem for the ActiveMQ adapter.

<subsystem xmlns="urn:jboss:domain:resource-adapters:2.0">
     <resource-adapters>
         <resource-adapter id="activemq-rar.rar">
             <archive>
                 activemq-rar.rar
             </archive>
             <transaction-support>XATransaction</transaction-support>
             <config-property name="UseInboundSession">
                 false
             </config-property>
             <config-property name="Password">
                 defaultPassword
             </config-property>
             <config-property name="UserName">
                 defaultUser
             </config-property>
             <config-property name="ServerUrl">
                 tcp://localhost:61616?jms.rmIdFromConnectionId=true
             </config-property>
             <connection-definitions>
                 <connection-definition class-name="org.apache.activemq.ra.ActiveMQManagedConnectionFactory" jndi-name="java:/ActiveMQConnectionFactory" enabled="true" pool-name="ConnectionFactory">
                     <xa-pool>
                         <min-pool-size>1</min-pool-size>
                         <max-pool-size>20</max-pool-size>
                         <prefill>false</prefill>
                         <is-same-rm-override>false</is-same-rm-override>
                     </xa-pool>
                 </connection-definition>
             </connection-definitions>
             <admin-objects>
                 <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/queue/HELLOWORLDMDBQueue" use-java-context="true" pool-name="HELLOWORLDMDBQueue">
                     <config-property name="PhysicalName">
                         HELLOWORLDMDBQueue
                     </config-property>
                 </admin-object>
                 <admin-object class-name="org.apache.activemq.command.ActiveMQTopic" jndi-name="java:/topic/HELLOWORLDMDBTopic" use-java-context="true" pool-name="HELLOWORLDMDBTopic">
                     <config-property name="PhysicalName">
                         HELLOWORLDMDBTopic
                     </config-property>
                 </admin-object>
             </admin-objects>
         </resource-adapter>
     </resource-adapters>
 </subsystem>

If your resource adapter archive filename differs from activemq-rar.rar, you must change the content of the archive element in the preceding configuration to match the name of your archive file.

The values of the UserName and Password configuration properties must be chosen to match the credentials of a valid user in the external broker.

You might need to change the value of the ServerUrl configuration property to match the actual hostname and port exposed by the external broker.

4) Start WildFly. If everything is configured correctly, you should see a message within the WildFly server.log like.

13:16:08,412 INFO  [org.jboss.as.connector.deployment] (MSC service thread 1-5) JBAS010406: Registered connection factory java:/AMQConnectionFactory`

6.1.2. Camel route configuration

The following ActiveMQ producer and consumer examples make use of the ActiveMQ embedded broker and the 'vm' transport (thus avoiding the need for an external ActiveMQ broker).

The examples use CDI in conjunction with the camel-cdi component. JMS ConnectionFactory instances are injected into the Camel RouteBuilder through JNDI lookups.

ActiveMQ Producer
@Startup
@ApplicationScoped
@ContextName("activemq-camel-context")
public class ActiveMQRouteBuilder extends RouteBuilder {

  @Override
  public void configure() throws Exception {
    from("timer://sendJMSMessage?fixedRate=true&period=10000")
    .transform(constant("<?xml version='1.0><message><greeting>hello world</greeting></message>"))
    .to("activemq:queue:WildFlyCamelQueue?brokerURL=vm://localhost")
    .log("JMS Message sent");
  }
}

A log message will be output to the console each time a message is added to the WildFlyCamelQueue destination. To verify that the messages really are being placed onto the queue, you can use the ../features/hawtio.md[Hawtio console,window=_blank] provided by the WildFly-Camel subsystem.

activemq queue browse
ActiveMQ Consumer

To consume ActiveMQ messages the Camel RouteBuilder implementation is similar to the producer example.

When the ActiveMQ endpoint consumes messages from the WildFlyCamelQueue destination, the content is logged to the console.

@Override
public void configure() throws Exception {
  from("activemq:queue:WildFlyCamelQueue?brokerURL=vm://localhost")
  .to("log:jms?showAll=true");
}
ActiveMQ Transactions
ActiveMQ Resource Adapter Configuration

The ActiveMQ resource adapter is required to leverage XA transaction support, connection pooling etc.

The XML snippet below shows how the resource adapter is configured within the WildFly server XML configuration. Notice that the ServerURL is set to use an embedded broker. The connection factory is bound to the JNDI name java:/ActiveMQConnectionFactory. This will be looked up in the RouteBuilder example that follows.

Finally, two queues are configured named 'queue1' and 'queue2'.

<subsystem xmlns="urn:jboss:domain:resource-adapters:2.0">
  <resource-adapters>
    <resource-adapter id="activemq-rar.rar">
      ...
      <admin-objects>
        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/queue/queue1" use-java-context="true" pool-name="queue1pool">
          <config-property name="PhysicalName">queue1</config-property>
        </admin-object>
        <admin-object class-name="org.apache.activemq.command.ActiveMQQueue" jndi-name="java:/queue/queue2" use-java-context="true" pool-name="queue2pool">
          <config-property name="PhysicalName">queue2</config-property>
        </admin-object>
      </admin-objects>
    </resource-adapter>
  </resource-adapters>
</subsystem>
Transaction Manager

The camel-activemq component requires a transaction manager of type org.springframework.transaction.PlatformTransactionManager. Therefore, you can start by creating a bean extending JtaTransactionManager which fulfills this requirement. Note that the bean is annotated with @Named to allow the bean to be registered within the Camel bean registry. Also note that the WildFly transaction manager and user transaction instances are injected using CDI.

@Named("transactionManager")
public class CdiTransactionManager extends JtaTransactionManager {

  @Resource(mappedName = "java:/TransactionManager")
  private TransactionManager transactionManager;

  @Resource
  private UserTransaction userTransaction;

  @PostConstruct
  public void initTransactionManager() {
    setTransactionManager(transactionManager);
    setUserTransaction(userTransaction);
  }
}
Transaction Policy

Next you need to declare the transaction policy that you want to use. Again, use the @Named annotation to make the bean available to Camel. The transaction manager is also injected so that a TransactionTemplate can be created with the desired transaction policy. PROPAGATION_REQUIRED in this instance.

@Named("PROPAGATION_REQUIRED")
public class CdiRequiredPolicy extends SpringTransactionPolicy {
  @Inject
  public CdiRequiredPolicy(CdiTransactionManager cdiTransactionManager) {
    super(new TransactionTemplate(cdiTransactionManager,
      new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED)));
  }
}
Route Builder

Now you can configure the Camel RouteBuilder class and inject the dependencies needed for the Camel ActiveMQ component. The ActiveMQ connection factory that you configured on the resource adapter configuration is injected together with the transaction manager you configured earlier.

In this example RouteBuilder, whenever any messages are consumed from queue1, they are routed to another JMS queue named queue2. Messages consumed from queue2 result in JMS transaction being rolled back using the rollback() DSL method. This results in the original message being placed onto the dead letter queue(DLQ).

@Startup
@ApplicationScoped
@ContextName("activemq-camel-context")
public class ActiveMQRouteBuilder extends RouteBuilder {

  @Resource(mappedName = "java:/ActiveMQConnectionFactory")
  private ConnectionFactory connectionFactory;

  @Inject
  private CdiTransactionManager transactionManager;

  @Override
  public void configure() throws Exception {
    ActiveMQComponent activeMQComponent = ActiveMQComponent.activeMQComponent();
    activeMQComponent.setTransacted(false);
    activeMQComponent.setConnectionFactory(connectionFactory);
    activeMQComponent.setTransactionManager(transactionManager);

    getContext().addComponent("activemq", activeMQComponent);

      errorHandler(deadLetterChannel("activemq:queue:ActiveMQ.DLQ")
      .useOriginalMessage()
      .maximumRedeliveries(0)
      .redeliveryDelay(1000));

    from("activemq:queue:queue1F
      .transacted("PROPAGATION_REQUIRED")
      .to("activemq:queue:queue2");

    from("activemq:queue:queue2")
      .to("log:end")
      .rollback();
  }
}

6.1.3. Security

Refer to the JMS security section.

6.1.4. Code examples on GitHub

An example camel-activemq application is available on GitHub.

6.2. camel-ahc

The ahc component provides HTTP based endpoints for consuming external HTTP resources (as a client to call external servers using HTTP). The component uses the Async Http Client library.

6.3. camel-ahc-ws

The ahc-ws component provides Websocket based endpoints for a client communicating with external servers over Websocket. The component uses the ahc component that in turn uses the Async Http Client library.

6.4. camel-amqp

The amqp component supports the AMQP 1.0 protocol using the JMS client of the Qpid project.

6.5. camel-apns

The apns component is used for sending notifications to iOS devices. The apns components use javapns library.

6.6. camel-asterisk

The asterisk component allows you to interface with an Asterisk PBX Server using asterisk-java.

6.7. camel-atmosphere-websocket

The atmosphere-websocket component provides Websocket based endpoints for a servlet communicating with external clients over Websocket (as a servlet accepting websocket connections from external clients).

The component leverages the Atmosphere websocket library.

6.8. camel-atom

Atom feed consumption in Camel is provided by the atom component.

The following example configures an Atom endpoint to consume the recent activity GitHub feed of user 'wildflyext'. The raw content of each feed entry is then written out as a file within directory 'feed/entries'.

CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("atom://https://github.com/wildflyext.atom?splitEntries=true")
        .process(new Processor() {
            @Override
            public void process(final Exchange exchange) throws Exception {
                Entry entry = exchange.getIn().getBody(Entry.class);
                exchange.getOut().setBody(entry.getContent());
            }
        })
        .to("file:///feed/entries/");
    }
});

6.9. camel-atomix

The atomix-map component allows you to work with Atomix’s Distributed Map collection.

The atomix-messaging component allows you to work with Atomix’s Group Messaging.

The atomix-multimap component allows you to work with Atomix’s Distributed MultiMap collection.

The atomix-queue component allows you to work with Atomix’s Distributed Queues.

The atomix-set component allows you to work with Atomix’s Distributed Set collection.

The atomix-value component allows you to work with Atomix’s Distributed Value.

6.10. camel-avro

The avro component provides a dataformat for avro, which allows serialization and deserialization of messages using Apache Avro’s binary dataformat. Moreover, it provides support for Apache Avro’s rpc, by providing producers and consumers endpoint for using avro over netty or http.

6.11. camel-aws-cw

The AWS CloudWatch component allows messages to be sent to an Amazon CloudWatch metrics.

6.12. camel-aws-ddb

The AWS DynamoDB component supports supports storing and retrieving data from/to Amazon’s DynamoDB service.

6.13. camel-aws-ddbstream

The AWS DynamoDB Stream component supports receiving messages from Amazon DynamoDB Stream service.

6.14. camel-aws-ec2

The AWS EC2 component supports create, run, start, stop and terminate AWS EC2 instances.

6.15. camel-aws-kinesis

The AWS Kinesis component supports receiving messages from and sending messages to Amazon Kinesis service.

6.16. camel-aws-s3

The AWS S3 component supports storing and retrieving objects from/to Amazon’s S3 service.

6.17. camel-aws-sdb

The AWS SDB component storing and retrieving data from/to Amazon’s SDB service.

6.18. camel-aws-ses

The AWS Simple Email Service component supports sending emails with from Amazon’s SES service.

6.19. camel-aws-sns

The AWS SNS component allows messages to be sent to an Amazon Simple Notification Topic.

6.20. camel-aws-sqs

The AWS SQS component sending and receiving messages to Amazon’s SQS service.

6.21. camel-aws-swf

The AWS Simple Workflow component supports managing workflows from Amazon’s Simple Workflow service.

6.22. camel-azure

The azure-blob component supports storing and retrieving the blobs to/from Azure Storage Blob service.

The azure-queue component supports storing and retrieving the messages to/from Azure Storage Queue service.

6.23. camel-beanstalk

The beanstalk component provides a Camel component for job retrieval and post-processing of Beanstalk jobs.

6.24. camel-bean-validator

The bean-validator component provides support for message body validation using the Java Bean Validation API.

6.25. camel-bindy

The goal of bindy is to allow the parsing/binding of non-structured data to/from Java Beans that have binding mappings defined with annotations.

Here we have a annotated domain model class

@CsvRecord(separator = ",")
public class Customer {

    @DataField(pos = 1)
    private String firstName;

    @DataField(pos = 2)
    private String lastName;

    ...
}

We can use the BindyCsvDataFormat data format unmarshall CSV data like John,Doe to the domain model.

camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .unmarshal(new BindyCsvDataFormat(Customer.class))
        .to("mock:result");
    }
});
camelctx.start();

6.26. camel-box

The Box component provides access to all of the box.com APIs.

6.27. camel-braintree

The braintree component provides access to Braintree Payments trough through their Java SDK.

BraintreeComponent component = new BraintreeComponent(camelctx);
component.setConfiguration(configuration);
camelctx.addComponent("braintree", component);

camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("timer://braintree?repeatCount=1")
            .to("braintree:clientToken/generate")
            .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    latch.countDown();
                }})
            .to("mock:result");
    }
});

6.28. camel-caffeine

The caffeine-cache component enables you to perform caching operations using The simple cache from Caffeine.

The caffeine-loadcache component enables you to perform caching operations using The Load cache from Caffeine.

6.29. camel-cassandra

The cassandra component is an open source NoSQL database designed to handle large amounts on commodity hardware. Like Amazon’s DynamoDB, Cassandra has a peer-to-peer and master-less architecture to avoid single point of failure and guarantees high availability. Like Google’s BigTable, Cassandra data is structured using column families which can be accessed through the Thrift RPC API or a SQL-like API called CQL.

6.30. camel-cdi

Covered by CDI.

6.30.1. Camel CDI for EAR deployments on WildFly-Camel

Camel CDI EAR deployments on WildFly-Camel have some differences in class and resource loading behaviour, compared to standard WAR or JAR deployments.

WildFly bootstraps Weld using the EAR deployment ClassLoader. WildFly also mandates that only a single CDI extension is created and shared by all EAR sub-deployments.

This results in the 'Auto-configured' CDI Camel Context using the EAR deployment ClassLoader to dynamically load classes and resources. By default, this ClassLoader does not have access to resources within EAR sub-deployments.

For EAR deployments, it is recommended that usage of the 'Auto-configured' CDI Camel Context is avoided and that RouteBuilder classes are annotated with @ContextName, or that a CamelContext is created via the @ImportResource annotation or through CDI producer methods and fields. This helps WildFly-Camel to determine the correct ClassLoader to use with Camel.

6.31. camel-chunk

The chunk component allows for processing a message using a Chunk template.

6.32. camel-cm-sms

The cm-sms component enables you to integrate with the CM SMS API.

6.33. camel-cmis

The cmis component uses the Apache Chemistry client API and allows you to add / read nodes to / from a CMIS compliant content repositories.

6.34. camel-coap

The coap component enables you work with the CoAP protocol. The protocol is designed for machine-to-machine (M2M) applications and is suitable for IoT devices.

6.35. camel-consul

The consul component allows you to work with Consul a distributed highly available datacenter-aware service discovery and configuration system.

6.36. camel-couchbase

The couchbase component allows you to treat CouchBase instances as a producer or consumer of messages.

6.37. camel-couchdb

The couchdb component enables you to treat CouchDB instances as a producer or consumer of messages.

6.38. camel-crypto

Secure message exchanges in camel is provided by the crypto component.

With Camel cryptographic endpoints and Java’s Cryptographic extension it is easy to create Digital Signatures for Exchanges. Camel provides a pair of flexible endpoints which get used in concert to create a signature for an exchange in one part of the exchange’s workflow and then verify the signature in a later part of the workflow.

Begin by loading a keystore for binding to JNDI so that camel can discover it from its bean registry.

KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = getClass().getResourceAsStream("/my-keystore.ks");
keystore.load(in, "my-keystore-password".toCharArray());

Certificate cert = keystore.getCertificate("my-certificate-alias");

KeyStoreParameters keystoreParameters = new KeyStoreParameters();
keystoreParameters.setPassword("my-keystore-password");
keystoreParameters.setResource("./my-keystore.ks");

InitialContext initialContext = new InitialContext();
initialContext.bind("signatureParams", keystoreParameters);
initialContext.bind("keystore", keystore);
initialContext.bind("myPublicKey", cert.getPublicKey());
initialContext.bind("myCert", cert);
initialContext.bind("myPrivateKey", keystore.getKey("my-certificate-alias", "my-keystore-password".toCharArray()));

Finally, a Camel route that signs and verifies an exchange.

CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
      from("direct:sign")
      .to("crypto:sign://basic?privateKey=#myPrivateKey")
      .to("direct:verify");
      from("direct:verify")
      .to("crypto:verify://basic?publicKey=#myPublicKey")
      .to("mock:result");
    }
});

6.39. camel-crypto-cms

The Crypto CMS component supports the following parts of this standard:

  • Content Type "Enveloped Data" with Key Transport (asymmetric key),

  • Content Type "Signed Data".

You can create CMS Enveloped Data instances, decrypt CMS Enveloped Data instances, create CMS Signed Data instances, and validate CMS Signed Data instances.

6.40. camel-cxf

Covered by JAX-RS and JAX-WS.

6.40.1. CXF consumers on WildFly

The configuration of camel-cxf consumers on WildFly is different to that of standalone Camel. Producer endpoints work as per normal.

On WildFly, camel-cxf consumers leverage the default Undertow HTTP server provided by the container. The server is defined within the undertow subsystem configuration. Here’s an excerpt of the default configuration from standalone.xml:

<subsystem xmlns="urn:jboss:domain:undertow:4.0">
    <buffer-cache name="default" />
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" />
        <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true" />
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content" />
            <filter-ref name="server-header" />
            <filter-ref name="x-powered-by-header" />
            <http-invoker security-realm="ApplicationRealm" />
        </host>
    </server>
</subsystem>

In this instance, Undertow is configured to listen on interfaces / ports specified by the http and https socket-binding. By default this is port 8080 for http and 8443 for https.

For example, if you configure an endpoint consumer using different host or port combinations, a warning will appear within the server log file. For example the following host & port configurations would be ignored:

<cxf:rsServer id="cxfRsConsumer"
              address="http://somehost:1234/path/to/resource"
              serviceClass="org.example.ServiceClass" />
<cxf:cxfEndpoint id="cxfWsConsumer"
                 address="http://somehost:1234/path/to/resource"
                 serviceClass="org.example.ServiceClass" />
[org.wildfly.extension.camel] (pool-2-thread-1) Ignoring configured host: http://somehost:1234/path/to/resource

However, the consumer is still available on the default host & port localhost:8080 or localhost:8443.

Applications which use camel-cxf consumers must be packaged as a WAR. In previous WildFly-Camel releases, other types of archive such as JAR were permitted, but this is no longer supported.

Configuring alternative ports

If alternative ports are to be accepted, then these must be configured via the WildFly subsystem configuration. This is explained in the server documentation:

Configuring security with Elytron

WildFly-Camel supports securing camel-cxf consumer endpoints with the Elytron security framework.

Configuring a security domain

To secure a WildFly-Camel application with Elytron, an application security domain needs to be referenced within WEB-INF/jboss-web.xml of your WAR deployment:

<jboss-web>
  <security-domain>my-application-security-domain</security-domain>
</jboss-web>

The <security-domain> configuration references the name of an <application-security-domain> defined by the Undertow subsystem. For example, the Undertow subsystem <application-security-domain> is configured within the WildFly server standalone.xml configuration file as follows:

<subsystem xmlns="urn:jboss:domain:undertow:6.0">
    ...
    <application-security-domains>
        <application-security-domain name="my-application-security-domain" http-authentication-factory="application-http-authentication"/>
    </application-security-domains>
</subsystem>

The <http-authentication-factory> application-http-authentication is defined within the Elytron subsystem. application-http-authentication is available by default in both the standalone.xml and standalone-full.xml server configuration files. For example:

<subsystem xmlns="urn:wildfly:elytron:1.2">
    ...
    <http>
        ...
        <http-authentication-factory name="application-http-authentication" http-server-mechanism-factory="global" security-domain="ApplicationDomain">
            <mechanism-configuration>
                <mechanism mechanism-name="BASIC">
                    <mechanism-realm realm-name="Application Realm" />
                </mechanism>
                <mechanism mechanism-name="FORM" />
            </mechanism-configuration>
        </http-authentication-factory>
        <provider-http-server-mechanism-factory name="global" />
    </http>
    ...
</subsystem>

The <http-authentication-factory> named application-http-authentication, holds a reference to a Elytron security domain called ApplicationDomain.

For more information on how to configure the Elytron subsystem, refer to the Elytron documentation.

Configuring security constraints, authentication methods and security roles

Security constraints, authentication methods and security roles for camel-cxf consumer endpoints can be configured within your WAR deployment WEB-INF/web.xml. For example, to configure BASIC Authentication:

<web-app>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>secure</web-resource-name>
      <url-pattern>/webservices/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>my-role</role-name>
    </auth-constraint>
  </security-constraint>
  <security-role>
    <description>The role that is required to log in to /webservices/*</description>
    <role-name>my-role</role-name>
  </security-role>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>my-realm</realm-name>
  </login-config>
</web-app>

Note that the <url-pattern> defined by the Servlet Specification is relative to the context path of the web application. If your application is packaged as my-app.war, WildFly will make it accessible under the context path /my-app and the <url-patternpattern> /webservices/* will be applied to paths relative to /my-app.

For example, requests against http://my-server/my-app/webservices/my-endpoint will match the /webservices/* pattern, while http://my-server/webservices/my-endpoint will not match.

This is important because WildFly-Camel allows the creation of camel-cxf endpoint consumers whose base path is outside of the host web application context path. For example, it is possible to create a camel-cxf consumer for http://my-server/webservices/my-endpoint inside my-app.war.

In order to define security constraints for such out-of-context endpoints, WildFly-Camel supports a custom, non-standard <url-pattern> convention where prefixing the pattern with three forward slashes /// will be interpreted as absolute to server host name. For example, to secure http://my-server/webservices/my-endpoint inside my-app.war, you would add the following configuration to web.xml:

<web-app>
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>secure</web-resource-name>
      <url-pattern>///webservices/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>my-role</role-name>
    </auth-constraint>
  </security-constraint>
  <security-role>
    <description>The role that is required to log in to /webservices/*</description>
    <role-name>my-role</role-name>
  </security-role>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>my-realm</realm-name>
  </login-config>
</web-app>

6.41. camel-digitalocean

The digitalocean component allows you to manage Droplets and resources within the DigitalOcean cloud with Camel.

6.42. camel-disruptor

The Disruptor component provides asynchronous SEDA behavior much as the standard SEDA Component, but utilizes a Disruptor instead of a BlockingQueue.

6.43. camel-disruptor-vm

The Disruptor VM component provides a Disruptor based alternative to VM endpoints.

6.44. camel-dns

The dns component provides the ability to:

  • Resolve a domain by its ip

  • Lookup information about a domain

  • Run DNS queries

  CamelContext camelctx = new DefaultCamelContext();
  camelctx.addRoutes(new RouteBuilder() {
      @Override
      public void configure() throws Exception {
          from("direct:start")
          .to("dns:lookup");
      }
  });

  ProducerTemplate producer = camelctx.createProducerTemplate();
  Record[] record = producer.requestBodyAndHeader("direct:start", null, DnsConstants.DNS_NAME, "wildfly.org", Record[].class);

6.45. camel-docker

The docker component enables you to integrate with Docker APIs via the docker-java client.

6.46. camel-dozer

The dozer component provides the ability to map between Java beans using the Dozer mapping framework. Camel also supports the ability to trigger Dozer mappings as a type converter.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").convertBodyTo(CustomerB.class);
    }
});

DozerBeanMapperConfiguration mconfig = new DozerBeanMapperConfiguration();
mconfig.setMappingFiles(Arrays.asList(new String[] { "mappings.xml" }));
new DozerTypeConverterLoader(camelctx, mconfig);

6.47. camel-dropbox

The Dropbox component enables you to integrate with the Dropbox API in order to download, upload and manipulate files.

6.48. camel-ehcache

The ehcache component enables you to perform caching operations using Ehcache 3 as the cache implementation.

6.49. camel-elasticsearch-rest

The elasticsearch-rest component allows you to interface with an ElasticSearch 6.x API using the REST Client library.

6.50. camel-elsql

The ElSql component enables you to write SQL queries through ElSql.

6.51. camel-etcd

The camel-etcd component enables you to interact with etcd key/value store clusters.

6.52. camel-exec

The exec component enables you to execute system commands.

6.53. camel-facebook

The Facebook component provides access to all of the Facebook APIs. You will require a valid developer account in order to use it.

6.54. camel-file2

The file component provides access to file systems, allowing files to be processed by any other Camel Components or messages from other components to be saved to disk.

Here is a simple route that prepends the message with 'Hello' and writes the result to a file in WildFly’s data directory.

final String datadir = System.getProperty("jboss.server.data.dir");

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").transform(body().prepend("Hello ")).
        to("file:" + datadir + "?fileName=camel-file.txt");
    }
});

6.55. camel-fop

The FOP component allows you to render a message into different output formats using Apache FOP.

6.56. camel-freemarker

The freemarker component enables you to use FreeMarker templates in your camel routes.

6.57. camel-ftp

The ftp component provides access to remote file systems over the FTP and SFTP protocols.

CamelContext camelctx = new DefaultCamelContext();
Endpoint endpoint = camelctx.getEndpoint("ftp://localhost:21000/foo?username=admin&password=admin");
camelctx.createProducerTemplate().sendBodyAndHeader(endpoint, "Hello", "CamelFileName", "test.txt");

6.58. camel-ganglia

The Ganglia component provides a mechanism to send a value (the message body) as a metric to the Ganglia monitoring system.

6.59. camel-geocoder

The Geoder component is used for looking up geocodes (latitude and longitude) for a given address, or reverse lookup. The component uses the Google Geocoder API library.

6.60. camel-git

The git component enables you to interact with Git repositories.

6.61. camel-github

The github component enables you to interact with the GitHub API.

6.62. camel-google-bigquery

6.63. camel-google-calendar

The google-calendar component provides access to Google Calendar via the Google Calendar API v3.

6.64. camel-google-drive

The google-drive component provides access to Google Drive via the Google Drive API v2.

6.65. camel-google-mail

The google-mail component provides access to Gmail via the Google Mail Web APIs.

6.66. camel-google-pubsub

The google-pubsub component provides access to Cloud Pub/Sub Infrastructure via the Google Client Services API.

6.67. camel-grpc

The grpc component enables you to call or expose Remote Procedure Call (RPC) services using Protocol Buffers (protobuf) exchange format over HTTP/2 transport.

6.68. camel-guava-eventbus

The http://camel.apache.org/guava-eventbus.htmlguava-eventbus,window=_blank] component provides integration bridge between Camel and Google Guava EventBus infrastructure.

6.69. camel-hazelcast

The hazelcast component allows you to work with the Hazelcast distributed data grid/cache. Hazelcast is a in memory data grid, entirely written in Java (single jar). It offers a great palette of different data stores like map, multi map (same key, n values), queue, list and atomic number. The main reason to use Hazelcast is its simple cluster support.

6.70. camel-hdfs

The hdfs component enables you to read and write messages to and from an HDFS file system using Hadoop 2.x. HDFS is the distributed file system at the heart of Hadoop.

6.71. camel-headersmap

The headersmap component provides a faster implementation of a case-insensitive map which can be plugged in and used by Camel at runtime to have slight faster performance in the Camel Message headers.

6.72. camel-hipchat

The hipchat component supports producing and consuming messages from/to Hipchat service.

6.73. camel-hl7

The hl7 component is used for working with the HL7 MLLP protocol and HL7 v2 messages using the HAPI library.

final String msg = "MSH|^~\\&|MYSENDER|MYRECEIVER|MYAPPLICATION||200612211200||QRY^A19|1234|P|2.4\r";
final HL7DataFormat format = new HL7DataFormat();

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .marshal(format)
        .unmarshal(format)
        .to("mock:result");
    }
});
camelctx.start();

HapiContext context = new DefaultHapiContext();
Parser p = context.getGenericParser();
Message hapimsg = p.parse(msg);

ProducerTemplate producer = camelctx.createProducerTemplate();
Message result = (Message) producer.requestBody("direct:start", hapimsg);
Assert.assertEquals(hapimsg.toString(), result.toString());

6.74. camel-http4

The http4 component provides HTTP based endpoints for calling external HTTP resources.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .to("http4://somehost:8080/simple/myservlet");
    }
});

For secure communication over SSL/TLS, you can use the https4 endpoint:

to("https4://somehost:443/simple/myservlet");

6.75. camel-hystrix

The hystrix EIP provides integration with Netflix Hystrix to be used as circuit breaker in Camel routes.

6.76. camel-iec60870

The IEC 60870-5-104 Client component provides access to IEC 60870 servers using the Eclipse NeoSCADA™ implementation.

The IEC 60870-5-104 Server component provides access to IEC 60870 servers using the Eclipse NeoSCADA™ implementation.

6.77. camel-infinispan

This infinispan component allows you to interact with Infinispan distributed data grid / caches.

You can interact with container managed Infinispan caches by referring to their JNDI lookup within your Camel route. For example, to write a cache entry.

  CamelContext camelctx = new DefaultCamelContext();
  camelctx.addRoutes(new RouteBuilder() {
      @Override
      public void configure() throws Exception {
          from("direct:put")
          .to("infinispan://localhost?cacheContainer=#java:jboss/infinispan/container/myCache&command=PUT");
      }
  });

  Map<String, Object> headers = new HashMap<>();
  headers.put(InfinispanConstants.KEY, "name");
  headers.put(InfinispanConstants.VALUE, "kermit");

  ProducerTemplate template = camelctx.createProducerTemplate();
  template.sendBodyAndHeaders("direct:put", null, headers);

Or you can interact with external Infinispan caches.

  CamelContext camelctx = new DefaultCamelContext();
  camelctx.addRoutes(new RouteBuilder() {
      @Override
      public void configure() throws Exception {
          from("direct:put")
          .to("infinispan://my.cache.host?command=PUT");
      }
  });

  Map<String, Object> headers = new HashMap<>();
  headers.put(InfinispanConstants.KEY, "name");
  headers.put(InfinispanConstants.VALUE, "kermit");

  ProducerTemplate template = camelctx.createProducerTemplate();
  template.sendBodyAndHeaders("direct:put", null, headers);

6.78. camel-influxdb

The influxdb component enables you to interact with InfluxDB

6.79. camel-ipfs

The ipfs component provides access to the Interplanetary File System (IPFS).

6.80. camel-irc

The irc component enables you to publish and consume messages from IRC channels.

6.81. camel-jasypt

The jasypt component provides a simplified encryption library which makes encryption and decryption easy. Camel integrates with Jasypt to allow sensitive information in Properties files to be encrypted.

JasyptPropertiesParser jasypt = new JasyptPropertiesParser();
jasypt.setPassword("secret");

PropertiesComponent pc = new PropertiesComponent();
pc.setLocation("classpath:mysecrets.properties");
pc.setPropertiesParser(jasypt);

context.addComponent("properties", pc);

6.82. camel-jaxb

Covered by JAXB.

6.83. camel-jbpm

The jbpm component provides integration with Business Process Management (BPM) Suit jBPM. It uses kie-remote-client API to interact with jBPM instance over REST. The component supports only producer.

6.84. camel-jcache

The jcache component enables you to perform caching operations using JCache (JSR-107) as the Cache Implementation.

6.85. camel-jclouds

The camel-jclouds component allows interaction with cloud provider key-value engines (blobstores) and compute services. The component uses jclouds which is a library that provides abstractions for blobstores and compute services.

ComputeService simplifies the task of managing machines in the cloud. For example, you can use ComputeService to start 5 machines and install your software on them.

BlobStore simplifies dealing with key-value providers such as Amazon S3. For example, BlobStore can give you a simple Map view of a container.

6.86. camel-jcr

The jcr component allows you to add/read nodes to/from a JCR compliant content repository (e.g. Apache Jackrabbit) with its producer, or register an EventListener with the consumer.

6.87. camel-jdbc

The jdbc component provides access to SQL databases via JDBC.

6.88. camel-jgroups

The jgroups component provides reliable multicast communication via the JGroups toolkit.

6.89. camel-jing

The jing component uses Jing to perform XML validation on the message body using either:

6.90. camel-jms

Covered by JMS.

6.91. camel-jmx

Covered by JMX.

6.92. camel-jolt

The jolt component allows you to process JSON messages using the JOLT specification.

6.93. camel-jpa

Covered by JPA.

6.94. camel-jsch

The jsch component enables secure file transfer using the SCP protocol.

CamelContext camelctx = new DefaultCamelContext();
Endpoint endpoint = camelctx.getEndpoint("scp://localhost:22/my/directory?username=admin&password=admin");
camelctx.createProducerTemplate().sendBodyAndHeader(endpoint, "Hello", "CamelFileName", "test.txt");

6.95. camel-json-validator

The json-validator component performs bean validation of the message body agains JSON Schemas using the Everit JSON Schema library.

6.96. camel-jt400

The jt400 component allows you to exchanges messages with an AS/400 system using data queues.

6.97. camel-kafka

The kafka component is used for communicating with Apache Kafka message broker.

6.98. camel-kubernetes

The kubernetes component provides the capability to integrate with Kubernetes and OpenShift clusters to create, read, update & delete resources.

6.99. camel-ldap

The ldap component provides the capability to perform LDAP queries.

6.100. camel-ldif

The ldif component allows you to do updates on an LDAP server from a LDIF body content.

6.101. camel-leveldb

The leveldb component provides access to the Google LevelDB lightweight and embeddable key value database. It allows together with Camel to provide persistent support for various Camel features such as Aggregator.

6.102. camel-lra

The LRA component provides bindings of the Saga EIP with any Microprofile compatible LRA Coordinator.

6.103. camel-lucene

The lucene component is based on the Apache Lucene project. Apache Lucene is a powerful high-performance, full-featured text search engine library written entirely in Java.

6.104. camel-lumberjack

The lumberjack component retrieves logs sent over the network using the Lumberjack protocol, from Filebeat for instance.

6.105. camel-mail

Interaction with email is provided by the mail component.

By default, Camel will create its own mail session and use this to interact with your mail server. Since WildFly already provides a mail subsystem with all of the relevant support for secure connections, username and password encryption etc, therefore, it is recommended to configure your mail sessions within the WildFly configuration and use JNDI to wire them into your Camel endpoints.

6.105.1. WildFly configuration

First you configure the WildFly mail subsystem for the Mail server. The following example adds configuration for Google Mail IMAP and SMTP .

An additional mail-session is configured after the 'default' session.

<subsystem xmlns="urn:jboss:domain:mail:2.0">
    <mail-session name="default" jndi-name="java:jboss/mail/Default">
      <smtp-server outbound-socket-binding-ref="mail-smtp"/>
    </mail-session>
    <mail-session debug="true" name="gmail" jndi-name="java:jboss/mail/gmail">
      <smtp-server outbound-socket-binding-ref="mail-gmail-smtp" ssl="true" username="your-username-here" password="your-password-here"/>
      <imap-server outbound-socket-binding-ref="mail-gmail-imap" ssl="true" username="your-username-here" password="your-password-here"/>
    </mail-session>
</subsystem>

You can configure outbound-socket-binding-ref values of 'mail-gmail-smtp' and 'mail-gmail-imap'.

The next step is to configure these socket bindings. You can add additional bindings to the socket-binding-group configuration as per the following.

<outbound-socket-binding name="mail-gmail-smtp">
  <remote-destination host="smtp.gmail.com" port="465"/>
</outbound-socket-binding>

<outbound-socket-binding name="mail-gmail-imap">
  <remote-destination host="imap.gmail.com" port="993"/>
</outbound-socket-binding>

This configures the mail session to connect to host smtp.gmail.com on port 465 and imap.gmail.com on port 993. If you’re using a different mail host, then this detail will be different.

6.105.2. POP3 Configuration

If you need to configure POP3 sessions, the principles are the same as defined in the examples above.

<!-- Server configuration -->
<pop3-server outbound-socket-binding-ref="mail-pop3" ssl="true" username="your-username-here" password="your-password-here"/>

<!-- Socket binding configuration -->
<outbound-socket-binding name="mail-gmail-imap">
  <remote-destination host="pop3.gmail.com" port="993"/>
</outbound-socket-binding>

6.105.3. Camel route configuration

Mail producer

This example uses the SMTPS protocol, together with CDI in conjunction with the camel-cdi component. The Java mail session that you configured within the WildFly configuration is injected into a Camel RouteBuilder through JNDI.

Route builder SMTPS example

The GMail mail session is injected into a Producer class using the @Resource annotation with a reference to the jndi-name attribute that you previously configured. This allows you to reference the mail session on the camel-mail endpoint configuration.

public class MailSessionProducer {
    @Resource(lookup = "java:jboss/mail/greenmail")
    private Session mailSession;

    @Produces
    @Named
    public Session getMailSession() {
        return mailSession;
    }
}
public class MailRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .to("smtps://smtp.gmail.com?session=#mailSession");
    }
}

To send an email, you can create a ProducerTemplate and send an appropriate body together with the necessary email headers.

Map<String, Object> headers = new HashMap<String, Object>();
headers.put("To", "destination@test.com");
headers.put("From", "sender@example.com");
headers.put("Subject", "Camel on Wildfly rocks");

String body = "Hi,\n\nCamel on Wildfly rocks!.";

ProducerTemplate template = camelContext.createProducerTemplate();
template.sendBodyAndHeaders("direct:start", body, headers);
Mail consumer

To receive email you can use an IMAP MailEndpoint. The Camel route configuration looks like the following.

public void configure() throws Exception {
   from("imaps://imap.gmail.com?session=#mailSession")
   .to("log:email");
}

6.105.4. Security

SSL configuration

WildFly can be configured to manage Java mail sessions and their associated transports using SSL / TLS. When configuring mail sessions you can configure SSL or TLS on server types:

  • smtp-server

  • imap-server

  • pop-server

By setting attributes ssl="true" or tls="true".

Securing passwords

It is recommended to not use clear text for passwords within configuration files. You can mask sensitive data using the WildFly Vault.

Camel security

Camel endpoint security documentation can be found on the mail component guide. Camel also has a security summary page.

6.105.5. Code examples on GitHub

An example camel-mail application is available on GitHub for you to try out sending / receiving email.

6.106. camel-master

The master endpoint provides a way to ensure only a single consumer in a cluster consumes from a given endpoint; with automatic failover if that JVM dies.

This can be very useful if you need to consume from some legacy back end which either doesn’t support concurrent consumption or due to commercial or stability reasons you can only have a single connection at any point in time.

6.107. camel-metrics

The metrics component allows you to define, publish and collect metrics from Camel routes.

from("direct:start")
.to("metric:counter:simple.counter?increment=3")

6.108. camel-micrometer

The micrometer component allows you to collect various metrics directly from Camel routes.

6.109. camel-microprofile-health

The MircoProfile Health component is used for bridging Eclipse MicroProfile Health checks with Camel’s own Health Check API.

Health checks are available via the WildFly health endpoint.

6.110. camel-microprofile-metrics

The MircoProfile Metrics component provides the capability to expose metrics from Camel routes by leveraging the WildFly metrics subsystem.

Camel metrics are available via the WildFly metrics endpoint.

6.111. camel-milo

The milo-client component provides access to OPC UA servers using the Eclipse Milo™ implementation.

The milo-server component component provides an OPC UA server using the Eclipse Milo™ implementation.

6.112. camel-mina

The mina component is a transport for working with Apache MINA.

6.113. camel-mllp

The mllp component is specifically designed to handle the nuances of the MLLP protocol and provide the functionality required by Healthcare providers to communicate with other systems using the MLLP protocol. The MLLP component provides a simple configuration URI, automated HL7 acknowledgment generation and automatic acknowledgement interrogation.

6.114. camel-mongodb-gridfs

The mongodb-gridfs component provides MongoDB GridFS file storage. Instead of storing a file in a single document, GridFS divides the file into parts, or chunks, and stores each chunk as a separate document.

6.115. camel-mongodb

The mongodb component uses the Mongo Driver for Java 3.4. If your are looking for previous versions, please look at the mongodb component.

6.116. camel-msv

The msv component performs XML validation of the message body using the MSV Library and any of the supported XML schema languages, such as XML Schema or RelaxNG XML Syntax.

6.117. camel-mustache

The mustache component allows for processing a message using a Mustache template.

6.118. camel-mvel

The mvel component allows you to process a message using an MVEL template.

A simple template

Hello @{request.body}

can be used like this

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").to("mvel:template.mvel");
    }
});
camelctx.start();
ProducerTemplate producer = camelctx.createProducerTemplate();
String result = producer.requestBody("direct:start", "Kermit", String.class);
Assert.assertEquals("Hello Kermit", result);

6.119. camel-mybatis

The mybatis component allows you to query, poll, insert, update and delete data in a relational database using MyBatis.

6.120. camel-nagios

The nagios component allows you to send passive checks to Nagios.

6.121. camel-nats

The nats component is used for communicating with the NATS messaging platform.

6.122. camel-netty

Netty client / server support in Camel is provided by the netty component.

WildFly 8 and EAP 6.4 are bundled with module libraries supporting the Netty project version 4. Therefore, the standard netty component will not work since it is compatible with Netty version 3 only.

6.122.1. Simple Netty Client / Server Test

CamelContext camelContext = new DefaultCamelContext();

camelContext.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("netty:tcp://localhost:7666?textline=true")
                .transform(simple("Hello ${body}"))
                .to("direct:end");
    }
});

camelContext.start();

PollingConsumer pollingConsumer = camelContext.getEndpoint("direct:end").createPollingConsumer();
pollingConsumer.start();

Socket socket = new Socket("localhost", 7666);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

try {
    out.write("Kermit\n");
} finally {
    out.close();
    socket.close();
}

String result = pollingConsumer.receive().getIn().getBody(String.class);

Assert.assertEquals("Hello Kermit", result);

camelContext.stop();

6.123. camel-nsq

The nsq component enables you to interact with the NSQ realtime distributed messaging platform.

6.124. camel-ognl

OGNL expression support in Camel is provided by the ognl component.

6.124.1. Simple Camel OGNL Use Case

CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
            .choice()
                .when()
                    .ognl("request.body.name == 'Kermit'").transform(simple("Hello ${body.name}"))
                .otherwise()
                    .to("mock:dlq");
    }
});

camelContext.start();

Person person = new Person();
person.setName("Kermit");

ProducerTemplate producer = camelContext.createProducerTemplate();
String result = producer.requestBody("direct:start", person, String.class);

Assert.assertEquals("Hello Kermit", result);

camelContext.stop();

6.125. camel-olingo2

The olingo2 component provides the capability to interact with OData 2.0 and 3.0 compliant services via Apache Olingo.

6.126. camel-olingo4

The olingo4 component utilizes Apache Olingo version 4.0 APIs to interact with OData 4.0 compliant service.

6.127. camel-openstack

The openstack-swift component allows messages to be sent to an OpenStack object storage services.

The openstack-nova component allows messages to be sent to an OpenStack compute services.

The openstack-neutron component allows messages to be sent to an OpenStack network services.

The openstack-keystone component allows messages to be sent to an OpenStack identity services.

The openstack-glance component allows messages to be sent to an OpenStack image services.

The openstack-cinder component allows messages to be sent to an OpenStack block storage services.

6.128. camel-opentracing

The opentracing component is used for tracing and timing incoming and outgoing Camel messages using OpenTracing.

6.129. camel-optaplanner

The camel-optaplanner component solves the planning problem contained in a message with OptaPlanner.

6.130. camel-paho

The paho component provides connector for the MQTT messaging protocol using the Eclipse Paho library.

6.131. camel-pdf

The pdf component provides the ability to create, modify or extract content from PDF documents. This component uses Apache PDFBox as underlying library to work with PDF documents.

6.132. camel-pgevent

The pgevent component allows for Producing/Consuming PostgreSQL events related to LISTEN/NOTIFY commands.

In order to use this component on WildFly, you must configure a datasource. For example:

<subsystem xmlns="urn:jboss:domain:datasources:5.0">
    <datasources>
        <datasource jndi-name="java:jboss/datasources/PostgreSqlDS" pool-name="PostgreSqlDS">
            <connection-url>jdbc:pgsql://localhost:5432/postgres</connection-url>
            <driver>pgsql</driver>
            <security>
                <user-name>postgres</user-name>
                <password>s3cret</password>
            </security>
        </datasource>
        <drivers>
            <driver name="pgsql" module="com.impossibl.pgjdbc"/>
        </drivers>
    </datasources>
</subsystem>

Then configure the pgevent endpoint to make use of the DataSource:

pgevent:///postgres/testchannel?datasource=#java:jboss/datasources/PostgreSqlDS

6.133. camel-printer

The printer component provides a way to direct payloads on a route to a printer. The objective is to be able to direct specific payloads as jobs to a line printer in a camel flow.

6.134. camel-pubnub

The The PubNub component allows you to communicate with the PubNub data stream network for connected devices. This component uses PubNub java library.

6.135. camel-quartz2

The quartz component provides a scheduled delivery of messages using the Quartz Scheduler 2.x.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
        from("quartz2://mytimer?trigger.repeatCount=3&trigger.repeatInterval=100")
        .process(new Processor() {
			public void process(Exchange exchange) throws Exception {
				latch.countDown();
			}})
        .to("mock:result");
    }
});

6.136. camel-quickfix

The quickfix component adapts the QuickFIX/J engine for using in Camel. This component uses the standard Financial Interchange (FIX) protocol for message transport.

6.137. camel-rabbitmq

The rabbitmq component enables you to produce and consume messages from RabbitMQ instances.

6.138. camel-reactive-streams

The reactive-streams component enables you to exchange messages with reactive stream processing libraries that are compatible with the reactive streams standard.

6.139. camel-reactor

The reactor component integrates with Project Reactor a fully non-blocking foundation with efficient demand management. It directly interacts with Java 8 functional API, Completable Future, Stream and Duration.

6.140. camel-ribbon

The ribbon component provides use of Netflix Ribbon for client side load balancing.

6.141. camel-rest

The rest component allows you to define REST endpoints using the Rest DSL and plugin to other Camel components as the REST transport.

The WildFly-Camel Subsystem only supports the camel-servlet and camel-undertow components for use with the REST DSL. However, the subsystem does not work, If you attempt to configure other components.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        restConfiguration().component("servlet").contextPath("camel/rest").port(8080);
        rest("/hello").get("/{name}").to("direct:hello");
        from("direct:hello").transform(simple("Hello ${header.name}"));
    }
});

6.142. camel-rest-swagger

The rest-swagger component can configure REST producers from a Swagger document and delegate to a component implementing the RestProducerFactory interface such as:

6.143. camel-rss

The rss component is used for polling RSS feeds.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    public void configure() throws Exception {
        from("rss://https://developer.jboss.org/blogs/feeds/posts?splitEntries=true&consumer.initialDelay=200&consumer.delay=1000")
        .process(new Processor() {
			public void process(Exchange exchange) throws Exception {
				latch.countDown();
			}})
        .to("mock:result");
    }
});

6.144. camel-rxjava

The rxjava component allows you to use the RxJava API for processing messages on endpoints.

6.145. camel-salesforce

The salesforce component provides producer and consumer endpoints to communicate with Salesforce.

In order to use the component, you will need a valid Salesforce account together with credentials for accessing the Salesforce API:

  • Client ID

  • Client Secret

  • Password

  • Username

You’ll want to generate the necessary Salesforce DTO objects before starting. This can be automated with the Camel Salesforce Maven plugin.

mvn camel-salesforce:generate -DcamelSalesforce.clientId=<clientid> -DcamelSalesforce.clientSecret=<clientsecret> -DcamelSalesforce.userName=<username> -DcamelSalesforce.password=<password>

This example queries Salesforce 'Opportunity' objects.

SalesforceLoginConfig loginConfig = new SalesforceLoginConfig();
loginConfig.setClientId("your-client-id");
loginConfig.setPassword("your-password");
loginConfig.setClientSecret("your-client-secret");
loginConfig.setUserName("your-username");

SalesforceComponent component = new SalesforceComponent();
// The package path to the generated DTO classes
component.setPackages("org.wildfly.camel.test.salesforce.dto");
component.setLoginConfig(loginConfig);

CamelContext camelctx = new DefaultCamelContext();
camelctx.addComponent("salesforce",  component);
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:query")
        .to("salesforce:query?sObjectQuery=SELECT id,name from Opportunity&sObjectClass=" + QueryRecordsOpportunity.class.getName())
        .to("log:salesforce?showAll=true");
    }
});

camelctx.start();

ProducerTemplate producer = ctx.createProducerTemplate();
QueryRecordsOpportunity queryRecords = producer.requestBody("direct:query", null, QueryRecordsOpportunity.class);

6.146. camel-sap

sap is a package consisting of ten different SAP components.

There are remote function call (RFC) components that support the sRFC, tRFC, and qRFC protocols; and there are IDoc components that facilitate communication using messages in IDoc format. The component uses the SAP Java Connector (SAP JCo) library to facilitate bidirectional communication with SAP and the SAP IDoc library to facilitate the transmission of documents in the Intermediate Document (IDoc) format.

A prerequisite for using the Camel SAP component is that the SAP Java Connector (SAP JCo) libraries and the SAP IDoc library are available for the WildFly-Camel Subsytem to use. The subsystem distribution does not include these libraries. You will need access to the SAP Service Marketplace in order to obtain them.

6.146.1. Configuring the camel-sap module

Before using camel-sap, an additional WildFly modules needs to be configured so that the subsystem can discover the new functionality.

Your application server should be stopped before making the following changes.

Modify module com.sap.conn.jco

Download the SAP JCo libraries and the SAP IDoc library from the SAP Service Marketplace, making sure to choose the appropriate library versions for your operating system.

  1. From a terminal session, change into the application server installation root directory

  2. Change into directory modules/system/layers/fuse

  3. Copy sapjco3.jar and sapidoc3.jar into com/sap/conn/jco/main

  4. Create an appropriate native library directory within com/sap/conn/jco/main. For example, if your target platform is Linux x86_64 you would create lib/linux-x86_64. For information relating to other operating systems and architectures see the WildFly Native Libraries documentation

  5. Copy the JCO native library (i.e the .so, .dll or .jnilib file) into the native library directory you created in the previous step

The file and directory structure for module com.sap.conn.jco should now look something like this:

com/sap/conn/jco
com/sap/conn/jco/main
com/sap/conn/jco/main/sapidoc3.jar
com/sap/conn/jco/main/sapjco3.jar
com/sap/conn/jco/main/module.xml
com/sap/conn/jco/main/lib
com/sap/conn/jco/main/lib/linux-x86_64
com/sap/conn/jco/main/lib/linux-x86_64/libsapjco3.so
Activate camel-sap component module
  1. From a terminal session change into the application server installation root directory

  2. Change into directory modules/system/layers/fuse/org/wildfly/camel/extras/main

  3. Edit module.xml and uncomment the org.fusesource.camel.component.sap module dependency. Save the modified file when finished

The module definition should look like this:

<module xmlns="urn:jboss:module:1.1" name="org.wildfly.camel.extras">
    <dependencies>
        <module name="org.fusesource.camel.component.sap" export="true" services="export" />
    </dependencies>
</module>

Start your application server and camel-sap will be available for use.

6.146.2. Example SAP Camel Route

This example uses XML files containing serialized SAP requests to query Customer records in the Flight Data Application within SAP.

These files are consumed by Camel and their contents are then converted to string message bodies. These messages are then routed to an sap-srfc-destination endpoint which converts and sends them to SAP as BAPI_FLCUST_GETLIST requests to query Customer records.

First we configure a destination data store.

DestinationData destinationData = new DestinationDataImpl();
destinationData.setAshost("example.com");
destinationData.setSysnr("00");
destinationData.setClient("000");
destinationData.setUser("user");
destinationData.setPasswd("password");
destinationData.setLang("en");

Map<String, DestinationData> destinationDataStore = new HashMap<>();
destinationDataStore.put("quickstartDest", destinationData);

Next wire the destinationDataStore into a SapConnectionConfiguration.

SapConnectionConfiguration configuration = new SapConnectionConfiguration();
configuration.setDestinationDataStore(destinationDataStore);

The Camel RouteBuilder looks like this.

@ApplicationScoped
@ContextName("camel-sap-cdi-context")
@Startup
public class SAPRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
      from("file:src/data")
      .convertBodyTo(String.class)
      .to("log:sap?showAll=true")
      .to("sap-srfc-destination:quickstartDest:BAPI_FLCUST_GETLIST")
      .to("log:sap?showAll=true");
    }
}

The XML request looks like the following and is consumed from a file within src/data.

<?xml version="1.0" encoding="ASCII"?>
<!-- NOTE: Replace 'XXX' with the SID of your SAP instance -->
<BAPI_FLCUST_GETLIST:Request xmlns:BAPI_FLCUST_GETLIST="http://sap.fusesource.org/rfc/XXX/BAPI_FLCUST_GETLIST" CUSTOMER_NAME="*" MAX_ROWS="10" WEB_USER="*"/>

When the Camel route runs, the request XML data is consumed from src/data and sent to SAP as a BAPI_FLCUST_GETLIST request. The results of the SAP request are output to the console. You should see an XML structure like the following containing customer records.

<BAPI_FLCUST_GETLIST:Response xmlns:BAPI_FLCUST_GETLIST="http://sap.fusesource.org/rfc/JBF/BAPI_FLCUST_GETLIST">
<CUSTOMER_LIST>
    <row CUSTOMERID="00004715" CUSTNAME="Fred Flintstone" FORM="Mr." STREET="123 Flintstone Lane" POBOX="" POSTCODE="01234" CITY="Bedrock" COUNTR="US" COUNTR_ISO="US" REGION="" PHONE="800-555-1212" EMAIL=""/>
    <row CUSTOMERID="00004716" CUSTNAME="Wilma Flintstone" FORM="Mr." STREET="123 Flintstone Lane" POBOX="" POSTCODE="01234" CITY="Bedrock" COUNTR="US" COUNTR_ISO="US" REGION="" PHONE="800-555-1212" EMAIL=""/>
</CUSTOMER_LIST>
<CUSTOMER_RANGE/>
<EXTENSION_IN/>
<EXTENSION_OUT/>
<RETURN>
    <row TYPE="S" ID="BC_IBF" NUMBER="000" MESSAGE="Method was executed successfully" LOG_NO="" LOG_MSG_NO="000000" MESSAGE_V1="" MESSAGE_V2="" MESSAGE_V3="" MESSAGE_V4="" PARAMETER="" FIELD="" SYSTEM="DEVQKCLNT"/>
</RETURN>
</BAPI_FLCUST_GETLIST:Response>

6.146.3. Further Reading

The example above only scratches the surface of the functionality provided by the camel-sap component. For comprehensive component documentation visit the Camel SAP Component Reference.

6.147. camel-sap-netweaver

The sap-netweaver component integrates with the SAP Gateway.

You will need a valid SAP account in order to use this component. You can sign up here.

6.148. camel-saxon

The saxon component supports XQuery to allow an Expression or Predicate to be used in the DSL or Xml Configuration.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        Namespaces ns = new Namespaces("ns", "http://org/wildfly/test/jaxb/model/Customer");
        from("direct:start").transform().xquery("/ns:customer/ns:firstName", String.class, ns)
        .to("mock:result");
    }
});

6.149. camel-schematron

The schematron component utilises Schematron to make assertions about the presence or absence of patterns in XML documents.

6.150. camel-servicenow

The servicenow component provides access to the ServiceNow REST APIs.

6.151. camel-servlet

The servlet component provides HTTP based endpoints for consuming HTTP requests that arrive at a HTTP endpoint that is bound to a published Servlet.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("servlet://hello?servletName=CamelServletTest&matchOnUriPrefix=true")
        .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                exchange.getOut().setBody("Hello Kermit");
            }
        });
    }
});

6.152. camel-shiro

The shiro component provides security, based on the Apache Shiro security project.

Apache Shiro is a powerful and flexible open-source security framework that cleanly handles authentication, authorization, enterprise session management and cryptography. The objective of the Apache Shiro project is to provide the most robust and comprehensive application security framework available while also being very easy to understand and extremely simple to use.

6.153. camel-slack

The slack component allows you to connect to an instance of Slack and delivers a message contained in the message body via a pre established Slack incoming webhook.

6.154. camel-smpp

The smpp component enables SMSC over the SMPP protocol in order to send and receive SMS.

6.155. camel-snmp

The snmp component enables you to poll SNMP enabled devices or configure an SNMP trap.

6.156. camel-solr

The solr component allows you to interface with an Apache Lucene Solr server.

6.157. camel-spring

Camel contexts can be configured with Spring via the spring component.

6.157.1. Camel Spring XML example

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

    <camelContext id="hello-camel-context" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="timer:hello?period=5000" />
            <log message="Hello world" />
        </route>
    </camelContext>

</beans>

6.157.2. Deployment

Spring Camel contexts can be deployed either as part of the camel subsystem configuration or by deploying a '-camel-context.xml' suffixed file.

For more information see the features.

6.158. camel-spring-batch

The spring-batch component and support classes provide integration bridge between Camel and Spring Batch infrastructure.

6.159. camel-spring-javaconfig

The spring-javaconfig component provides Java instead of XML configuration capabilities for Spring camel contexts.

6.160. camel-spring-ldap

The spring-ldap component provides a Camel wrapper for Spring LDAP.

6.161. camel-spring-redis

The spring-redis component allows sending and receiving messages from Redis. Redis is advanced key-value store where keys can contain strings, hashes, lists, sets and sorted sets. In addition it provides pub/sub functionality for inter-app communications.

Camel provides a producer for executing commands, consumer for subscribing to pub/sub messages an idempotent repository for filtering out duplicate messages.

6.162. camel-spring-ws

The spring-ws component allows you to integrate with Spring Web Services. It offers both client-side support, for accessing web services, and server-side support for creating your own contract-first web services.

6.163. camel-sip

The sip component is a communication component, based on the Jain SIP implementation (available under the JCP license).

Session Initiation Protocol (SIP) is an IETF-defined signaling protocol, widely used for controlling multimedia communication sessions such as voice and video calls over Internet Protocol (IP).The SIP protocol is an Application Layer protocol designed to be independent of the underlying transport layer; it can run on Transmission Control Protocol (TCP), User Datagram Protocol (UDP) or Stream Control Transmission Protocol (SCTP).

6.164. camel-sjms

The sjms component, or SJMS, is a JMS client for use with Camel that uses well known best practices when it comes to JMS client creation and configuration.

6.165. camel-sjms-batch

The sjms-batch SJMS Batch component is a specialized component for highly performant, transactional batch consumption from a JMS queue.

6.166. camel-sjms2

The sjms2 component, or SJMS2, is a JMS 2.x client for use with Camel that uses well known best practices when it comes to JMS client creation and configuration.

6.167. camel-slack

The slack component allows you to connect to an instance of Slack and delivers a message contained in the message body via a pre established Slack incoming webhook.

6.168. camel-splunk

The splunk component provides access to Splunk, via the Splunk provided client Rest API, allowing you to publish and search for events in Splunk.

6.169. camel-sql

The SQL component allows you to work with databases using JDBC queries. The difference between this component and JDBC component is that in case of SQL the query is a property of the endpoint and it uses message payload as parameters passed to the query.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("sql:select name from information_schema.users?dataSource=java:jboss/datasources/ExampleDS")
        .to("direct:end");
    }
});

The JNDI datasource lookup shown above works only when configuring a DefaultCamelContext. See below for CdiCamelContext and SpringCamelContext examples.

When used in conjunction with the camel-cdi component, Java EE annotations can make a datasource available to Camel. This example uses the @Named annotation so that Camel can discover the desired datasource.

public class DatasourceProducer {
    @Resource(lookup = "java:jboss/datasources/ExampleDS")
    DataSource dataSource;

    @Produces
    @Named("wildFlyExampleDS")
    public DataSource getDataSource() {
        return dataSource;
    }
}

Now the datasource can be referenced through the dataSource parameter on the camel-sql endpoint configuration.

@ApplicationScoped
@ContextName("camel-sql-cdi-context")
@Startup
public class CdiRouteBuilder extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        from("sql:select name from information_schema.users?dataSource=wildFlyExampleDS")
        .to("direct:end");
    }
}

When using camel-spring the route configuration would look like:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">

    <jee:jndi-lookup id="wildFlyExampleDS" jndi-name="java:jboss/datasources/ExampleDS"/>

    <camelContext id="sql-spring-context" xmlns="http://camel.apache.org/schema/spring">
        <route>
            <from uri="sql:select name from information_schema.users?dataSource=#wildFlyExampleDS" />
            <to uri="direct:end" />
        </route>
    </camelContext>

</beans>

6.169.1. Spring JDBC XML namespace support

Support for the following Spring JDBC XML configurations is supported

jdbc:embedded-database

<jdbc:embedded-database id="datasource" type="H2">
  <jdbc:script location="db-schema.sql"/>
</jdbc:embedded-database>

Only H2 databases are supported by default as WildFly has native support for this. If you want to use other embedded database providers, you will need to install the appropriate database driver.

jdbc:initialize-database

<jdbc:initialize-database data-source="datasource">
  <jdbc:script location="classpath:db-init.sql"/>
</jdbc:initialize-database>

6.170. camel-ssh

The ssh component provides the capability to interact with SSH servers.

6.171. camel-stax

The StAX component enables messages to be passed through a SAX ContentHandler. It can also iterate over JAXB records using StAX.

6.172. camel-stomp

The stomp can be used for communicating with Stomp compliant message brokers, like Apache ActiveMQ or ActiveMQ Apollo.

6.173. camel-stream

The stream component provides access to the System.in, System.out and System.err streams as well as allowing streaming of file and URL.

6.174. camel-string-template

The string-template component allows you to process a message using a String Template.

6.175. camel-swagger

The swagger module is used for exposing the REST services and their APIs using Swagger.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        restConfiguration().component("servlet").contextPath("swagger-tests/rest").port(8080);
        rest("/hello").get("/{name}").to("direct:hello");
        from("direct:hello").transform(simple("Hello ${header.name}"));
    }
});
camelctx.start();

6.176. camel-telegram

The telegram component provides access to the Telegram Bot API. It allows a Camel-based application to send and receive messages by acting as a Bot, participating in direct conversations with normal users, private and public groups or channels.

6.177. camel-thrift

The thrift component allows you to call or expose Remote Procedure Call (RPC) services using Apache Thrift binary communication protocol and serialization mechanism.

6.178. camel-tika

The tika provides the ability to detect and parse documents with Apache Tika.

6.179. camel-twilio

The twilio component provides access to Version 2010-04-01 of Twilio REST APIs accessible using Twilio Java SDK.

6.180. camel-twitter

The twitter component provides the capability to interact with the Twitter API in order to create and consume tweets, timelines, users, trends, and direct messages.

6.181. camel-undertow

The undertow component provides HTTP-based endpoints for consuming and producing HTTP requests. That is, the Undertow component behaves as a simple Web server. Undertow can also be used as a http client which mean you can also use it with Camel as a producer.

The Undertow component integrates with the Undertow server provided by WildFly.

6.181.1. Undertow consumers on WildFly

The configuration of camel-undertow consumers on WildFly is different to that of standalone Camel. Producer endpoints work as per normal.

On WildFly, camel-undertow consumers leverage the default Undertow HTTP server provided by the container. The server is defined within the undertow subsystem configuration. Here’s an excerpt of the default configuration from standalone.xml:

<subsystem xmlns="urn:jboss:domain:undertow:4.0">
    <buffer-cache name="default" />
    <server name="default-server">
        <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true" />
        <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true" />
        <host name="default-host" alias="localhost">
            <location name="/" handler="welcome-content" />
            <filter-ref name="server-header" />
            <filter-ref name="x-powered-by-header" />
            <http-invoker security-realm="ApplicationRealm" />
        </host>
    </server>
</subsystem>

In this instance, Undertow is configured to listen on interfaces / ports specified by the http and https socket-binding. By default this is port 8080 for http and 8443 for https.

This has the following implications:

  • camel-undertow consumers will only bind to localhost:8080 or localhost:8443

  • Some endpoint consumer configuration options have no effect (see below), since these settings are managed by the WildFly container

For example, if you configure an endpoint consumer using different host or port combinations, a warning will appear within the server log file. For example the following host & port configurations would be ignored:

from("undertow:http://somehost:1234/path/to/resource")
[org.wildfly.extension.camel] (pool-2-thread-1) Ignoring configured host: http://somehost:1234/path/to/resource

However, the consumer is still available on the default host & port localhost:8080 or localhost:8443.

Configuring alternative ports

If alternative ports are to be accepted, then these must be configured via the WildFly subsystem configuration. This is explained in the server documentation:

6.182. camel-velocity

The velocity component allows you to process a message using an Apache Velocity template.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start").to("velocity:" + VELOCITY_TEMPLATE);
    }
});
camelctx.start();

6.183. camel-vertx

The vertx component is for working with the Vertx EventBus. The Vertx EventBus sends and receives JSON events.

6.184. camel-weather

The weather component provides integration with the Open Weather Map API.

As an example, we can consume the current weather for Madrid in Spain and make some decisions based upon the humidity percentage:

CamelContext camelContext = new DefaultCamelContext();
camelContext.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("weather:foo?location=Madrid,Spain")
        .choice()
          .when().jsonpath("$..[?(@humidity > 90)]")
            .to("direct:veryhumid")
          .when().jsonpath("$..[?(@humidity > 70)]")
            .to("direct:humid")
          .otherwise()
            .to("direct:nothumid");
    }
});
camelContext.start();

6.185. camel-wordpress

The wordpress component provides support for Wordpress API.

6.186. camel-xchange

The XChange component uses the XChange Java library to provide access to 60+ Bitcoin and Altcoin exchanges. It comes with a consistent interface for trading and accessing market data.

Camel can get crypto currency market data, query historical data, place market orders and much more.

6.187. camel-xmpp

The XMPP component provides the capability to produce and consume XMPP (Jabber) messages.

6.188. camel-xstream

The xstream component provides the XStream Data Format which uses the XStream library to marshal and unmarshal Java objects to and from XML.

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .marshal().xstream();
    }
});

camelctx.start();
try {
    ProducerTemplate producer = camelctx.createProducerTemplate();
    String customer = producer.requestBody("direct:start", new Customer("John", "Doe"), String.class);
} finally {
    camelctx.close();
}

6.189. camel-yammer

The yammer component allows you to interact with the Yammer enterprise social network. Consuming messages, users, and user relationships is supported as well as creating new messages.

6.190. camel-zendesk

The zendesk component provides access to all of the Zendesk APIs via the zendesk-java-client.

6.191. camel-zipkin

The camel-zipkin component is used for tracing and timing incoming and outgoing Camel messages using zipkin. Events are captured for incoming and outgoing messages being sent to/from Camel.

6.192. camel-zookeeper

The zookeeper component allows interaction with a ZooKeeper cluster and exposes the following features to Camel:

  • Creation of nodes in any of the ZooKeeper create modes.

  • Get and Set the data contents of arbitrary cluster nodes.

  • Create and retrieve the list the child nodes.

  • A Distributed RoutePolicy that leverages a Leader election.

6.193. camel-zookeeper-master

The zookeeper-master component provides a way to ensure only a single consumer in a cluster consumes from a given endpoint; with automatic failover if that JVM dies.

This can be very useful if you need to consume from some legacy back end which either doesn’t support concurrent consumption or due to commercial or stability reasons you can only have a single connection at any point in time.

6.194. Adding Components

Adding support for additional Camel Components is easy

Add your modules.xml definition

A modules.xml descriptor defines the class loading behavior for your component. It should be placed together with the component’s jar in modules/system/layers/fuse/org/apache/camel/component. Module dependencies should be setup for direct compile time dependencies.

Here is an example for the camel-ftp component

<module xmlns="urn:jboss:module:1.1" name="org.apache.camel.component.ftp">
  <resources>
    <resource-root path="camel-ftp-2.14.0.jar" />
  </resources>
  <dependencies>
    <module name="com.jcraft.jsch" />
    <module name="javax.xml.bind.api" />
    <module name="org.apache.camel.core" />
    <module name="org.apache.commons.net" />
  </dependencies>
</module>

Make sure that you do not duplicate modules that are already available in WildFly and can be reused.

Add a reference to the component

To make this module visible by default to arbitrary JavaEE deployments add a reference to modules/system/layers/fuse/org/apache/camel/component/main/module.xml

<module xmlns="urn:jboss:module:1.3" name="org.apache.camel.component">
  <dependencies>
    ...
    <module name="org.apache.camel.component.ftp" export="true" services="export"/>
  </dependencies>
</module>

7. Data Formats

8. Languages

The following lists supported scripting languages

9. Cloud Integration

This chapter details information about cloud integration

9.1. OpenShift Local

Here we follow the instructions on Try Origin. We use the All-In-One VM approach through Minishift on VirtualBox VM.

After having installed Minishift and VirtualBox, we run:

$ minishift start --vm-driver=virtualbox --memory 12048 --cpus 3
...
   OpenShift server started.
   The server is accessible via web console at:
       https://192.168.99.100:8443

   You are logged in as:
       User:     developer
       Password: developer

   To login as administrator:
       oc login -u system:admin

9.1.1. Client Tools

The client tools are available from the Minishift installation.

$ export PATH=$PATH:~/.minishift/cache/oc/v3.6.0

9.1.2. Docker access

When running OpenShift in a single VM, it is recommended to reuse the Docker daemon which Minishift uses for pure Docker use-cases as well. By using the same docker daemon as Minishift, you can speed up your local experiments.

To be able to work with the docker daemon on your Mac or GNU/Linux host use the docker-env command in your shell:

$ eval $(minishift docker-env)

You should now be able to use docker on the command line of your host, talking to the docker daemon inside the Minishift VM:

$ docker ps

9.1.3. Running WildFly-Camel

With every WildFly-Camel release we also publish the latest wildflyext/wildfly-camel image.

You can run the standalone container like this

$ docker run --rm -ti -e WILDFLY_MANAGEMENT_USER=admin -e WILDFLY_MANAGEMENT_PASSWORD=admin -p 8080:8080 -p 9990:9990 wildflyext/wildfly-camel

and access the admin console like this: http://192.168.99.100:9990/console

console standalone

9.1.4. Create an OpenShift project

Here we run a set of WildFly-Camel servers on OpenShift Origin. The target platform is the local OpenShift instance that we created above.

example rest design

The example architecture consists of a set of three high available (HA) servers running REST endpoints. For server replication and failover we use Kubernetes. Each server runs in a dedicated Pod that we access via Services.

A project allows us to create deployments, pods, services, routes, etc. under our own custom 'wildfly-camel' namespace.

$ oc login -u user -p user
$ oc new-project wildfly-camel
Create a new application

Now, lets create a new application from an existing wildfly-camel based image.

$ oc new-app wildflyext/example-camel-rest

It’s good practice to add liveness and readiness probes to the deployment.

$ oc set probe dc/example-camel-rest --liveness --initial-delay-seconds 60 -- echo ok
$ oc set probe dc/example-camel-rest --readiness --initial-delay-seconds 60 --get-url=http://:8080/example-camel-cxf-jaxrs/cxf

Scale up the deployment.

$ oc scale --replicas=3 dc example-camel-rest

After a while you should see the pod running

openshift standalone pods

The pods running the JAX-RS endpoints are however not yet exposed to the world.

Exposing the container externally

Now, lets expose the HTTP root context of the running WildFly server.

$ oc expose service example-camel-rest

You can discover the exposed route host name with.

$ oc get route example-camel-rest

From a remote client, you should now be able to access the service like this

Hello Kermit from 172.17.0.8

You can clean up all created resources with.

$ oc delete all -l "app=example-camel-rest"

9.2. OpenShift on EC2

Here we follow the instructions on Try Origin for binary releases VM.

After having launched an instance of RHEL7 on EC2 we can ssh into the box.

$ ssh -i ~/.ssh/id_rsa_ec2.pem ec2-user@1.2.3.4

9.2.1. Install Docker

Then we install Docker and add the ec2-user to the docker group.

$ curl -fsSL https://get.docker.com/ | sh
$ sudo usermod -aG docker ec2-user
$ sudo systemctl enable docker.service
$ sudo systemctl start docker
$ docker run hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.

9.2.2. Download & Install OpenShift

Now download the OpenShift server and start it

$ curl -L https://github.com/openshift/origin/releases/download/v1.4.0-rc1/openshift-origin-server-v1.4.0-rc1.b4e0954-linux-64bit.tar.gz > openshift-origin-server-v1.4.0-rc1.tar.gz
$ tar xzf openshift-origin-server-v1.4.0-rc1.tar.gz
$ oc cluster up --public-hostname=ec2-1-2-3-4.eu-west-1.compute.amazonaws.com --routing-suffix=1.2.3.4.xip.io

If you see a failure during startup like this, follow the instructions below for Docker deamon configuration.

-- Checking Docker daemon configuration ... FAIL
   Error: did not detect an --insecure-registry argument on the Docker daemon
   Solution:

     Ensure that the Docker daemon is running with the following argument:
     	--insecure-registry 172.30.0.0/16

9.2.3. Registry Security

The Docker registry may need to be marked as insecure.

  1. Create the /etc/systemd/system/docker.service.d directory.

    $ sudo mkdir /etc/systemd/system/docker.service.d
  2. Create/Edit the /etc/systemd/system/docker.service.d/docker.conf file.

    Override the ExecStart configuration from your docker.service file to customize the docker daemon. To modify the ExecStart configuration you have to specify an empty configuration followed by a new one as follows:

    $ sudo vi /etc/systemd/system/docker.service.d/docker.conf
    [Service]
    ExecStart=
    ExecStart=/usr/bin/dockerd --insecure-registry 172.30.0.0/16
  3. Restart the docker daemon.

    $ sudo systemctl daemon-reload; sudo systemctl restart docker
  4. Restart the OpenShift cluster

$ oc cluster up --public-hostname=ec2-1-2-3-4.eu-west-1.compute.amazonaws.com --routing-suffix=1.2.3.4.xip.io

9.2.4. Access the Console

We can now access the OpenShift console on: https://1.2.3.4:8443/console

The process of creating a project and application follows that of OpenShift Local.

9.3. Source to Image

The WildFly-Camel Docker image is capable of performing Source-To-Image builds.

This enables you to build reproducible images from source.

9.3.1. Example S2I build

First you’ll need to download and install the S2I tooling from here.

Then you can build and run a Docker image from source. For example, to build the WildFly-Camel CDI quickstart:

$ s2i build https://github.com/wildfly-extras/wildfly-camel-examples.git -r 12.0.0 --context-dir camel-cdi wildflyext/wildfly-camel:12.0.0 wildfly-camel-example-cdi
$ docker run -ti -p 8080:8080 wildfly-camel-example-cdi

From a remote client, you should now be able to access the service like this

Hello Kermit

9.3.2. S2I with OpenShift

WildFly-Camel provides an S2I builder image, which enables you to do source to image builds in OpenShift.

First add the WildFly-Camel S2I ImageStream and application template.

$ oc project # Check into which project you are importing the image stream and the template
Using project "myproject" from context named "minishift" on server "https://192.168.42.188:8443".
$ oc apply -f http://wildfly-extras.github.io/wildfly-camel/sources/wildfly-camel-imagestream.json
$ oc create -f http://wildfly-extras.github.io/wildfly-camel/sources/wildfly-camel-application-template.json

In the OpenShift web console, go to the project where you imported the image stream and the template. When you select 'Add to Project → Select from Project' in the top right corner you should see a new catalog item named 'Wildfly Camel'. Choose this option, then provide the required parameters.

wildfly camel s2i builder01

To build the latest release of the WildFly-Camel CDI example you would enter (leaving the rest of the parameters unchanged):

Application Name

camel-cdi

Base Image ImageStream Namespace

The name of the project where you imported the WildFly Camel image stream the previous step; e.g. myproject

Git Repository URL

https://github.com/wildfly-extras/wildfly-camel-examples.git

Git Reference

12.0.0

Context Directory

camel-cdi

Click 'Create' to start the build process.

You’ll then be able to monitor your application S2I build and deployment in OpenShift. Eventually you should see your application with 1 pod running.

wildfly camel s2i builder02

Then to access the application you can browse to the route endpoint URL. For example:

Hello Kermit

9.4. WildFly OpenShift Operator

It is useful to deploy and manage containerized WildFly-Camel applications on OpenShift via the WildFly Operator.

9.4.1. Installation

Operator Lifecycle Manager (OLM)

With OpenShift 4, the operator can be installed from the OLM marketplace. Browse the operator catalog, select the WildFly item, click the 'install' button and follow the instructions.

OLM can be installed on an OpenShift 3 cluster by following the installation instructions.

Manual installation

To manually install the WildFly operator, apply the required Custom Resource Definition (CRD), roles and deployments to your cluster by following the instructions.

9.4.2. Deploying a operator managed application

For the WildFly operator to manage a containerized WildFly-Camel application deployment, you need to create WildFlyServer resources on your cluster.

$ cat <<EOF | oc create -f -
apiVersion: wildfly.org/v1alpha1
kind: WildFlyServer
metadata:
  name: example-camel-rest
spec:
  applicationImage: "docker.io/wildflyext/example-camel-rest"
  size: 3
EOF

This results in 3 replicas of the example-camel-rest application backed by a service and route.

$ oc get pods -l app.kubernetes.io/name=example-camel-rest

NAME                   READY     STATUS             RESTARTS   AGE
example-camel-rest-0   1/1       Running            0          5m
example-camel-rest-1   1/1       Running            0          5m
example-camel-rest-2   1/1       Running            0          5m

10. Security

Security in WildFly is a vast topic. Both WildFly and Camel have well documented, standardised methods of securing configuration, endpoints and payloads.

10.1. Hawtio Security

Securing the Hawtio console can be accomplished via the following steps.

1. Add system properties to standalone.xml

<system-properties>
    <property name="hawtio.authenticationEnabled" value="true" />
    <property name="hawtio.realm" value="hawtio-domain" />
</system-properties>

2. Add a security realm for Hawtio within the security subsystem

<security-domain name="hawtio-domain" cache-type="default">
    <authentication>
        <login-module code="RealmDirect" flag="required">
            <module-option name="realm" value="ManagementRealm"/>
        </login-module>
    </authentication>
</security-domain>

3. Configure a management user

$JBOSS_HOME/bin/add-user.sh -u someuser -p s3cret

Browse to http://localhost:8080/hawtio, and authenticate with the credentials configured for the management user.

10.2. JAX-RS Security

The following topics explain how to secure JAX-RS endpoints.

10.3. JAX-WS Security

The following topics explain how to secure JAX-WS endpoints.

10.4. JMS Security

The following topics explain how to secure JMS endpoints.

Additionally, you can use Camel’s notion of Route Policies to integrate with the WildFly security system.

10.5. Route Policy

Camel supports the notion of RoutePolicies, which can be used to integrate with the WildFly security system. There are currently two supported scenarios for security integration.

10.5.1. Camel calls into JavaEE

When a camel route calls into a secured JavaEE component, it acts as a client and must provide appropriate credentials associated with the call.

You can decorate the route with a ClientAuthorizationPolicy as follows:

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .policy(new ClientAuthorizationPolicy())
        .to("ejb:java:module/AnnotatedSLSB?method=doSelected");
    }
});

This does not do any authentication and authorization, as a part of the camel message processing. Instead, it associates the credentials that come with the Camel Exchange with the call into the EJB3 layer.

The client that calls the message consumer must provide appropriate credentials in the AUTHENTICATION header like this:

ProducerTemplate producer = camelctx.createProducerTemplate();
Subject subject = new Subject();
subject.getPrincipals().add(new DomainPrincipal(domain));
subject.getPrincipals().add(new EncodedUsernamePasswordPrincipal(username, password));
producer.requestBodyAndHeader("direct:start", "Kermit", Exchange.AUTHENTICATION, subject, String.class);

Authentication and authorization will happen in the JavaEE layer.

10.5.2. Securing a Camel Route

In order to secure a Camel Route, you can associate a DomainAuthorizationPolicy with the route. This policy requires a successful authentication against the given security domain and authorization for "Role2".

CamelContext camelctx = new DefaultCamelContext();
camelctx.addRoutes(new RouteBuilder() {
    @Override
    public void configure() throws Exception {
        from("direct:start")
        .policy(new DomainAuthorizationPolicy().roles("Role2"))
        .transform(body().prepend("Hello "));
    }
});
camelctx.start();

Again, the client that calls the message consumer must provide appropriate credentials in the AUTHENTICATION header like this:

ProducerTemplate producer = camelctx.createProducerTemplate();
Subject subject = new Subject();
subject.getPrincipals().add(new DomainPrincipal(domain));
subject.getPrincipals().add(new EncodedUsernamePasswordPrincipal(username, password));
producer.requestBodyAndHeader("direct:start", "Kermit", Exchange.AUTHENTICATION, subject, String.class);

11. Developer Info