Partner – Microsoft – NPI (cat= Spring)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

1. Overview

This article will demonstrate how to configure and use Apache Camel with Spring.

Apache Camel provides quite a lot of useful components that support libraries such as JPA, Hibernate, FTP, Apache-CXF, AWS-S3 and of course many others – all to help integrating data between two different systems.

For example, using the Hibernate and Apache CXF components, you could pull data from a database and send it to another system over REST API calls.

In this tutorial, we’ll go over a simple Camel example – reading a file and converting its contents to uppercase and then back to lowercase. We’re going to use Camel’s File component and Spring 4.2.

Here are the full details of the example:

  1. Read file from source directory
  2. Convert file content to uppercase using a custom Processor
  3. Write converted output to a destination directory
  4. Convert file content to lowercase using Camel Translator
  5. Write converted output to a destination directory

2. Add Dependencies

To use Apache Camel with Spring, you will need the following dependencies in your POM file:

<properties>
    <camel.version>4.3.0</camel.version>
    <spring.version>5.3.25</spring.version>
</properties>

<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.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
</dependencies>

So, we have:

  • camel-core – the main dependency for Apache Camel
  • camel-spring – enables us use Camel with Spring
  • camel-stream – an optional dependency, which you can use (for example) to display some messages on the console while routes are running
  • spring-context – the standard Spring dependency, required in our case as we are going to run Camel routes in a Spring context

3. Spring Camel Context

First, we’ll create the Spring Config file where we will later define our Camel routes.

Notice how the file contains all required Apache Camel and Spring namespaces and schema locations:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:camel="http://camel.apache.org/schema/spring"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-4.2.xsd	
          http://camel.apache.org/schema/spring 
          http://camel.apache.org/schema/spring/camel-spring.xsd
          http://www.springframework.org/schema/util 
          http://www.springframework.org/schema/util/spring-util-4.2.xsd">

	<camelContext xmlns="http://camel.apache.org/schema/spring">
            <!-- Add routes here -->
	</camelContext>

</beans>

The <camelContext> element represents (unsurprisingly) the Camel context, which can be compared to a Spring application context. Now your context file is ready to start defining Camel routes.

3.1. Camel Route With Custom Processor

Next we’ll write our first route to convert file content to uppercase.

We need to define a source from which the route will read data. This can be a database, file, console, or any number of other sources. In our case, it will be file.

Then we need to define the processor of the data that will be read from the source. For this example, we are going to write a custom processor class. This class will be a Spring bean which will implement the standard Camel Processor Interface.

Once the data is processed, we need to tell the route to where to direct the processed data. Once again, this could be one of a wide variety of outputs, such as a database, file, or the console. In our case, we are going to store it in a file.

To set up these steps, including the input, processor, and output, add the following route to the Camel context file:

<route>
    <from uri="file://data/input" /> <!-- INPUT -->
    <process ref="myFileProcessor" /> <!-- PROCESS -->
    <to uri="file://data/outputUpperCase" /> <!-- OUTPUT -->
</route>

Additionally, we must define the myFileProcessor bean:

<bean id="myFileProcessor" class="org.apache.camel.processor.FileProcessor" />

3.2. Custom Uppercase Processor

Now we need to create the custom file processor we defined in our bean. It must implement the Camel Processor interface, defining a single process method, which takes an Exchange object as its input. This object provides the details of the data from the input source.

Our method must read the message from the Exchange, uppercase the content, and then set that new content back into the Exchange object:

public class FileProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {
        String originalFileContent = (String) exchange.getIn().getBody(String.class);
        String upperCaseFileContent = originalFileContent.toUpperCase();
        exchange.getIn().setBody(upperCaseFileContent);
    }
}

This process method will be executed for every input received from the source.

3.3. Lowercase Processor

Now we will add another output to our Camel route. This time, we will convert the same input file’s data into lowercase. This time, we will not use a custom processor, however; we will use Apache Camel’s Message Translator feature. This is the updated Camel route:

<route>
    <from uri="file://data/input" />
    <process ref="myFileProcessor" />
    <to uri="file://data/outputUppperCase" />
    <transform>
        <simple>${body.toLowerCase()}</simple>
    </transform>
    <to uri="file://data/outputLowerCase" />
</route>

4. Running the Application

In order to have our routes be processed, we simply need to load the Camel context file into a Spring application context:

ClassPathXmlApplicationContext applicationContext = 
  new ClassPathXmlApplicationContext("camel-context.xml");

Once the route has been run successfully, two files will have been created: one with uppercase content, and one with lowercase content.

5. Conclusion

If you’re doing integration work, Apache Camel can definitely make things easier. The library provides plug-and-play components that will help you reduce boilerplate code and focus on the main logic of processing data.

And if you want to explore the Enterprise Integration Patterns concepts in detail, you should have a look at this book written by Gregor Hohpe and and Bobby Woolf, who conceptualize the EIPs very cleanly.

The example described in this article is available in a project on GitHub.

Course – LS (cat=Spring)

Get started with Spring and Spring Boot, through the Learn Spring course:

>> THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.