In this chapter, we will understand the different Camel Concepts. Let us start by taking a basic example to understand core concepts to begin with.
Every camel application will have at least one CamelContext. This is the place where we add camel routes. It is similar to ApplicationContext of Spring.
Camel context can be thought as a container which keeps all things together. One camel context can have multiple routes inside it.
CamelContext may contain one or more routes. Routes are the integration logic which defines how data will flow in camel context from one endpoint to another.
Endpoint is end of channel through which system can send or receive messages. This is what we call as destination or source in communication language.
Components are point of extension in Camel. Components can be an interface to technology, data format, transformers, etc. They may also act as a factory for endpoints.
EIP stands for Enterprise Integration Pattern. These are identified and well-known solutions to a recurring problem. Camel supports most of the Enterprise Integration Patterns.
CBR patterns allow us to route data as per the content of the input file.
This pattern is used when we have to route values depending on the contents of the body of input.
The following example will read data from D:/data/input directory. After reading, it will check for value tag inside the data tag. If the value tag contains value1, it will be sent to D:/value1, If it contains value2, it will be sent to D:/value2 and if none of these both, then it will be sent to others.
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "file:///D:/data/input"/> <choice> <when> <xpath>/data/value = 'value1'</xpath> <to uri = "file:///D:/value1"/> </when> <when> <xpath>/data/value = 'value2'</xpath> <to uri = "file:///D:/value2"/> </when> <otherwise> <to uri = "file:///D:/others "/> </otherwise> </choice> </route> </camelContext>
Input
D:/data/input/message1.xml
<data> <value>value1</value> </data>
D:/data/input/message2.xml
<data> <value>value2</value> </data>
Output
D:/value1/
<data> <value>value1</value> </data>
D:/value2/
<data> <value>value2</value> </data>
A splitter pattern is used to split input data into smaller chunks.
This pattern is used most of the times with huge data input which requires to be split in chunks, so it becomes process-able. It breaks down input into smaller fragments based on input token string.
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "file:///D:/inbox"/> <split streaming = "true"> <tokenize token = "order" xml = "true"/> <to uri = "activemq:queue:order"/> </split> </route> </CamelContext>
Input
D:/inbox/message.xml
<order> <data> <value>value1</value> </data> </order> <order> <data> <value>value2</value> </data> </order> <order> <data> <value>value3</value> </data> </order>
Output
If you check AMQ you will find 3 messages posted.
<order> <data> <value>value4</value> </data> </order>
A recipient list pattern is used when a list of recipient needs to be retrieved from the message body itself.
In the following example, a message will be sent to all the recipients who are listed in the customer tag as comma separated list of strings.
<CamelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "jms:xmlOrders" /> <recipientList> <xpath>/order/customer</xpath> </recipientList> </route> </camelContext>
Camel provides support to almost all the EIPs identified. Some of commonly used EIP are as mentioned below.
Log − To log complete message or part of it
Message Filter − Filtering contents of messages
Re-Sequencer − To get all tokens in sequence
Wiretap − To inspect travelling messages
The complete list of EIP and their usage can be found at Camel’s official documentation http://camel.apache.org/eip.html
Using Error Handler − This is the easiest way to handle exceptions in camel.
To use this, we have to configure Error handler class bean and provide it as reference to CamelContext errorHandlerRef attribute.
<bean id = "loggingErrorHandler" class = "org.apache.camel.builder.LoggingErrorHandler"> <property name = "logName" value = "mylogger.name"/> <property name = "level" value = "DEBUG"/> </bean> <camelContext errorHandlerRef = ” loggingErrorHandler” > … </camelContext>
Camel also supports Java style Try Catch Finally block for error handling.
Just like Java, it has the following three blocks −
doTry block contains code that may generate exception.
doCatch block contains code that needs to be executed in case of exception.
doFinally block has code that must be executed irrespective of exception. It will always be executed no matter if exception was raised or not.
Note − Mock is testing component and not recommended for other purposes. It is the component in camel used for testing just like jMOck component in Test driven development.
<route> <from uri = "direct:start"/> <doTry> <process ref = "someProcesorThatmayFail"/> <to uri = "mock:result"/> <doCatch> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <to uri = "mock:catch"/> </doCatch> <doFinally> <to uri = "mock:finally"/> </doFinally> </doTry> </route>
In the above example, we can give a list of exceptions that need to be handled by the catch block.
Start Fuse using Fuse.bat/start.bat.
If you start Fuse using start.bat, use client.bat to connect to Fuse. You should get the UI as shown in the following screenshot.
This is the CLI for accessing Karaf and Fuse commands.
install –s mvn:group.id /artifact.id/version e.g. install –s mvn:com.tutorialpoint.app/camel-firt-app/1.0-SNAPSHOT