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:
- Maven 3.2.3
- Apache Camel 2.15.1
- Spring 4.1.5.RELEASE
- 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.
camel-stream
– We will use this to send output to the console.camel-jms
andactivemq-camel
– ActiveMQ JMS components.spring-context
andcamel-spring
– Since we be configuring our camel context in spring.mysql-connector-java
MySQL Driver.camel-jdbc
to access the Camel JDBC component.spring-jdbc
to configure JDBC resources in spring likeDataSource
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