diff --git a/README.adoc b/README.adoc index 0f59ad8e4..7227e5512 100644 --- a/README.adoc +++ b/README.adoc @@ -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"] |=== @@ -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 diff --git a/pom.xml b/pom.xml index c9824d6e0..81fb857e7 100644 --- a/pom.xml +++ b/pom.xml @@ -134,6 +134,7 @@ spring-pulsar spring-xquery telegram + timer transformer-demo vault whatsapp diff --git a/timer/README.adoc b/timer/README.adoc new file mode 100644 index 000000000..8148ccd2b --- /dev/null +++ b/timer/README.adoc @@ -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! \ No newline at end of file diff --git a/timer/pom.xml b/timer/pom.xml new file mode 100644 index 000000000..eb3e941b5 --- /dev/null +++ b/timer/pom.xml @@ -0,0 +1,99 @@ + + + + + 4.0.0 + + + org.apache.camel.example + camel-examples + 4.19.0-SNAPSHOT + + + camel-example-timer + jar + Camel :: Example :: Timer + An example showing how to work with Camel Timer component + + + Beginner + Timer + + + + + + + org.apache.camel + camel-bom + ${camel.version} + pom + import + + + + + + + + org.apache.camel + camel-core + + + + + org.apache.logging.log4j + log4j-core + runtime + ${log4j2-version} + + + org.apache.logging.log4j + log4j-slf4j2-impl + runtime + ${log4j2-version} + + + + + org.apache.camel + camel-test-junit6 + test + + + + + + + + + org.apache.camel + camel-maven-plugin + ${camel.version} + + org.apache.camel.example.timer.TimerExample + + + + + + + + \ No newline at end of file diff --git a/timer/src/main/java/org/apache/camel/example/timer/TimerExample.java b/timer/src/main/java/org/apache/camel/example/timer/TimerExample.java new file mode 100644 index 000000000..2f444db8f --- /dev/null +++ b/timer/src/main/java/org/apache/camel/example/timer/TimerExample.java @@ -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. + *

+ * 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); + }); + } + }; + } +} \ No newline at end of file diff --git a/timer/src/main/resources/log4j2.properties b/timer/src/main/resources/log4j2.properties new file mode 100644 index 000000000..dde96bbd3 --- /dev/null +++ b/timer/src/main/resources/log4j2.properties @@ -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 \ No newline at end of file diff --git a/timer/src/test/java/org/apache/camel/example/timer/TimerExampleTest.java b/timer/src/test/java/org/apache/camel/example/timer/TimerExampleTest.java new file mode 100644 index 000000000..80689cba5 --- /dev/null +++ b/timer/src/test/java/org/apache/camel/example/timer/TimerExampleTest.java @@ -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(); + } +} \ No newline at end of file