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 Routing
Example: Header based CBR
<route> <from uri="file:/home/demo/in?noop=true" /> <choice> <when> <simple>${header.CamelFileName} regex '^.*xml
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")); } }