Apache Camel is a neat framework if your application requires customizable workflows, components and a wide array of input and output adapters. This post demonstrates how to use Camel with Spring and XML to define routes.
Route
The dependencies
The following dependencies are needed for using Camel with Spring dependency injection along with with the ability to use XML files and Elastic search.
- camel-core
- camel-spring
- camel-stream
- camel-spring-xml
- camel-elasticsearch-rest
- spring-context
<dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-stream</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring-xml</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-elasticsearch-rest</artifactId> <version>${camel.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>${gson.version}</version> </dependency> </dependencies>
The route
The entire flow shown in the diagram is defined in the routes.xml file.
<?xml version = "1.0" encoding = "UTF-8"?> <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"> <bean name="lowerCaser" class="com.sbytestream.processors.LowerCaser"></bean> <bean name="emailParser" class="com.sbytestream.processors.EmailParser"></bean> <bean name="jsonConvertor" class="com.sbytestream.processors.JsonConvertor"></bean> <bean name="spamIdentifier" class="com.sbytestream.processors.SpamIdentifier"> <property name="blockedSenders"> <list> <value>manish@email.com</value> <value>rajesh@email.com</value> </list> </property> </bean> <bean name="elasticsearch-rest" class="org.apache.camel.component.elasticsearch.ElasticsearchComponent"> <property name="hostAddresses" value="localhost:9200"></property> <property name="user" value="elastic"></property> <property name="password" value="builder!12"></property> </bean> <camelContext xmlns = "http://camel.apache.org/schema/spring" id="camel"> <route> <from uri="file://data/input" /> <process ref="emailParser" /> <process ref="spamIdentifier" /> <choice> <when> <simple>${exchangeProperty.spam} == 'true'</simple> <to uri="file://data/spam" /> </when> <otherwise> <process ref="jsonConvertor" /> <to uri="file://data/output" /> <to uri="elasticsearch-rest://elasticsearch?operation=INDEX&indexName=mails" /> </otherwise> </choice> </route> </camelContext> </beans>
Reading emails
Input emails are stored in the 'data/input' folder in the current directory. The format of the email file is mocked, for the purpose of the demo, the file structure should be as shown below:
from:siddharth@email.com to:neel@email.com subject:hello world content:this email is a test email for telling Hello World Emails are read as plain files using the file:// protocol. Two sample email files are available in the data directory, these can be copied into the input folder for testing.
Processing emails
Email files are sent to the EmailParser class for converting the content to a POJO. The POJO is then sent to the SpamIdentifier. The SpamIdentifier class checks if the sender is one of the email addresses in its list of blocked senders. It adds a new property named "spam" to "true".
Output
The output of spam processing is sent to a check block where spam emails are stored in a folder named "spam" and other emails are sent to Elastic Search in an index named "mails" using the ElasticsearchComponent. You can query these items using the following request:
GET mails/_search { "query": { "match_all": {} } }
Wiring everything together
Components and wiring are defined in the routes.xml file.
Elastic search configuration
Make sure you have set the Elastic Search configuration to match your setup. This is defined in the routes.xml file as well. The sample code for this article is available for download at GitHub.