5.2. Examples of JBoss Fuse on EAP
This section includes the working examples that demonstrate various features of JBoss on Fuse EAP. These examples will help you get started with the EAP Camel subsystem.
Note
You can access the
$JBOSS_HOME/quickstarts/camel
directory to view the full source code of all the examples.
To run the given examples, ensure that you install the following on your machine:
- Maven 3.2.3 or greater
- Java 1.7 or greater
- Red Hat JBoss Fuse 6.3
- Red Hat JBoss EAP 6.4
Note
To install JBoss Fuse on EAP, see chapter "Install JBoss Fuse on JBoss EAP" in "Installation on JBoss EAP".
5.2.1. Camel ActiveMQ
The following example describes how to use the
camel-activemq
component with JBoss Fuse on EAP, to produce and consume JMS messages.
In this example, a camel route consumes files from the
${JBOSS_HOME}/standalone/data/orders
directory and place the content to an external ActiveMQ JMS queue. A second route consumes messages from the OrdersQueue and then via a content based router, it sorts the directory of each country that are located within the $JBOSS_HOME/standalone/data/orders/processed
directory.
Note
The CLI script automatically configure the ActiveMQ resource adapter. These scripts are located within the
src/main/resources/cli
directory.
5.2.1.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
- An ActiveMQ broker
Procedure 5.1. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
5.2.1.2. Configuring ActiveMQ
Here are the details to configure the ActiveMQ component:
@Startup @CamelAware @ApplicationScoped public class ActiveMQRouteBuilder extends RouteBuilder { /** * Inject the ActiveMQConnectionFactory that has been configured through the ActiveMQ Resource Adapter */ @Resource(mappedName = "java:/ActiveMQConnectionFactory") private ConnectionFactory connectionFactory; @Override public void configure() throws Exception { /** * Configure the ActiveMQ component */ ActiveMQComponent activeMQComponent = ActiveMQComponent.activeMQComponent(); activeMQComponent.setConnectionFactory(connectionFactory); getContext().addComponent("activemq", activeMQComponent); /** * This route reads files placed within $JBOSS_HOME/standalone/data/orders * and places them to ActiveMQ queue 'ordersQueue' */ from("file://{{jboss.server.data.dir}}/orders") .convertBodyTo(String.class) // Remove headers to ensure we end up with unique file names being generated in the next route .removeHeaders("*") .to("activemq:queue:OrdersQueue"); /** * This route consumes messages from the 'ordersQueue'. Then, based on the * message payload XML content it uses a content based router to output * orders into appropriate country directories */ from("activemq:queue:OrdersQueue") .choice() .when(xpath("/order/customer/country = 'UK'")) .log("Sending order ${file:name} to the UK") .to("file:{{jboss.server.data.dir}}/orders/processed/UK") .when(xpath("/order/customer/country = 'US'")) .log("Sending order ${file:name} to the US") .to("file:{{jboss.server.data.dir}}/orders/processed/US") .otherwise() .log("Sending order ${file:name} to another country") .to("file://{{jboss.server.data.dir}}/orders/processed/Others"); } }
5.2.1.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -PdeployIt removes the ActiveMQ resource adapter configuration. However, you need to restart the application after you execute the undeploy command.
5.2.2. Camel CDI
The following example describes how to use the
camel-cdi
component with JBoss Fuse on EAP, to integrate CDI beans with camel routes.
In this example, a camel route takes a message payload from a servlet HTTP GET request and passes it to the direct endpoint. However, you can pass the payload to a Camel CDI bean invocation to produce a message response. It displays the message response on the web browser page.
5.2.2.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.2. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
5.2.2.2. Configuring Camel CDI
Here are the details to configure the
camel-cdi
component:
@Startup @CamelAware @ApplicationScoped public class MyRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { from("direct:start").bean("helloBean"); } }
@SuppressWarnings("serial") @WebServlet(name = "HttpServiceServlet", urlPatterns = { "/*" }, loadOnStartup = 1) public class SimpleServlet extends HttpServlet { @Inject private CamelContext camelctx; @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String name = req.getParameter("name"); ServletOutputStream out = res.getOutputStream(); ProducerTemplate producer = camelctx.createProducerTemplate(); String result = producer.requestBody("direct:start", name, String.class); out.print(result); } }
5.2.2.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy
5.2.3. Camel JMS
The following example describes how to use the
camel-jms
component with JBoss Fuse on EAP to produce and consume JMS messages.
In this example, a Camel route consumes files from the
${JBOSS_HOME}/standalone/data/orders
directory and place the content in the OrdersQueue. A second route consumes messages from the OrdersQueue and through a content based router.
5.2.3.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.3. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
5.2.3.2. Configuring Camel JMS
Here are the details to configure the camel-jms component.
@Startup @CamelAware @ApplicationScoped public class JmsRouteBuilder extends RouteBuilder { @Resource(mappedName = "java:/ConnectionFactory") private ConnectionFactory connectionFactory; @Override public void configure() throws Exception { /** * Configure the JMSComponent to use the connection factory * injected into this class */ JmsComponent component = new JmsComponent(); component.setConnectionFactory(connectionFactory); getContext().addComponent("jms", component); /** * This route reads files placed within $JBOSS_HOME/standalone/data/orders * and places them onto JMS queue 'ordersQueue' within the WildFly * internal HornetQ broker. */ from("file://{{jboss.server.data.dir}}/orders") .convertBodyTo(String.class) // Remove headers to ensure we end up with unique file names being generated in the next route .removeHeaders("*") .to("jms:queue:OrdersQueue"); /** * This route consumes messages from the 'ordersQueue'. Then, based on the * message payload XML content it uses a content based router to output * orders into appropriate country directories */ from("jms:queue:OrdersQueue") .choice() .when(xpath("/order/customer/country = 'UK'")) .log("Sending order ${file:name} to the UK") .to("file:{{jboss.server.data.dir}}/orders/processed/UK") .when(xpath("/order/customer/country = 'US'")) .log("Sending order ${file:name} to the US") .to("file:{{jboss.server.data.dir}}/orders/processed/US") .otherwise() .log("Sending order ${file:name} to another country") .to("file://{{jboss.server.data.dir}}/orders/processed/others"); } }
5.2.3.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy
5.2.4. Camel JPA
The following example describes how to use the
camel-jpa
component with JBoss Fuse on EAP to persist entities to the in-memory database.
In this example, a camel route consumes XML files from the
${JBOSS_HOME}/standalone/data/customers
directory. Camel then uses JAXB to unmarshal the data to a Customer entity. However, the entity is then passed to the JPA endpoint and is persisted to the customer database.
5.2.4.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.4. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
5.2.4.2. Configuring Camel JPA
Here are the details to configure the
camel-jpa
component.
@Startup @CamelAware @ApplicationScoped public class JpaRouteBuilder extends RouteBuilder { @Inject private EntityManager em; @Inject UserTransaction userTransaction; @Override public void configure() throws Exception { // Configure our JaxbDataFormat to point at our 'model' package JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(); jaxbDataFormat.setContextPath(Customer.class.getPackage().getName()); EntityManagerFactory entityManagerFactory = em.getEntityManagerFactory(); // Configure a JtaTransactionManager by looking up the JBoss transaction manager from JNDI JtaTransactionManager transactionManager = new JtaTransactionManager(userTransaction); transactionManager.afterPropertiesSet(); // Configure the JPA endpoint to use the correct EntityManagerFactory and JtaTransactionManager JpaEndpoint jpaEndpoint = new JpaEndpoint(); jpaEndpoint.setCamelContext(getContext()); jpaEndpoint.setEntityType(Customer.class); jpaEndpoint.setEntityManagerFactory(entityManagerFactory); jpaEndpoint.setTransactionManager(transactionManager); /* * Simple route to consume customer record files from directory input/customers, * unmarshall XML file content to a Customer entity and then use the JPA endpoint * to persist the it to the 'ExampleDS' datasource (see standalone.camel.xml for datasource config). */ from("file://{{jboss.server.data.dir}}/customers") .unmarshal(jaxbDataFormat) .to(jpaEndpoint) .to("log:input?showAll=true"); } }
public class CustomerRepository { @Inject private EntityManager em; /** * Find all customer records * * @return A list of customers */ public List<Customer> findAllCustomers() { CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder(); CriteriaQuery<Customer> query = criteriaBuilder.createQuery(Customer.class); query.select(query.from(Customer.class)); return em.createQuery(query).getResultList(); } }
5.2.4.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy
5.2.5. Camel Mail
The following example describes how to use the
camel-mail
component with JBoss Fuse on EAP to send and receive email.
In this example, you can configure a local mail server on your machine. This eliminates the need to use any external mail services. You can access the
src/main/resources/cli
directory to see the EAP mail subsystem configuration.
Note
Here the mail session used is bound to JNDI at the
java:jboss/mail/
location. You can configure the server entries for SMTP and POP3 protocols.
5.2.5.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.5. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
Note
If you want to deploy the application multiple times, ensure that you run the undeploy command and restart the application server.
5.2.5.2. Configuring Camel Mail
Here are the configurations details to configure the
camel-mail
component.
public class MailSessionProducer { @Resource(lookup = "java:jboss/mail/greenmail") private Session mailSession; @Produces @Named public Session getMailSession() { return mailSession; } }
@Startup @CamelAware @ApplicationScoped public class MailRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { // Configure routes and endpoints to send and receive email over SMTP and POP3 from("direct:sendmail").to("smtp://localhost:10025?session=#mailSession"); from("pop3://user2@localhost:10110?consumer.delay=30000&session=#mailSession").to("log:emails?showAll=true&multiline=true"); } }
5.2.5.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy
5.2.6. Camel REST
The following example describes how to write the JAX-RS REST routes with JBoss Fuse on EAP.
It includes two methods of implementing Camel REST consumers. Requests made to paths under the
/example-camel-rest/camel
are handled by the Camel REST DSL and requests made to paths >/example-camel-rest/rest
are handled by the EAP JAX-RS subsystem along with the CamelProxy.
5.2.6.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.6. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
5.2.6.2. Configuring Camel REST
Here are the configurations details to configure the Camel REST routes.
@Startup @CamelAware @ApplicationScoped public class RestConsumerRouteBuilder extends RouteBuilder { /** * Inject a service for interacting with the EAP exampleDS in-memory database. */ @Inject private CustomerRepository customerRepository; @Override public void configure() throws Exception { /** * Configure the Camel REST DSL to use the camel-servlet component for handling HTTP requests. * * Whenever a POST request is made to /customer it is accompanied with a JSON string representation * of a Customer object. Note that the binding mode is set to RestBindingMode.json. This will enable * Camel to unmarshal JSON to the desired object type. * * Note that the contextPath setting below has no effect on how the application server handles HTTP traffic. * The context root and required servlet mappings are configured in WEB-INF/jboss-web.xml and WEB-INF/web.xml. * */ restConfiguration().component("servlet").contextPath("/camel-example-rest/camel").port(8080).bindingMode(RestBindingMode.json); /** * Handles requests to a base URL of /camel-example-rest/camel/customer */ rest("/customer") /** * Handles GET requests to URLs such as /camel-example-rest/camel/customer/1 */ .get("/{id}") /** * Marshalls the response to JSON */ .produces(MediaType.APPLICATION_JSON) .to("direct:readCustomer") /** * Handles POST requests to /camel-example-rest/camel/customer */ .post() /** * Unmarshalls the JSON data sent with the POST request to a Customer object. */ .type(Customer.class) .to("direct:createCustomer"); /** * This route returns a JSON representation of any customers matching the id * that was sent with the GET request. * * If no customer was found, an HTTP 404 response code is returned to the calling client. */ from("direct:readCustomer") .bean(customerRepository, "readCustomer(${header.id})") .choice() .when(simple("${body} == null")) .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(404)); /** * This route handles persistence of new customers. */ from("direct:createCustomer") .bean(customerRepository, "createCustomer"); /** * This route handles REST requests that have been made to the RESTful services defined within * CustomerServiceImpl. * * These services are running under the WildFly RESTEasy JAX-RS subsystem. A CamelProxy proxies the direct:rest * route so that requests can be handled from within a Camel route. */ from("direct:rest") .process(new Processor() { @Override public void process(Exchange exchange) throws Exception { /** * Retrieve the message payload. Since we are using camel-proxy to proxy the direct:rest * endpoint the payload will be of type BeanInvocation. */ BeanInvocation beanInvocation = exchange.getIn().getBody(BeanInvocation.class); /** * Get the invoked REST service method name and build a response to send * back to the client. */ String methodName = beanInvocation.getMethod().getName(); if (methodName.equals("getCustomers")) { /** * Retrieve all customers and send back a JSON response */ List<Customer> customers = customerRepository.findAllCustomers(); exchange.getOut().setBody(Response.ok(customers).build()); } else if(methodName.equals("updateCustomer")) { /** * Get the customer that was sent on this method call */ Customer updatedCustomer = (Customer) beanInvocation.getArgs()[0]; Customer existingCustomer = customerRepository.readCustomer(updatedCustomer.getId()); if(existingCustomer != null){ if(existingCustomer.equals(updatedCustomer)) { /** * Nothing to be updated so return HTTP 304 - Not Modified. */ exchange.getOut().setBody(Response.notModified().build()); } else { customerRepository.updateCustomer(updatedCustomer); exchange.getOut().setBody(Response.ok().build()); } } else { /** * No customer exists for the provided id, so return HTTP 404 - Not Found. */ exchange.getOut().setBody(Response.status(Response.Status.NOT_FOUND).build()); } } else if(methodName.equals("deleteCustomer")) { Long customerId = (Long) beanInvocation.getArgs()[0]; Customer customer = customerRepository.readCustomer(customerId); if(customer != null) { customerRepository.deleteCustomer(customerId); exchange.getOut().setBody(Response.ok().build()); } else { /** * No customer exists for the provided id, so return HTTP 404 - Not Found. */ exchange.getOut().setBody(Response.status(Response.Status.NOT_FOUND).build()); } } else if(methodName.equals("deleteCustomers")) { customerRepository.deleteCustomers(); /** * Return HTTP status OK. */ exchange.getOut().setBody(Response.ok().build()); } } }); } }
@Startup @CamelAware @ApplicationScoped public class RestProducerRouteBuilder extends RouteBuilder { @Override public void configure() throws Exception { /** * This route demonstrates a JAX-RS producer using the camel-restlet component. * * Every 30 seconds, a call is made to the REST API for retrieving all customers at * the URL http://localhost:8080/example-camel-rest/rest/customer. * * The results of the REST service call are written to a file at: * * $JBOSS_HOME/standalone/data/customer-records/customers.json */ from("timer://outputCustomers?period=30000") .to("restlet://http://localhost:8080/example-camel-rest/rest/customer") .choice() .when(simple("${header.CamelHttpResponseCode} == 200")) .log("Updating customers.json") .setHeader(Exchange.FILE_NAME, constant("customers.json")) .to("file:{{jboss.server.data.dir}}/customer-records/") .otherwise() .log("REST request failed. HTTP status ${header.CamelHttpResponseCode}"); } }
5.2.6.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy
5.2.7. Camel Transacted JMS
The following example describes how to use the
camel-jms
component with JBoss Fuse on EAP to produce and consume JMS messages in a transacted session.
In this example, a camel route consumes files from the
${JBOSS_HOME}/standalone/data/orders
directory and place the content in the OrdersQueue. A second route consumes messages from the OrdersQueue, converts the message body to the Order entity and persists it.
5.2.7.1. Running the Application
Before you start running the application, make sure that the following are installed on your machine:
- Maven 3.2.3 or greater
- JBoss Fuse on EAP
Procedure 5.7. To run the application
Perform the following steps:
- Start the application server in standalone mode.
${JBOSS_HOME}/bin/standalone.sh -c standalone-full.xml
- Run the following command to build and deploy the project.
mvn install -Pdeploy
- When the server starts, navigate to the
example-camel-transacted-jms/orders
directory.
The application displays the
page. It includes the list of processed orders.
5.2.7.2. Configuring Transacted JMS
Here are the details to configure the
camel-jms
component in a transacted session.
@Startup @CamelAware @ApplicationScoped public class JmsRouteBuilder extends RouteBuilder { /** * Inject the resources required to configure the JMS and JPA Camel * components. The JPA EntityManager, JMS TransactionManager and a JMS * ConnectionFactory bound to the JNDI name java:/JmsXA */ @Inject private EntityManager entityManager; @Inject private JmsTransactionManager transactionManager; @Resource(mappedName = "java:/JmsXA") private ConnectionFactory connectionFactory; @Override public void configure() throws Exception { /** * Create an instance of the Camel JmsComponent and configure it to support JMS * transactions. */ JmsComponent jmsComponent = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager); getContext().addComponent("jms", jmsComponent); /** * Create an instance of the Camel JpaComponent and configure it to support transactions. */ JpaComponent jpaComponent = new JpaComponent(); jpaComponent.setEntityManagerFactory(entityManager.getEntityManagerFactory()); jpaComponent.setTransactionManager(transactionManager); getContext().addComponent("jpa", jpaComponent); /** * Configure JAXB so that it can discover model classes. */ JaxbDataFormat jaxbDataFormat = new JaxbDataFormat(); jaxbDataFormat.setContextPath(Order.class.getPackage().getName()); /** * Configure a simple dead letter strategy. Whenever an IllegalStateException * is encountered this takes care of rolling back the JMS and JPA transactions. The * problem message is sent to the WildFly dead letter JMS queue (DLQ). */ onException(IllegalStateException.class) .maximumRedeliveries(1) .handled(true) .to("jms:queue:DLQ") .markRollbackOnly(); /** * This route consumes XML files from $JBOSS_HOME/standalone/data/orders and sends * the file content to JMS destination OrdersQueue. */ from("file:{{jboss.server.data.dir}}/orders") .transacted() .to("jms:queue:OrdersQueue"); /** * This route consumes messages from JMS destination OrdersQueue, unmarshalls the XML * message body using JAXB to an Order entity object. The order is then sent to the JPA * endpoint for persisting within an in-memory database. * * Whenever an order quantity greater than 10 is encountered, the route throws an IllegalStateException * which forces the JMS / JPA transaction to be rolled back and the message to be delivered to the dead letter * queue. */ from("jms:queue:OrdersQueue") .unmarshal(jaxbDataFormat) .to("jpa:Order") .choice() .when(simple("${body.quantity} > 10")) .log("Order quantity is greater than 10 - rolling back transaction!") .throwException(new IllegalStateException()) .otherwise() .log("Order processed successfully"); } }
5.2.7.3. Undeploy the Application
Run the following command to undeploy the application:
mvn clean -Pdeploy