Apache Camel

Apache Camel Hello World example

In this article, I am going to show you a ‘Hello World’ example of camel.

But first let me first introduce you to Apache Camel.

Apache Camel is an open-source integration framework which integrates systems. Messages play an important role in integrating systems, you can decide from which source to accept message, build the routing rules to determine how to process and send those messages to the other destinations.

Apache Camel uses URIs to work directly with any kind of Transport or messaging model such as HTTP, ActiveMQ, JMS etc., but on the outset, the API remains same regardless of the transport protocol the systems are using.

Camel has two main ways of defining routing rules: the Java-based domain specific language (DSL) and the Spring XML configuration format. I will show you an example for each case.

Now its the time to setup, below are the details:

  • I am using Maven – the build tool
  • Eclipse  as the IDE, version Luna 4.4.1.

1. Dependencies

I am using Camel 2.15.1 release. You can view the latest releases from Apache Camel site.
Add camel-core dependency to pom.xml.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.camel</groupId>
	<artifactId>camelHelloWorld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>2.15.1</version>
		</dependency>
	</dependencies>
</project>

2. Camel Hello World Example

In our first example, we want camel to listen on a JMS queue, take messages off the queue and send them to the standard output. We will use ActiveMQ as the JMS component.

Since camel depends on ActiveMQ and the standard output components, we will have to add the below dependencies to our pom.xml.

  1. camel-stream – The stream: component provides access to the System.in, System.out and System.err streams
  2. camel-jms – The JMS component allows messages to be sent to (or consumed from) a JMS Queue or Topic
  3. activemq-camel - For JMS Messaging with Apache ActiveMQ

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.camel</groupId>
	<artifactId>camelHelloWorld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-stream</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-jms</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-camel</artifactId>
			<version>5.6.0</version>
		</dependency>
	</dependencies>
</project>

Let’s analyse our CamelHelloWorldExample.

  1. First, you need to create CamelContext. It represents Camel’s runtime system. You can think of it as a container for Components, Routes etc., in other words, CamelContext is an object that knows all the pieces of the integration framework and keeps them together.
  2. We will add the JMS component to the CamelContext using context.addComponent
  3. Next, we build our route. We want CamelContext to listen on the AcyiveMQ Queue. As soon as a message arrives, it should retrieve off the queue and send it to the standard output.
  4. We use Java Domain Specific Language (DSL) to build the route. We instantiate RouteBuilder and override configure() to build the route

Below is our route plan. It looks straightforward. Retrieve messages from activeMQ queue test.queue and send it to stream out. activemq:queue:test.queue and stream:out are the URIs which help camel context to determine the component and configure them.

from("activemq:queue:test.queue")
.to("stream:out");

Now that we have built our route plan. We need to start the context. You need to call context.start(). In the finally, you should make sure it is closed.
For our example sake, to trigger off the route, we need to send some message to the queue. We do that using ProducerTemplate.

template.sendBody("activemq:test.queue", "Hello World")

CamelHelloWorldExample:

package com.javacodegeeks.camel;

import org.apache.activemq.camel.component.ActiveMQComponent;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;

public class CamelHelloWorldExample {
	public static void main(String[] args) throws Exception {
		CamelContext context = new DefaultCamelContext();
		try {
			context.addComponent("activemq", ActiveMQComponent.activeMQComponent("vm://localhost?broker.persistent=false"));
			context.addRoutes(new RouteBuilder() {
				@Override
				public void configure() throws Exception {
					from("activemq:queue:test.queue")
					.to("stream:out");
				}
			});
			ProducerTemplate template = context.createProducerTemplate();
			context.start();
			template.sendBody("activemq:test.queue", "Hello World");
			Thread.sleep(2000);
		} finally {
			context.stop();
		}
	}
}

Output:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
Hello World

3. Camel Hello World Example using Spring

Now, we will do the same using spring. We will define the route in the applicationContext.xml. Since we are relying on spring here, we need to modify our dependencies in pom.xml and add spring-context and camel-spring.

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.camel</groupId>
	<artifactId>camelHelloWorld</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<dependencies>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-stream</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-jms</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-camel</artifactId>
			<version>5.6.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.1.5.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-spring</artifactId>
			<version>2.15.1</version>
		</dependency>		
	</dependencies>
</project>

Element <camelContext> defines our context. Add child element <route> to define the route. Other child elements within <route> are self-explanatory.

applicationContext.xml:

<?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 id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="vm://localhost?broker.persistent=false" />
	</bean>
	<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
		<property name="connectionFactory" ref="connectionFactory" />
	</bean>
	<camelContext xmlns="http://camel.apache.org/schema/spring">
		<route>
			<from uri="activemq:queue:test.queue" />
			<to uri="bean:myBean?method=appendCamel"/>
			<to uri="stream:out" />
		</route>
	</camelContext>
	<bean id="myBean" class="com.javacodegeeks.camel.MyBean"/>

</beans>

We have modified our route plan a bit. The message is retrieved from the activeMQ queue and sent to a bean, to myBean.appendCamel method. The bean’s method appendCamel, appends ‘Camel’ to ‘Hello World’ and returns it. The returned message is then sent to the standard output.

MyBean:

package com.javacodegeeks.camel;

public class MyBean {
	public String appendCamel(String msg) {
		return msg + " Camel";
	}
}

Let’s go through CamelHelloWorldSpringExample. Since CamelContext is defined in applicationContext.xml, first create the ApplicationContext object. Next, call SpringCamelContext.springCamelContext to return us the CamelContext. You need to pass the ApplicationContext object to it so that it can build the CamelContext from it.

CamelHelloWorldSpringExample:

package com.javacodegeeks.camel;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.spring.SpringCamelContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CamelHelloWorldSpringExample {
	public static void main(String[] args) throws Exception {
		ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		CamelContext camelContext = SpringCamelContext.springCamelContext(appContext, false);
		try {
			ProducerTemplate template = camelContext.createProducerTemplate();
			camelContext.start();
			template.sendBody("activemq:test.queue", "Hello World");
		} finally {
			camelContext.stop();
		}
	}
}

Output:

Apr 13, 2015 11:11:42 AM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7506e922: startup date [Mon Apr 13 11:11:42 IST 2015]; root of context hierarchy
Apr 13, 2015 11:11:42 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
SLF4J: Failed to load class "org.slf4j.impl.StaticMDCBinder".
SLF4J: Defaulting to no-operation MDCAdapter implementation.
SLF4J: See http://www.slf4j.org/codes.html#no_static_mdc_binder for further details.
Hello World Camel

4. Camel HelloWorld Example using a Timer component

In this example, we use camel’s timer component.
Here is its route.

from("timer://myTimer?period=2000")
.setBody()
.simple("Hello World Camel fired at ${header.firedTime}")
.to("stream:out");

We can configure the timer component in the URI itself timer://myTimer?period=2000. Our timer component name is myTimer and it triggers off every 2000ms.
It sends text ‘Hello World Camel fired at ${header.firedTime} to the standrad output every 2000ms.

${header.firedTime} will be replaced with the fired time.

CamelHelloWorldTimerExample:

package com.javacodegeeks.camel;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.impl.DefaultCamelContext;

public class CamelHelloWorldTimerExample {
	public static void main(String[] args) throws Exception {
		CamelContext context = new DefaultCamelContext();
		try {
			context.addRoutes(new RouteBuilder() {
				@Override
				public void configure() throws Exception {
					from("timer://myTimer?period=2000")
					.setBody()
				    .simple("Hello World Camel fired at ${header.firedTime}")
				    .to("stream:out");
				}
			});
			context.start();
			Thread.sleep(10000);
		} finally {
			context.stop();
		}
	}
}

Output:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Hello World Camel fired at Mon Apr 13 10:56:44 IST 2015
Hello World Camel fired at Mon Apr 13 10:56:46 IST 2015
Hello World Camel fired at Mon Apr 13 10:56:48 IST 2015
Hello World Camel fired at Mon Apr 13 10:56:50 IST 2015
Hello World Camel fired at Mon Apr 13 10:56:52 IST 2015

5. Download the Eclipse Project

This was an example of Camel ‘HelloWorld’.

Download
You can download the full source code of this example here: camelHelloWorldExample.zip

Ram Mokkapaty

Ram holds a master's degree in Machine Design from IT B.H.U. His expertise lies in test driven development and re-factoring. He is passionate about open source technologies and actively blogs on various java and open-source technologies like spring. He works as a principal Engineer in the logistics domain.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Jai
Jai
4 years ago

Thanks, Ram for sharing. You’ve explained core concepts beautifully with clear objectives and purpose.

Back to top button