You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/08/31 14:34:13 UTC

[camel] 01/01: CAMEL-19817: camel-timer - Remove firedTime header and turn off metadata headers by default to make the exchange empty, and avoid leaking unwanted headers by default. Add backwards compatible option on component to turn this on globally.

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch timer
in repository https://gitbox.apache.org/repos/asf/camel.git

commit a7e37e4b6608c11be455316a0e12ff3d4d344756
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Aug 31 16:33:58 2023 +0200

    CAMEL-19817: camel-timer - Remove firedTime header and turn off metadata headers by default to make the exchange empty, and avoid leaking unwanted headers by default. Add backwards compatible option on component to turn this on globally.
---
 .../org/apache/camel/catalog/components/timer.json    |  7 ++++---
 .../component/timer/TimerComponentConfigurer.java     |  6 ++++++
 .../org/apache/camel/component/timer/timer.json       |  7 ++++---
 .../apache/camel/component/timer/TimerComponent.java  | 19 +++++++++++++++++++
 .../apache/camel/component/timer/TimerConstants.java  |  2 +-
 .../apache/camel/component/timer/TimerConsumer.java   |  7 ++++---
 .../apache/camel/component/timer/TimerEndpoint.java   |  7 +++----
 .../camel/component/timer/TimerFiredTimeTest.java     |  4 ++--
 .../timer/TimerNegativeNoRepeatCountDelayTest.java    |  4 ++--
 .../camel/component/timer/TimerRepeatCountTest.java   |  2 +-
 .../ROOT/pages/camel-4x-upgrade-guide-4_1.adoc        | 10 ++++++++++
 .../component/dsl/TimerComponentBuilderFactory.java   | 17 +++++++++++++++++
 .../endpoint/dsl/TimerEndpointBuilderFactory.java     | 14 +++++++-------
 13 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/timer.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/timer.json
index 757a0bc5e59..5b5ce5d800b 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/timer.json
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/timer.json
@@ -23,17 +23,18 @@
   },
   "componentProperties": {
     "bridgeErrorHandler": { "index": 0, "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be proce [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "includeMetadata": { "index": 1, "kind": "property", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc." },
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
   },
   "headers": {
-    "firedTime": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The fired time", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_FIRED_TIME" },
+    "CamelTimerFiredTime": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The fired time", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_FIRED_TIME" },
     "CamelMessageTimestamp": { "index": 1, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The timestamp of the message", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_MESSAGE_TIMESTAMP" }
   },
   "properties": {
     "timerName": { "index": 0, "kind": "path", "displayName": "Timer Name", "group": "consumer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the timer" },
     "delay": { "index": 1, "kind": "parameter", "displayName": "Delay", "group": "consumer", "label": "", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Delay before first event is triggered." },
     "fixedRate": { "index": 2, "kind": "parameter", "displayName": "Fixed Rate", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Events take place at approximately regular intervals, separated by the specified period." },
-    "includeMetadata": { "index": 3, "kind": "parameter", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc. This information is default included." },
+    "includeMetadata": { "index": 3, "kind": "parameter", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc." },
     "period": { "index": 4, "kind": "parameter", "displayName": "Period", "group": "consumer", "label": "", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "If greater than 0, generate periodic events every period." },
     "repeatCount": { "index": 5, "kind": "parameter", "displayName": "Repeat Count", "group": "consumer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "description": "Specifies a maximum limit of number of fires. So if you set it to 1, the timer will only fire once. If you set it to 5, it will only fire five times. A value of zero or negative means fire forever." },
     "bridgeErrorHandler": { "index": 6, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the lik [...]
diff --git a/components/camel-timer/src/generated/java/org/apache/camel/component/timer/TimerComponentConfigurer.java b/components/camel-timer/src/generated/java/org/apache/camel/component/timer/TimerComponentConfigurer.java
index efaba06eb29..6c7ad0b2209 100644
--- a/components/camel-timer/src/generated/java/org/apache/camel/component/timer/TimerComponentConfigurer.java
+++ b/components/camel-timer/src/generated/java/org/apache/camel/component/timer/TimerComponentConfigurer.java
@@ -25,6 +25,8 @@ public class TimerComponentConfigurer extends PropertyConfigurerSupport implemen
         case "autowiredEnabled": target.setAutowiredEnabled(property(camelContext, boolean.class, value)); return true;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": target.setBridgeErrorHandler(property(camelContext, boolean.class, value)); return true;
+        case "includemetadata":
+        case "includeMetadata": target.setIncludeMetadata(property(camelContext, boolean.class, value)); return true;
         default: return false;
         }
     }
@@ -36,6 +38,8 @@ public class TimerComponentConfigurer extends PropertyConfigurerSupport implemen
         case "autowiredEnabled": return boolean.class;
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return boolean.class;
+        case "includemetadata":
+        case "includeMetadata": return boolean.class;
         default: return null;
         }
     }
@@ -48,6 +52,8 @@ public class TimerComponentConfigurer extends PropertyConfigurerSupport implemen
         case "autowiredEnabled": return target.isAutowiredEnabled();
         case "bridgeerrorhandler":
         case "bridgeErrorHandler": return target.isBridgeErrorHandler();
+        case "includemetadata":
+        case "includeMetadata": return target.isIncludeMetadata();
         default: return null;
         }
     }
diff --git a/components/camel-timer/src/generated/resources/org/apache/camel/component/timer/timer.json b/components/camel-timer/src/generated/resources/org/apache/camel/component/timer/timer.json
index 757a0bc5e59..5b5ce5d800b 100644
--- a/components/camel-timer/src/generated/resources/org/apache/camel/component/timer/timer.json
+++ b/components/camel-timer/src/generated/resources/org/apache/camel/component/timer/timer.json
@@ -23,17 +23,18 @@
   },
   "componentProperties": {
     "bridgeErrorHandler": { "index": 0, "kind": "property", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be proce [...]
-    "autowiredEnabled": { "index": 1, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
+    "includeMetadata": { "index": 1, "kind": "property", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc." },
+    "autowiredEnabled": { "index": 2, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...]
   },
   "headers": {
-    "firedTime": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The fired time", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_FIRED_TIME" },
+    "CamelTimerFiredTime": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The fired time", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_FIRED_TIME" },
     "CamelMessageTimestamp": { "index": 1, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The timestamp of the message", "constantName": "org.apache.camel.component.timer.TimerConstants#HEADER_MESSAGE_TIMESTAMP" }
   },
   "properties": {
     "timerName": { "index": 0, "kind": "path", "displayName": "Timer Name", "group": "consumer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the timer" },
     "delay": { "index": 1, "kind": "parameter", "displayName": "Delay", "group": "consumer", "label": "", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "Delay before first event is triggered." },
     "fixedRate": { "index": 2, "kind": "parameter", "displayName": "Fixed Rate", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Events take place at approximately regular intervals, separated by the specified period." },
-    "includeMetadata": { "index": 3, "kind": "parameter", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc. This information is default included." },
+    "includeMetadata": { "index": 3, "kind": "parameter", "displayName": "Include Metadata", "group": "consumer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to include metadata in the exchange such as fired time, timer name, timer count etc." },
     "period": { "index": 4, "kind": "parameter", "displayName": "Period", "group": "consumer", "label": "", "required": false, "type": "duration", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1000", "description": "If greater than 0, generate periodic events every period." },
     "repeatCount": { "index": 5, "kind": "parameter", "displayName": "Repeat Count", "group": "consumer", "label": "", "required": false, "type": "integer", "javaType": "long", "deprecated": false, "autowired": false, "secret": false, "description": "Specifies a maximum limit of number of fires. So if you set it to 1, the timer will only fire once. If you set it to 5, it will only fire five times. A value of zero or negative means fire forever." },
     "bridgeErrorHandler": { "index": 6, "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the lik [...]
diff --git a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerComponent.java b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerComponent.java
index 5c3f51829ea..254d1177e0e 100644
--- a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerComponent.java
+++ b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerComponent.java
@@ -25,6 +25,8 @@ import java.util.Timer;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.camel.Endpoint;
+import org.apache.camel.api.management.ManagedAttribute;
+import org.apache.camel.spi.Metadata;
 import org.apache.camel.support.DefaultComponent;
 
 /**
@@ -39,9 +41,25 @@ public class TimerComponent extends DefaultComponent {
     private final Map<String, Timer> timers = new HashMap<>();
     private final Map<String, AtomicInteger> refCounts = new HashMap<>();
 
+    @Metadata
+    private boolean includeMetadata;
+
     public TimerComponent() {
     }
 
+    @ManagedAttribute(description = "Include metadata")
+    public boolean isIncludeMetadata() {
+        return includeMetadata;
+    }
+
+    /**
+     * Whether to include metadata in the exchange such as fired time, timer name, timer count etc.
+     */
+    @ManagedAttribute(description = "Include metadata")
+    public void setIncludeMetadata(boolean includeMetadata) {
+        this.includeMetadata = includeMetadata;
+    }
+
     public Timer getTimer(TimerConsumer consumer) {
         String key = consumer.getEndpoint().getTimerName();
         if (!consumer.getEndpoint().isDaemon()) {
@@ -93,6 +111,7 @@ public class TimerComponent extends DefaultComponent {
     @Override
     protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
         TimerEndpoint answer = new TimerEndpoint(uri, this, remaining);
+        answer.setIncludeMetadata(includeMetadata);
 
         // convert time from String to a java.util.Date using the supported patterns
         String time = getAndRemoveOrResolveReferenceParameter(parameters, "time", String.class);
diff --git a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConstants.java b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConstants.java
index 92e81026ec0..a89b3a0dd55 100644
--- a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConstants.java
+++ b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConstants.java
@@ -22,7 +22,7 @@ import org.apache.camel.spi.Metadata;
 public final class TimerConstants {
 
     @Metadata(description = "The fired time", javaType = "Date")
-    public static final String HEADER_FIRED_TIME = "firedTime";
+    public static final String HEADER_FIRED_TIME = Exchange.TIMER_FIRED_TIME;
     @Metadata(description = "The timestamp of the message", javaType = "long")
     public static final String HEADER_MESSAGE_TIMESTAMP = Exchange.MESSAGE_TIMESTAMP;
 
diff --git a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConsumer.java b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConsumer.java
index d14e68a7bbe..d1545eb1bad 100644
--- a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConsumer.java
+++ b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerConsumer.java
@@ -188,12 +188,13 @@ public class TimerConsumer extends DefaultConsumer implements StartupListener, S
         if (endpoint.isIncludeMetadata()) {
             exchange.setProperty(Exchange.TIMER_COUNTER, counter);
             exchange.setProperty(Exchange.TIMER_NAME, endpoint.getTimerName());
-            exchange.setProperty(Exchange.TIMER_TIME, endpoint.getTime());
+            if (endpoint.getTime() != null) {
+                exchange.setProperty(Exchange.TIMER_TIME, endpoint.getTime());
+            }
             exchange.setProperty(Exchange.TIMER_PERIOD, endpoint.getPeriod());
 
             Date now = new Date();
-            exchange.setProperty(Exchange.TIMER_FIRED_TIME, now);
-            // also set now on in header with same key as quartz to be consistent
+            exchange.setProperty(TimerConstants.HEADER_FIRED_TIME, now);
             exchange.getIn().setHeader(TimerConstants.HEADER_FIRED_TIME, now);
             exchange.getIn().setHeader(TimerConstants.HEADER_MESSAGE_TIMESTAMP, now.getTime());
         }
diff --git a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java
index 23415099603..97dfaacbd4a 100644
--- a/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java
+++ b/components/camel-timer/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java
@@ -63,8 +63,8 @@ public class TimerEndpoint extends DefaultEndpoint implements MultipleConsumersS
     private String pattern;
     @UriParam(label = "advanced")
     private Timer timer;
-    @UriParam(defaultValue = "true")
-    private boolean includeMetadata = true;
+    @UriParam
+    private boolean includeMetadata;
     @UriParam(defaultValue = "false", label = "advanced",
               description = "Sets whether synchronous processing should be strictly used")
     private boolean synchronous;
@@ -253,8 +253,7 @@ public class TimerEndpoint extends DefaultEndpoint implements MultipleConsumersS
     }
 
     /**
-     * Whether to include metadata in the exchange such as fired time, timer name, timer count etc. This information is
-     * default included.
+     * Whether to include metadata in the exchange such as fired time, timer name, timer count etc.
      */
     @ManagedAttribute(description = "Include metadata")
     public void setIncludeMetadata(boolean includeMetadata) {
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerFiredTimeTest.java b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerFiredTimeTest.java
index 7f018bb6ff7..4a4112e6bb6 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerFiredTimeTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerFiredTimeTest.java
@@ -40,7 +40,7 @@ public class TimerFiredTimeTest extends ContextTestSupport {
         Exchange exchange = mock.getExchanges().get(0);
         assertEquals("hello", exchange.getProperty(Exchange.TIMER_NAME));
         assertNotNull(exchange.getProperty(Exchange.TIMER_FIRED_TIME));
-        assertNotNull(exchange.getIn().getHeader("firedTime"));
+        assertNotNull(exchange.getIn().getHeader(Exchange.TIMER_FIRED_TIME));
         assertEquals(Long.valueOf(1), exchange.getProperty(Exchange.TIMER_COUNTER));
     }
 
@@ -48,7 +48,7 @@ public class TimerFiredTimeTest extends ContextTestSupport {
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             public void configure() throws Exception {
-                from("timer://hello?period=10&delay=10").to("mock:result");
+                from("timer://hello?period=10&delay=10&includeMetadata=true").to("mock:result");
             }
         };
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerNegativeNoRepeatCountDelayTest.java b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerNegativeNoRepeatCountDelayTest.java
index 4ee3a0aaee9..b2e5bf0c62c 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerNegativeNoRepeatCountDelayTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerNegativeNoRepeatCountDelayTest.java
@@ -44,7 +44,6 @@ public class TimerNegativeNoRepeatCountDelayTest extends ContextTestSupport {
             Exchange exchange = iter.next();
             assertEquals("negativeDelay", exchange.getProperty(Exchange.TIMER_NAME));
             assertNotNull(exchange.getProperty(Exchange.TIMER_FIRED_TIME));
-            assertNotNull(exchange.getIn().getHeader("firedTime"));
         }
     }
 
@@ -53,7 +52,8 @@ public class TimerNegativeNoRepeatCountDelayTest extends ContextTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("timer://negativeDelay?delay=-1&repeatCount=10").routeId("routeTest").to("mock:result");
+                from("timer://negativeDelay?delay=-1&repeatCount=10&includeMetadata=true").routeId("routeTest")
+                        .to("mock:result");
             }
         };
     }
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerRepeatCountTest.java b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerRepeatCountTest.java
index b893c200ef0..3e1bbeeaa4c 100644
--- a/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerRepeatCountTest.java
+++ b/core/camel-core/src/test/java/org/apache/camel/component/timer/TimerRepeatCountTest.java
@@ -47,7 +47,7 @@ public class TimerRepeatCountTest extends ContextTestSupport {
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             public void configure() throws Exception {
-                from("timer://hello?delay=0&repeatCount=3&period=10").noAutoStartup().to("mock:result");
+                from("timer://hello?delay=0&repeatCount=3&period=10&includeMetadata=true").noAutoStartup().to("mock:result");
             }
         };
     }
diff --git a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
index e4d2b6eae8f..a71849478ce 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_1.adoc
@@ -10,6 +10,16 @@ from both 4.0 to 4.1 and 4.1 to 4.2.
 
 Dumping routes to JMX no longer includes `customId="true"` in the XML nodes.
 
+=== camel-timer
+
+The `timer` no longer includes header `firedTime` with the timestamp of when the exchange was fired.
+This means the exchange by default has no headers, and `null` body.
+
+The `firedTime` header has been renamed to `CamelTimerFireTime`.
+
+The option `includeMetadata` can be set to `true` on the endpoint or component level, to turn on
+these additional metadata headers again.
+
 === camel-aws2-step-functions
 
 The following Message Headers of `camel-aws2-step-functions` component have been renamed to follow standard camel naming convention.
diff --git a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/TimerComponentBuilderFactory.java b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/TimerComponentBuilderFactory.java
index eceec790a49..7bea515d179 100644
--- a/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/TimerComponentBuilderFactory.java
+++ b/dsl/camel-componentdsl/src/generated/java/org/apache/camel/builder/component/dsl/TimerComponentBuilderFactory.java
@@ -70,6 +70,22 @@ public interface TimerComponentBuilderFactory {
             doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
             return this;
         }
+        /**
+         * Whether to include metadata in the exchange such as fired time, timer
+         * name, timer count etc.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: consumer
+         * 
+         * @param includeMetadata the value to set
+         * @return the dsl builder
+         */
+        default TimerComponentBuilder includeMetadata(boolean includeMetadata) {
+            doSetProperty("includeMetadata", includeMetadata);
+            return this;
+        }
         /**
          * Whether autowiring is enabled. This is used for automatic autowiring
          * options (the option must be marked as autowired) by looking up in the
@@ -108,6 +124,7 @@ public interface TimerComponentBuilderFactory {
                 Object value) {
             switch (name) {
             case "bridgeErrorHandler": ((TimerComponent) component).setBridgeErrorHandler((boolean) value); return true;
+            case "includeMetadata": ((TimerComponent) component).setIncludeMetadata((boolean) value); return true;
             case "autowiredEnabled": ((TimerComponent) component).setAutowiredEnabled((boolean) value); return true;
             default: return false;
             }
diff --git a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/TimerEndpointBuilderFactory.java b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/TimerEndpointBuilderFactory.java
index 87230837a8b..b06fcbf0883 100644
--- a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/TimerEndpointBuilderFactory.java
+++ b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/TimerEndpointBuilderFactory.java
@@ -106,11 +106,11 @@ public interface TimerEndpointBuilderFactory {
         }
         /**
          * Whether to include metadata in the exchange such as fired time, timer
-         * name, timer count etc. This information is default included.
+         * name, timer count etc.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
          * 
-         * Default: true
+         * Default: false
          * Group: consumer
          * 
          * @param includeMetadata the value to set
@@ -122,12 +122,12 @@ public interface TimerEndpointBuilderFactory {
         }
         /**
          * Whether to include metadata in the exchange such as fired time, timer
-         * name, timer count etc. This information is default included.
+         * name, timer count etc.
          * 
          * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
          * type.
          * 
-         * Default: true
+         * Default: false
          * Group: consumer
          * 
          * @param includeMetadata the value to set
@@ -541,10 +541,10 @@ public interface TimerEndpointBuilderFactory {
          * 
          * Group: consumer
          * 
-         * @return the name of the header {@code firedTime}.
+         * @return the name of the header {@code TimerFiredTime}.
          */
-        public String firedTime() {
-            return "firedTime";
+        public String timerFiredTime() {
+            return "TimerFiredTime";
         }
 
         /**