Apache Camel Timer Component Examples

0

In this article, we will see some examples of Apache camel timer component.

The timer: component is used to generate message exchanges when a timer fires.

The message exchange can be created on-the-fly by setting its body or by invoking a bean which will return us the message body. Once the message is created, we can either log it, or pass it to other endpoints like a jdbc endpoint to poll a table at a regular interval.

We can setup our routing to do all this and then use a timer to to generate an event at regular interval to keep triggering the routing.

Before we start with our example, Let’s look into the setup details.

This example uses the following frameworks:

  1. Maven 3.2.3
  2. Apache Camel 2.15.1
  3. Spring 4.1.5.RELEASE
  4. Eclipse  as the IDE, version Luna 4.4.1.

Time Component URI Format

Its URI format is:

timer:name[?options]

name is the Timer object’s name and options can be used to configure the timer, for example, period=2s will generate periodic events every 2 seconds.

Dependencies

The timer component is the core component of camel so all you need to add is camel-core to your pom.xml dependencies. We will also add few more dependencies as our examples need those.

  1. camel-stream – We will use this to send output to the console.
  2. camel-jms and activemq-camel – ActiveMQ JMS components.
  3. spring-context and camel-spring – Since we be configuring our camel context in spring.
  4. mysql-connector-java MySQL Driver.
  5. camel-jdbc to access the Camel JDBC component.
  6. spring-jdbc to configure JDBC resources in spring like DataSource

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.javarticles.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>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.26</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-jdbc</artifactId>
			<version>2.15.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.1.5.RELEASE</version>
		</dependency>
	</dependencies>
</project>

Timer Component Examples

In this example, we feed a message to the ActiveMQ inbox queue once every second. In the second route, the messages are retrieved and are shown on the console. One can probably send it to a bean or update some database table, for example, to maintain the heartbeat status.

timerFeedActiveMqApplicationContext.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 id="timerPingToInQueue">
			<from uri="timer:ping?period=1s" />
			<transform>
				<simple>Ping at ${date:now:yyyy-MM-dd HH:mm:ss}</simple>
			</transform>
			<to uri="activemq:queue:ping_queue" />
		</route>
		<route id="InQueueToConsole">
			<from uri="activemq:queue:ping_queue" />
			<to uri="stream:out" />
		</route>
	</camelContext>
</beans>

CamelTimerFeedingActiveMqExample:

package com.javarticles.camel.components;

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

public class CamelTimerFeedingActiveMqExample {
	public static final void main(String[] args) throws Exception {
        ApplicationContext appContext = new ClassPathXmlApplicationContext(
                "timerFeedActiveMqApplicationContext.xml");
        CamelContext camelContext = SpringCamelContext.springCamelContext(
                appContext, false);
        try {
            camelContext.start();
            Thread.sleep(5000);
        } finally {
            camelContext.stop();
        }
	}
}

Output:

Ping at 2015-05-10 09:38:54
Ping at 2015-05-10 09:38:55
Ping at 2015-05-10 09:38:56
Ping at 2015-05-10 09:38:57

In our next example, we query new orders from database every second and process it.

Hers is the schema for order table.

db-schema.sql:

drop table if exists `orders`;
CREATE TABLE `orders` (
  `ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `NAME` VARCHAR(100) NOT NULL,
  `STATUS` VARCHAR(50) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Some sample orders.

db-test-data.sql:

insert into orders(id, name, status) values (1, "Flat TV", "NEW");
insert into orders(id, name, status) values (2, "Children Story Books", "NEW");
insert into orders(id, name, status) values (3, "Piano", "NEW");

Here is our routing. Our routing starts with a timer component which generates an event every 1 second. The next step in the routing sets the body to order query which retrieves the new orders. The retrieved orders we pass it to a jdbc component jdbc:dataSource to execute against the configured data source. The ResultSet is then split into individual orders which are handled by the order processor bean.

    
    
	
	    SELECT * FROM ORDERS WHERE STATUS='NEW' ORDER BY NAME
	
    
    
    
	${body}
	
    

timerSeelectQueryApplicationContext.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"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	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
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
       ">
	<jdbc:initialize-database data-source="dataSource"
		enabled="true">
		<jdbc:script location="classpath:db-schema.sql" />
		<jdbc:script location="classpath:db-test-data.sql" />
	</jdbc:initialize-database>
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver" />
		<property name="url" value="jdbc:mysql://localhost/test" />
		<property name="username" value="root" />
		<property name="password" value="mnrpass" />
	</bean>
	<camelContext xmlns="http://camel.apache.org/schema/spring">
		<route>
			<from uri="timer://queryTimer?period=1s" />
			<setBody>
				<constant>
					SELECT * FROM ORDERS WHERE STATUS='NEW' ORDER BY NAME
				</constant>
			</setBody>
			<to uri="jdbc:dataSource" />
			<split>
				<simple>${body}</simple>
				<to uri="bean:orderProcessor" />
			</split>
		</route>
	</camelContext>
	<bean id="orderProcessor" class="com.javarticles.camel.components.OrderProcessor"/>
</beans>

OrderProcessor:

package com.javarticles.camel.components;

import java.util.Map;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

public class OrderProcessor implements Processor {

    public void process(Exchange exchange) throws Exception {
        System.out.println("Order received: " + exchange);
        Map<?,?> order = exchange.getIn().getBody(Map.class);
        System.out.println("Processing order: " + order);
    }
}

CamelTimerSqlQueryExample:

package com.javarticles.camel.components;

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

public class CamelTimerSqlQueryExample {
	public static final void main(String[] args) throws Exception {
        ApplicationContext appContext = new ClassPathXmlApplicationContext(
                "timerSelectQueryApplicationContext.xml");
        CamelContext camelContext = SpringCamelContext.springCamelContext(
                appContext, false);
        try {
            camelContext.start();
            Thread.sleep(5000);
        } finally {
            camelContext.stop();
        }
	}
}

Output:

Order received: Exchange[Message: {ID=2, NAME=Children Story Books, STATUS=NEW}]
Processing order: {ID=2, NAME=Children Story Books, STATUS=NEW}
Order received: Exchange[Message: {ID=1, NAME=Flat TV, STATUS=NEW}]
Processing order: {ID=1, NAME=Flat TV, STATUS=NEW}
Order received: Exchange[Message: {ID=3, NAME=Piano, STATUS=NEW}]
Processing order: {ID=3, NAME=Piano, STATUS=NEW}
Order received: Exchange[Message: {ID=2, NAME=Children Story Books, STATUS=NEW}]
Processing order: {ID=2, NAME=Children Story Books, STATUS=NEW}
Order received: Exchange[Message: {ID=1, NAME=Flat TV, STATUS=NEW}]
Processing order: {ID=1, NAME=Flat TV, STATUS=NEW}
Order received: Exchange[Message: {ID=3, NAME=Piano, STATUS=NEW}]
Processing order: {ID=3, NAME=Piano, STATUS=NEW}

Download the source code

This was an example about Apache Timer Component. You can download the source code here: camelTimerComponentExamples

Share.

Comments are closed.