Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ readme's instructions.
== Examples

// examples: START
Number of Examples: 72 (0 deprecated)
Number of Examples: 73 (0 deprecated)

[width="100%",cols="4,2,4",options="header"]
|===
Expand Down Expand Up @@ -66,6 +66,8 @@ Number of Examples: 72 (0 deprecated)

| link:spring/README.adoc[Spring] (spring) | Beginner | An example showing how to work with Camel and Spring

| link:timer/README.adoc[Timer] (timer) | Beginner | An example showing how to work with Camel Timer component

| link:main/README.adoc[Main] (main) | Camel Standalone | An example for showing standalone Camel

| link:main-endpointdsl/README.adoc[Main Endpointdsl] (main-endpointdsl) | Camel Standalone | An example for showing standalone Camel with Endpoint DSL
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@
<module>spring-pulsar</module>
<module>spring-xquery</module>
<module>telegram</module>
<module>timer</module>
<module>transformer-demo</module>
<module>vault</module>
<module>whatsapp</module>
Expand Down
66 changes: 66 additions & 0 deletions timer/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
== Camel Timer Example

=== Introduction

This example shows how to work with the Camel Timer component.

The Timer component is used to generate message exchanges when a timer fires. It's useful for:

- Polling resources at regular intervals
- Scheduling batch jobs
- Triggering periodic tasks
- Creating heartbeat mechanisms

This example demonstrates various timer configurations including:

- Simple periodic timer
- Timer with initial delay
- Timer with repeat count
- Timer with fixed rate vs fixed delay

The example is minimal and shows how to use the timer component in standalone mode as a `public static void main` application.

=== Build

You will need to compile this example first:

[source,sh]
----
$ mvn compile
----

=== Run

To run the example type

[source,sh]
----
$ mvn camel:run
----

The example will run for about 5 seconds demonstrating different timer patterns.

To stop the example hit `ctrl+c`

You can also run the example from your editor such as Eclipse, IDEA etc,
by opening the class link:../timer/src/main/java/org/apache/camel/example/timer/TimerExample.java[org.apache.camel.example.timer.TimerExample]
and then right click, and chose run java application.

=== Configuration

The example shows multiple timer configurations:

- `timer:simple` - Fires every 300ms
- `timer:withDelay` - Fires every 300ms after a 500ms initial delay
- `timer:limited` - Fires only 3 times with 100ms interval
- `timer:fixedRate` - Fires every 500ms at fixed rate regardless of processing time

=== Help and contributions

If you hit any problem using Camel or have some feedback, then please
https://camel.apache.org/community/support/[let us know].

We also love contributors, so
https://camel.apache.org/community/contributing/[get involved] :-)

The Camel riders!
99 changes: 99 additions & 0 deletions timer/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<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/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.camel.example</groupId>
<artifactId>camel-examples</artifactId>
<version>4.19.0-SNAPSHOT</version>
</parent>

<artifactId>camel-example-timer</artifactId>
<packaging>jar</packaging>
<name>Camel :: Example :: Timer</name>
<description>An example showing how to work with Camel Timer component</description>

<properties>
<category>Beginner</category>
<title>Timer</title>
</properties>

<dependencyManagement>
<dependencies>
<!-- Add Camel BOM -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bom</artifactId>
<version>${camel.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>

<!-- logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<scope>runtime</scope>
<version>${log4j2-version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<scope>runtime</scope>
<version>${log4j2-version}</version>
</dependency>

<!-- for testing -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-junit6</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>

<!-- Allows the routes to be run via 'mvn camel:run' -->
<plugin>
<groupId>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
<version>${camel.version}</version>
<configuration>
<mainClass>org.apache.camel.example.timer.TimerExample</mainClass>
</configuration>
</plugin>

</plugins>

</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.example.timer;

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

/**
* An example showing how to use the Timer component in various configurations.
* <p>
* The timer component is used to generate message exchanges at regular intervals.
* This is useful for polling, scheduling, and triggering periodic tasks.
*/
public final class TimerExample {

public static void main(String[] args) throws Exception {
// create a CamelContext
try (CamelContext camel = new DefaultCamelContext()) {

// add routes demonstrating different timer patterns
camel.addRoutes(createTimerRoutes());

// start is not blocking
camel.start();

// run for 5 seconds to demonstrate the timers
Thread.sleep(5_000);

System.out.println("\nShutting down...");
}
}

static RouteBuilder createTimerRoutes() {
return new RouteBuilder() {
@Override
public void configure() {

// Simple timer - fires every 300ms
from("timer:simple?period=300")
.routeId("simple-timer")
.setBody(simple("Simple timer fired at ${date:now:yyyy-MM-dd HH:mm:ss}"))
.log("${body}");

// Timer with initial delay - waits 500ms before first fire, then every 300ms
from("timer:withDelay?delay=500&period=300")
.routeId("delayed-timer")
.setBody(simple("Delayed timer fired at ${date:now:yyyy-MM-dd HH:mm:ss}"))
.log("${body}");

// Timer with repeat count - fires only 3 times
from("timer:limited?period=100&repeatCount=3")
.routeId("limited-timer")
.setBody(simple("Limited timer fired (${header.CamelTimerCounter} of 3) at ${date:now:yyyy-MM-dd HH:mm:ss}"))
.log("${body}");

// Fixed rate timer - uses scheduleAtFixedRate (start-to-start timing)
// Attempts to maintain fixed intervals. If processing time < period, fires at regular intervals.
// vs fixedRate=false (default) - uses scheduleWithFixedDelay (end-to-start timing)
// Waits for completion + full period before next execution.
from("timer:fixedRate?period=500&fixedRate=true")
.routeId("fixed-rate-timer")
.setBody(simple("Fixed-rate timer fired at ${date:now:yyyy-MM-dd HH:mm:ss}"))
.log("${body}")
// simulate some processing time
.process(exchange -> {
// This 50ms delay is less than the 500ms period, demonstrating fixed-rate timing
Thread.sleep(50);
});
}
};
}
}
23 changes: 23 additions & 0 deletions timer/src/main/resources/log4j2.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

appender.out.type = Console
appender.out.name = out
appender.out.layout.type = PatternLayout
appender.out.layout.pattern = [%30.30t] %-30.30c{1} %-5p %m%n
rootLogger.level = INFO
rootLogger.appenderRef.out.ref = out
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.example.timer;

import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.NotifyBuilder;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.junit.jupiter.api.Test;

import java.util.concurrent.TimeUnit;

import static org.apache.camel.example.timer.TimerExample.createTimerRoutes;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* A unit test verifying that timer routes work correctly.
*/
class TimerExampleTest extends CamelTestSupport {

@Test
void should_fire_simple_timer() {
// Wait for at least 2 messages from the simple timer (fires every 300ms)
NotifyBuilder notify = new NotifyBuilder(context)
.from("timer:simple*")
.whenCompleted(2)
.create();

assertTrue(
notify.matches(20, TimeUnit.SECONDS), "Simple timer should fire at least twice"
);
}

@Test
void should_respect_repeat_count() {
// The limited timer should fire exactly 3 times
NotifyBuilder notify = new NotifyBuilder(context)
.from("timer:limited*")
.whenExactlyCompleted(3)
.create();

assertTrue(
notify.matches(20, TimeUnit.SECONDS), "Limited timer should fire exactly 3 times"
);
}

@Override
protected RoutesBuilder createRouteBuilder() {
return createTimerRoutes();
}
}
Loading