Camel cheatsheet

Here is a Camel cheatsheet you can use to build your Camel routes quickly:

Processor Component

<bean id="myProcessor" class="com.mycompany.MyProcessor"/>

<process ref="myProcessor"/>
package com.mycompany;


import org.apache.camel.Processor;
import org.apache.camel.Exchange;

public class MyProcessor implements Processor {
        public void process(Exchange exchange) throws Exception {

                String payload = exchange.getIn().getBody(String.class);
                System.out.println("Payload"+payload);
                payload = payload.toLowerCase();
                exchange.getIn().setBody(payload);
        }
}

 

Bean Component

<bean id="mybean" class="com.mycompany.jb421.chapter10.Validate" />

<bean ref="mybean" method="doSomething"/>
import org.apache.camel.Exchange;

public class Validate {

    public void doSomething(Exchange exchange) {

        exchange.getIn().setBody("Bye World");
     }
}

How to use Properties in a Camel blueprint

Include in your project's classpath a Property file (e.g. sql.properties)

<camelContext  xmlns="http://camel.apache.org/schema/blueprint">

  <propertyPlaceholder location="classpath:sql.properties" id="properties"/>

   . . . .
  <to uri="sql:{{sql.insertCustInfo}}?alwaysPopulateStatement=true"/>

</camelContext>

Using Embedded ActiveMQ

<bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">
        <property name="connectionFactory">
                <bean class="org.apache.activemq.ActiveMQConnectionFactory">
                     <property name="brokerURL"
                        value="vm://localhost?broker.persistent=false&broker.useJmx=false" />
                </bean>
        </property>
</bean>

<from uri="jms:queue:myqueue"/>

Using Remote ActiveMQ

<bean id="jms" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://0.0.0.0:61616" />
</bean>

<from uri="jms:queue:myqueue"/>

How to create a Java Producer

package com.sample;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class ProducerExample {

	public static void main(String[] args) {

	try {

             // Create a ConnectionFactory
             ConnectionFactory connectionFactory=new ActiveMQConnectionFactory("admin", "admin", ActiveMQConnection.DEFAULT_BROKER_URL);

             // Create a Connection
             Connection connection = connectionFactory.createConnection();

             connection.start();

             // Create a Session
             Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

             // Create the destination
             Destination destination = session.createQueue("demoMQ");

             // Create a MessageProducer from the Session to the Queue
             MessageProducer producer = session.createProducer(destination);
             producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

             // Create a messages
             TextMessage message = session.createTextMessage("Helloworld");

             producer.send(message);
             session.close();
             connection.close();

             System.out.println("Message sent");

         }

         catch (Exception e) {

             System.out.println(e);
             e.printStackTrace();

         }

	}

}

How to catch Exception with OnException

<camelContext xmlns="http://camel.apache.org/schema/spring"   >
        <propertyPlaceholder location="fabric8/route.properties"
                id="properties" />
        <route>
                <from uri="file:/home/francesco/files/in?noop=true" />

                <onException>
                        <exception>org.xml.sax.SAXParseException</exception>
                        <handled>
                                <constant>true</constant>
                        </handled>
                        <log message="Transformation result in error ${body}" />
                    <to uri="file:/home/francesco/files/" />
                </onException>

                <choice>
                        <!-- condition here -->
                </choice>
        </route>
</camelContext>

How to use Try Catch Finally

      <doTry>
        <bean ref="myProcessor"/>
        <transform>
          <constant>Transformed!</constant>
        </transform>
        <doCatch>
          <exception>com.error.MyException</exception>
          <to uri="mock:error"/>
          <transform>
            <constant>An error happened!</constant>
          </transform>
        </doCatch>
        <doFinally>
          <to uri="mock:finally"/>
        </doFinally>
      </doTry>

How to code a DLQ Handler

<camelContext xmlns="http://camel.apache.org/schema/spring" errorHandlerRef="DLQhandler">


  <errorHandler id="DLQhandler" type="DeadLetterChannel" deadLetterUri="jms:queue:dead"
  useOriginalMessage="false"   />

  <route>
    <from uri="file:/home/francesco/files/in?noop=true"/>
    <bean ref="mybean" method="doSomething"/> <!-- In case of exception the message is routes to the DLQ -->
    <to uri="jms:queue:myqueue"/>
  </route>
</camelContext>

How to reference a RouteBuilder from Spring passing properties

<bean id="javaRouteBuilder" class="com.sample.JavaRouteBuilder" >
     <property name="queue" value="jms:queue:orders"/>
     <property name="path" value="/home/francesco/cli"/>
     <property name="pathOut" value="/home/francesco/cli/out"/>
</bean>
import org.apache.camel.builder.RouteBuilder;

public class JavaRouteBuilder extends RouteBuilder {

        String path;
        String pathOut;
        String queue;

        . . .

        public void configure() throws Exception {

                    from("file:"+path +"?noop=true").to("log:com.mycompany?level=DEBUG").process(new MyProcessor()).to("file:"+pathOut);

        }
}

An Hello World Camel example

public class App1 {

        public static void main(String args[]) throws Exception {
                // This is a Registry for Beans used in the route
                SimpleRegistry registry = new SimpleRegistry();
                registry.put("taxCalculator", new TaxCalculator());

                CamelContext context = new DefaultCamelContext(registry);
                context.addRoutes(new RouteBuilder() {

                        public void configure() throws Exception {
                                from(
                                                "file:/home/demo/in?noop=true&include=.*.csv")
                                                .beanRef("taxCalculator", "processTax").to(
                                                                "file:/home/demo/out");
                        }

                });

                context.start();

                System.out.println("Press enter to continue...");
                Scanner keyboard = new Scanner(System.in);
                keyboard.nextLine();
                context.stop();
        }

}

How to make Content Based Routig

Example: Header based CBR

<route>
        <from uri="file:/home/demo/in?noop=true" />
        <choice>
                <when>
                        <simple>${header.CamelFileName} regex '^.*xml$'</simple>
                        <to uri="file:/home/demo/out/xml" />
                </when>
                <otherwise>
                        <to uri="file:/home/demo/in/error" />
                </otherwise>
        </choice>
</route>

Example: Body based CBR

<choice>
          <when>
                    <simple>${bodyAs(String)} contains 'expensive'</simple>
                    <to uri="activemq:BigSpendersQueue"/>
          </when>
        <otherwise>
                <to uri="file:/home/demo/in/error" />
        </otherwise>
</choice>

<choice>
        <when>
                <xpath>/person/city = 'London'</xpath> <!-- TEXT -->
               <!--  <xpath>/CustInfo[@infotype="LoanCustomer"]</xpath> ATTRIBUTE -->
                <log message="UK message" />
                <to uri="file:target/messages/uk" />
        </when>
        <otherwise>
                <log message="Other message" />
                <to uri="file:target/messages/others" />
        </otherwise>
</choice>

How to set header in Camel (various examples)

<setHeader headerName="customer">
        <xpath>/Payments/Payment/customer/text()</xpath>
</setHeader>

<setHeader headerName="subject">
        <constant>new incident reported</constant>
</setHeader>

<setHeader headerName="CamelFileName">
        <method bean="filenameGenerator" method="generateFilename"/>
</setHeader>

<setHeader headerName="CityList">
    <simple>${listCity.ListCities()}</simple>
</setHeader>

How to set Body in Camel (various examples)

<transform>
  <simple>Hello ${bodyAs(String)} how are you?</simple>
</transform>

<convertBodyTo type="java.lang.String"/>

<transform>
  <simple>Hello ${bodyAs(String)} how are you?</simple>
</transform>

<transform>
<simple>${body.toUpperCase()}</simple>
</transform>

How to Filter Messages

<route>

        <from uri="jms:queue:inbox"/>

        <filter>
                <!-- Header test = false -->
                <xpath>$test = 'false'</xpath>
                <to uri="jms:queue:inbox"/>

        </filter>

</route>

Aggregation Strategy example

<bean id="myAggregationStrategy" class="com.sample.MyAggregationStrategy" />
<camelContext xmlns="http://camel.apache.org/schema/spring"
        trace="false">
        <route>
            <from uri="file:/home/demo/in/aggregate?noop=true" />
                <log message="Sending ${body}" />
                <aggregate strategyRef="myAggregationStrategy"
                        completionSize="2" completionTimeout="5000">
                        <!-- Aggregate messages based on the following Correlation Expression -->
                        <correlationExpression>
                                <xpath>/Payments/Payment/customer/text()</xpath>
                        </correlationExpression>
                        <log message="Sending out ${body}" />
                         <to uri="file:/home/demo/in?fileName=out.xml" />
                </aggregate>
        </route>
</camelContext>
public class MyAggregationStrategy implements AggregationStrategy {
        public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
                if (oldExchange == null) {

                        return newExchange;

                }

                String oldBody = oldExchange.getIn().getBody(String.class);
                String newBody = newExchange.getIn().getBody(String.class);
                String body = oldBody + newBody;

                oldExchange.getIn().setBody(body);
                return oldExchange;
        }
}

How to create a Recipient List (Dynamic Multicast)

<bean id="calculateRecipients" class="com.mycompany.jb421.chapter3.XMLProcessor" />

<process ref="calculateRecipients" />
<recipientList>
        <header>recipients</header>
</recipientList>
public class XMLProcessor implements Processor {

        @Override
        public void process(Exchange exchange) throws Exception {


                String recipients = "jms:others";
                String customer =
                exchange.getIn().getHeader("customer", String.class);

                // Send these messages also to another queue 
                if (customer.equals("JOHN DOE")) {
                recipients += ",jms:john";
                }
                exchange.getIn().setHeader("recipients", recipients);

        }

}

Multicast dispatching of Messages

<multicast strategyRef="myAggregationStrategy">
    <to uri="direct:callRest1" pattern="InOut"/>
    <to uri="direct:callRest2" pattern="InOut"/>
</multicast>
public class MyAggregationStrategy implements AggregationStrategy {
        public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
                if (oldExchange == null) {

                        return newExchange;

                }

                String oldBody = oldExchange.getIn().getBody(String.class);
                String newBody = newExchange.getIn().getBody(String.class);
                String body = oldBody + newBody;

                oldExchange.getIn().setBody(body);
                return oldExchange;
        }
}

Transformation

1. From CSV to Java Object

  <dataFormats>
     <bindy type="Csv" id="transform-csv" classType="com.demo.csv.Order" />
  </dataFormats>

  <route>
     <from uri="file:/home/demo/in?fileName=order.csv&noop=true"/>
     <unmarshal ref="transform-csv"/>
     <log message="${body}"/>
     <to uri="activemq:queue:orders"/>
  </route>
@CsvRecord(separator=",",crlf="UNIX")
public class Order implements Serializable{

// Getter-setters

@DataField(pos=1)
private int id;
@DataField(pos=2)
private String description;
@DataField(pos=3)
private double price;
@DataField(pos=4)
private double tax;
}

2. From XML to Object

<unmarshal>
        <jaxb contextPath="com.sample.xml"/>
        <!-- Class Order is in com.sample.xml package -->  
</unmarshal>
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Order {
    @XmlAttribute
    public int id;
    @XmlAttribute
    public String description;
    @XmlAttribute
    public double price;
    @XmlAttribute
    public double tax;

// Getter-setters


}
@XmlRegistry
public class ObjectFactory {

    public ObjectFactory() {
    }

    public Order createOrderInfo() {
        return new Order();
    }

}

3. From Java to XML

<marshal> 
    <jaxb contextPath="com.sample.chapter3.xml"/> 
</marshal> 

<b>3. From CSV to JSON</b>

sourceModel=com.sample.Customer
targetModel=com.sample.Account
   <camelContext trace="false" xmlns="http://camel.apache.org/schema/spring">
        
        <endpoint id="csv2json" uri="dozer:csv2json?unmarshalId=transform-csv&marshalId=transform-json&sourceModel=com.sample.Customer&targetModel=com.sample.Account&mappingFile=transformation.xml"/>

        <dataFormats>
            <bindy type="Csv" id="transform-csv" classType="com.sample.Customer" />
            <json library="Jackson" id="transform-json"/>

        </dataFormats>
        <route>
            <from uri="file:/home/demo/in?fileName=customers.csv&noop=true"/>

            <!-- Splitting messages tokenizing by carriage return --> 
            <split streaming="true">
                <tokenize token="\n" trim="true" />
                <log message="Transform input ${body} to json" />
                <to ref="csv2json" />
                <to uri="file:/home/demo/out?fileName=csv-record-${date:now:yyyyMMdd}-${property.CamelSplitIndex}.txt"/>
            </split>
        </route>
    </camelContext>

transformation.xml file with mappings:

<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://dozer.sourceforge.net http://dozer.sourceforge.net/schema/beanmapping.xsd">
    <configuration>
        <wildcard>false</wildcard>
    </configuration>
    <mapping>
        <class-a>com.sample.Customer</class-a>
        <class-b>com.sample.Account</class-b>
        <!-- Map fields here from Customer to Account --> 
        <field>
            <a>customerId</a>
            <b>accountId</b>
        </field>
         . . .
    </mapping>
</mappings>

Split and Tokenize

<split streaming="true">
        <tokenize token="\n" trim="true" />
        <log message="Transform input ${body} to json" />
        <to uri="file:/home/demo/out?fileName=csv-record-${date:now:yyyyMMdd}-${property.CamelSplitIndex}.txt"/>
</split>

Split with Custom Thread Pool

<bean id="threadPool" class="java.util.concurrent.Executors" factory-method="newFixedThreadPool">
   <constructor-arg index="0" value="20"/>
</bean>

<split executorServiceRef="threadPool">
        <tokenize token="\n" trim="true" />
        <log message="Transform input ${body} to json" />
        <to uri="file:/home/demo/out?fileName=csv-record-${date:now:yyyyMMdd}-${property.CamelSplitIndex}.txt"/>
</split>

Split using an XPath expression

<split>
       <xpath>/Payments/Payment</xpath>
       <to uri="targetUri"/>
</split>
<split>
       <xpath>/PurchaseOrder/@PurchaseOrderNumber</xpath>
       <to uri="targetUri"/>
</split>

Velocity example

  <route>
     <from uri="file:/home/demo/in?fileName=order.xml&noop=true"/>
     <unmarshal ref="transform-xml"/>

     <to uri="velocity:etc/MailBody.vm"/>
     <to uri="file:/home/demo/out"/>
  </route>

file etc/MailBody.vm

#set( $order = ${body})

Order status:
- Id: ${order.id}
- Price: ${order.price}

Tax: ${order.tax}

Details:
${order.description}

JDBC example

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  <property name="driverClassName" value="org.h2.Driver"/>
  <property name="url" value="jdbc:h2:file:~/h2/homeloan;AUTO_SERVER=TRUE"/>
  <property name="username" value="sa"/>
  <property name="password" value=""/>
</bean>

<bean id="sql" class="org.apache.camel.component.sql.SqlComponent">
  <property name="dataSource" ref="dataSource"/>
</bean>

<route>
. . .

        <!-- Execute a Delete and Insert -->

        <to uri="sql:{{sql.deleteCustInfo}}?alwaysPopulateStatement=true" />
        <to uri="sql:{{sql.insertCustInfo}}?alwaysPopulateStatement=true"/>

</route>

Sample SQL file:

sql.insertCustInfo=INSERT INTO CustInfo (nationalID, firstName, lastName, age, occupation) values (:#${body.nationalID}, :#${body.firstName}, :#${body.lastName}, :#${body.age}, :#${body.occupation})
sql.deleteCustInfo=delete from CustInfo where nationalID = :#${body.nationalID};

JPA Example: From XML file to Database

<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent">
                <property name="entityManagerFactory" ref="entityManagerFactory" />
                <property name="transactionManager" ref="jpaTxManager" />
</bean>
<bean id="jpaTxManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="persistenceUnit" />
</bean>

<camelContext trace="true" xmlns="http://camel.apache.org/schema/spring">

        <route>

         <from uri="file:/home/demo/person?noop=true" />
                <!-- Unmarshal files from XML to JPA -->
                <unmarshal>
                        <jaxb contextPath="com.demo.model" prettyPrint="true" />
                </unmarshal>
                <to uri="jpa:com.demo.model.Person" />
        </route>
</camelContext>

 

@XmlRootElement
@XmlType
@Entity(name="Person")
@NamedQuery(name="Person.findAll", query="SELECT c FROM Person c")
public class Person {
    private Long id;
private String name;
private String surname;

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
    return id;
}

// Getter-setters

}
@XmlRegistry
public class ObjectFactory {


    public ObjectFactory() {   }


    public Person createPerson() {
        return new Person();
    }

}

JPA: From Database to XML

  <dataFormats>
    <jaxb contextPath="com.sample.model" id="jaxb-xml"/>
  </dataFormats>
  <route>
    <from uri="jpa:com.sample.model.Person?consumeDelete=false&consumer.namedQuery=Person.findAll"/>
    <marshal ref="jaxb-xml"/>
    <to uri="file:/home/demo/in/person/fileout"/>
      <stop/>
  </route>

How to expose a CXF Web service

  <cxf:cxfEndpoint id="claimEndpoint" address="/claim" serviceClass="org.demo.ClaimService" />

  <bean id="claimProcessor" class="org.demo.ClaimProcessor" />

  <camelContext trace="false" id="blueprintContext" xmlns="http://camel.apache.org/schema/blueprint">
    <route id="cxfRoute">
        <from uri="cxf:bean:claimEndpoint"/>
        <log message="${header.operationName}"/>
        <recipientList>
            <!-- Based on the Operation request, create a recipient list to execute a Processor methos --> 
            <simple>direct:${header.operationName}</simple>
        </recipientList>
    </route>
    <route id="executeRoute">
        <from uri="direct:execute"/>
        <bean method="process" ref="claimProcessor"/>
    </route>
    <route id="cancelRoute">
        <from uri="direct:cancel"/>
        <bean method="cancel" ref="claimProcessor"/>
    </route>

</camelContext>

How to expose a CXF Rest service

  <cxf:rsServer id="statusEndpoint" address="/status" serviceClass="org.demo.StatusService" />

  <bean id="claimProcessor" class="org.demo.ClaimProcessor" />

    <route>
        <from uri="cxfrs:bean:statusEndpoint"/>
        <log message="${header.operationName}"/>
            <!-- Choice based on the operationName contained in the Header --> 
        <choice>
            <when>
                <simple>${header.operationName} == "status"</simple>
                <bean method="status" ref="claimProcessor"/>
            </when>
            <when>
                <simple>${header.operationName} == "restCancel"</simple>
                <setHeader headerName="operationName">
                    <simple>cancel</simple>
                </setHeader>
                <bean method="prepareList" ref="claimProcessor"/>
                <to uri="cxf:bean:claimEndpoint"/>
            </when>
        </choice>
        <marshal>
            <json library="Jackson" prettyPrint="true"/>
        </marshal>
    </route>

</camelContext>

Timer

  <route>
    <from uri="timer:timerName?period=60000"/>
    <to uri="http://camel.apache.org"/>
    <to uri="file:/home/francesco/Desktop/FUSE/in/person/fileout"/>
  </route>

Jetty

  <route>
    <from uri="jetty:http://localhost:8080/myservice"/>
    <process ref="processorBean"/> <!-- ritorna HTML -->
  </route>

Mock Test example

public class TestWithMock extends CamelTestSupport {

        @Override
        protected CamelContext createCamelContext() throws Exception {
                CamelContext context = super.createCamelContext();
                context.addComponent("jms", context.getComponent("seda"));
                return context;
        }

        @Override
        protected RouteBuilder createRouteBuilder() throws Exception {
                return new RouteBuilder() {
                        @Override
                        public void configure() throws Exception {
                                from("direct:start")
                                 .convertBodyTo(String.class) //
                 .process(new Processor() {

                     @Override
                     public void process(Exchange exc) throws Exception {
                         String body = exc.getIn().getBody(String.class);
                         exc.getIn().setBody(body.toUpperCase());


                     }
                 })
                                .to("mock:orders");
                        }
                };
        }

        @Test
        public void testMock() throws Exception {
                MockEndpoint mock = getMockEndpoint("mock:orders");
                mock.expectedMessageCount(1);
                mock.expectedBodiesReceived("JB421 COURSE");
                context.createProducerTemplate().sendBody("direct:start", "jb421 Course");
                mock.assertIsSatisfied();
                List<Exchange> exchanges = mock.getReceivedExchanges();
                String body = exchanges.get(0).getIn().getBody(String.class);
                assertTrue(body.contains("JB421"));
        }
}


Advertisement

Cookie Alert