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

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


The following commit(s) were added to refs/heads/camel-3.18.x by this push:
     new 1ce486ea95e CAMEL-18318: camel-quartz - Add ignoreExpiredNextFireTime 
option.
1ce486ea95e is described below

commit 1ce486ea95e7800877c18d4c1c8915e213ef570c
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Thu Jul 28 16:40:34 2022 +0200

    CAMEL-18318: camel-quartz - Add ignoreExpiredNextFireTime option.
---
 .../apache/camel/catalog/components/quartz.json    |  1 +
 .../component/quartz/QuartzEndpointConfigurer.java |  6 +++
 .../component/quartz/QuartzEndpointUriFactory.java |  3 +-
 .../org/apache/camel/component/quartz/quartz.json  |  1 +
 .../camel/component/quartz/QuartzComponent.java    | 20 ++++++++
 .../camel/component/quartz/QuartzEndpoint.java     | 54 ++++++++++++++++++----
 .../endpoint/dsl/QuartzEndpointBuilderFactory.java | 45 ++++++++++++++++++
 7 files changed, 120 insertions(+), 10 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quartz.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quartz.json
index c9e390af8c9..af0acd4b6b2 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quartz.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/quartz.json
@@ -48,6 +48,7 @@
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
     "customCalendar": { "kind": "parameter", "displayName": "Custom Calendar", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.quartz.Calendar", "deprecated": false, "autowired": false, 
"secret": false, "description": "Specifies a custom calendar to avoid specific 
range of date" },
+    "ignoreExpiredNextFireTime": { "kind": "parameter", "displayName": "Ignore 
Expired Next Fire Time", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to ignore quartz cannot schedule a trigger because the trigger will 
never fire in the future. This can happen when using a cron trigger that are 
configured to only run in the past. [...]
     "jobParameters": { "kind": "parameter", "displayName": "Job Parameters", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": 
"job.", "multiValue": true, "deprecated": false, "autowired": false, "secret": 
false, "description": "To configure additional options on the job." },
     "prefixJobNameWithEndpointId": { "kind": "parameter", "displayName": 
"Prefix Job Name With Endpoint Id", "group": "advanced", "label": "advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Whether the job name should be prefixed with endpoint id" },
     "triggerParameters": { "kind": "parameter", "displayName": "Trigger 
Parameters", "group": "advanced", "label": "advanced", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.Object>", "prefix": "trigger.", "multiValue": true, "deprecated": 
false, "autowired": false, "secret": false, "description": "To configure 
additional options on the trigger. The parameter timeZone is supported if the 
cron option is present. Otherwise the parameters repeatI [...]
diff --git 
a/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointConfigurer.java
 
b/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointConfigurer.java
index 9aeea611d07..61cab392524 100644
--- 
a/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointConfigurer.java
+++ 
b/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointConfigurer.java
@@ -36,6 +36,8 @@ public class QuartzEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "exceptionHandler": 
target.setExceptionHandler(property(camelContext, 
org.apache.camel.spi.ExceptionHandler.class, value)); return true;
         case "exchangepattern":
         case "exchangePattern": 
target.setExchangePattern(property(camelContext, 
org.apache.camel.ExchangePattern.class, value)); return true;
+        case "ignoreexpirednextfiretime":
+        case "ignoreExpiredNextFireTime": 
target.setIgnoreExpiredNextFireTime(property(camelContext, boolean.class, 
value)); return true;
         case "jobparameters":
         case "jobParameters": target.setJobParameters(property(camelContext, 
java.util.Map.class, value)); return true;
         case "pausejob":
@@ -73,6 +75,8 @@ public class QuartzEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "exceptionHandler": return 
org.apache.camel.spi.ExceptionHandler.class;
         case "exchangepattern":
         case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "ignoreexpirednextfiretime":
+        case "ignoreExpiredNextFireTime": return boolean.class;
         case "jobparameters":
         case "jobParameters": return java.util.Map.class;
         case "pausejob":
@@ -111,6 +115,8 @@ public class QuartzEndpointConfigurer extends 
PropertyConfigurerSupport implemen
         case "exceptionHandler": return target.getExceptionHandler();
         case "exchangepattern":
         case "exchangePattern": return target.getExchangePattern();
+        case "ignoreexpirednextfiretime":
+        case "ignoreExpiredNextFireTime": return 
target.isIgnoreExpiredNextFireTime();
         case "jobparameters":
         case "jobParameters": return target.getJobParameters();
         case "pausejob":
diff --git 
a/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointUriFactory.java
 
b/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointUriFactory.java
index eaf3988bc49..f1ee6b77985 100644
--- 
a/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointUriFactory.java
+++ 
b/components/camel-quartz/src/generated/java/org/apache/camel/component/quartz/QuartzEndpointUriFactory.java
@@ -21,7 +21,7 @@ public class QuartzEndpointUriFactory extends 
org.apache.camel.support.component
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(18);
+        Set<String> props = new HashSet<>(19);
         props.add("autoStartScheduler");
         props.add("bridgeErrorHandler");
         props.add("cron");
@@ -31,6 +31,7 @@ public class QuartzEndpointUriFactory extends 
org.apache.camel.support.component
         props.add("exceptionHandler");
         props.add("exchangePattern");
         props.add("groupName");
+        props.add("ignoreExpiredNextFireTime");
         props.add("jobParameters");
         props.add("pauseJob");
         props.add("prefixJobNameWithEndpointId");
diff --git 
a/components/camel-quartz/src/generated/resources/org/apache/camel/component/quartz/quartz.json
 
b/components/camel-quartz/src/generated/resources/org/apache/camel/component/quartz/quartz.json
index c9e390af8c9..af0acd4b6b2 100644
--- 
a/components/camel-quartz/src/generated/resources/org/apache/camel/component/quartz/quartz.json
+++ 
b/components/camel-quartz/src/generated/resources/org/apache/camel/component/quartz/quartz.json
@@ -48,6 +48,7 @@
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
     "customCalendar": { "kind": "parameter", "displayName": "Custom Calendar", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "org.quartz.Calendar", "deprecated": false, "autowired": false, 
"secret": false, "description": "Specifies a custom calendar to avoid specific 
range of date" },
+    "ignoreExpiredNextFireTime": { "kind": "parameter", "displayName": "Ignore 
Expired Next Fire Time", "group": "advanced", "label": "advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to ignore quartz cannot schedule a trigger because the trigger will 
never fire in the future. This can happen when using a cron trigger that are 
configured to only run in the past. [...]
     "jobParameters": { "kind": "parameter", "displayName": "Job Parameters", 
"group": "advanced", "label": "advanced", "required": false, "type": "object", 
"javaType": "java.util.Map<java.lang.String, java.lang.Object>", "prefix": 
"job.", "multiValue": true, "deprecated": false, "autowired": false, "secret": 
false, "description": "To configure additional options on the job." },
     "prefixJobNameWithEndpointId": { "kind": "parameter", "displayName": 
"Prefix Job Name With Endpoint Id", "group": "advanced", "label": "advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Whether the job name should be prefixed with endpoint id" },
     "triggerParameters": { "kind": "parameter", "displayName": "Trigger 
Parameters", "group": "advanced", "label": "advanced", "required": false, 
"type": "object", "javaType": "java.util.Map<java.lang.String, 
java.lang.Object>", "prefix": "trigger.", "multiValue": true, "deprecated": 
false, "autowired": false, "secret": false, "description": "To configure 
additional options on the trigger. The parameter timeZone is supported if the 
cron option is present. Otherwise the parameters repeatI [...]
diff --git 
a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
 
b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
index ceb13e61c86..ecb10388671 100644
--- 
a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
+++ 
b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzComponent.java
@@ -30,6 +30,7 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.ExtendedStartupListener;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.DefaultComponent;
@@ -79,6 +80,8 @@ public class QuartzComponent extends DefaultComponent 
implements ExtendedStartup
     private boolean prefixJobNameWithEndpointId;
     @Metadata(defaultValue = "true")
     private boolean prefixInstanceName = true;
+    @UriParam(label = "advanced")
+    private boolean ignoreExpiredNextFireTime;
 
     public QuartzComponent() {
     }
@@ -189,6 +192,22 @@ public class QuartzComponent extends DefaultComponent 
implements ExtendedStartup
         this.interruptJobsOnShutdown = interruptJobsOnShutdown;
     }
 
+    public boolean isIgnoreExpiredNextFireTime() {
+        return ignoreExpiredNextFireTime;
+    }
+
+    /**
+     * Whether to ignore quartz cannot schedule a trigger because the trigger 
will never fire in the future.
+     * This can happen when using a cron trigger that are configured to only 
run in the past.
+     *
+     * By default, Quartz will fail to schedule the trigger and therefore fail 
to start the Camel route.
+     * You can set this to true which then logs a WARN and then ignore the 
problem, meaning that the route
+     * will never fire in the future.
+     */
+    public void setIgnoreExpiredNextFireTime(boolean 
ignoreExpiredNextFireTime) {
+        this.ignoreExpiredNextFireTime = ignoreExpiredNextFireTime;
+    }
+
     public SchedulerFactory getSchedulerFactory() {
         if (schedulerFactory == null) {
             try {
@@ -396,6 +415,7 @@ public class QuartzComponent extends DefaultComponent 
implements ExtendedStartup
             cron = cron.replace('+', ' ');
             result.setCron(cron);
         }
+        result.setIgnoreExpiredNextFireTime(ignoreExpiredNextFireTime);
         setProperties(result, parameters);
         return result;
     }
diff --git 
a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
 
b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
index 23cb1400d33..d2d38d06fa0 100644
--- 
a/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
+++ 
b/components/camel-quartz/src/main/java/org/apache/camel/component/quartz/QuartzEndpoint.java
@@ -49,6 +49,7 @@ import org.quartz.SimpleTrigger;
 import org.quartz.Trigger;
 import org.quartz.TriggerBuilder;
 import org.quartz.TriggerKey;
+import org.quartz.spi.OperableTrigger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -82,6 +83,8 @@ public class QuartzEndpoint extends DefaultEndpoint {
     private String cron;
     @UriParam
     private boolean stateful;
+    @UriParam(label = "advanced")
+    private boolean ignoreExpiredNextFireTime;
     @UriParam(defaultValue = "true")
     private boolean deleteJob = true;
     @UriParam
@@ -129,6 +132,22 @@ public class QuartzEndpoint extends DefaultEndpoint {
         return stateful;
     }
 
+    public boolean isIgnoreExpiredNextFireTime() {
+        return ignoreExpiredNextFireTime;
+    }
+
+    /**
+     * Whether to ignore quartz cannot schedule a trigger because the trigger 
will never fire in the future.
+     * This can happen when using a cron trigger that are configured to only 
run in the past.
+     *
+     * By default, Quartz will fail to schedule the trigger and therefore fail 
to start the Camel route.
+     * You can set this to true which then logs a WARN and then ignore the 
problem, meaning that the route
+     * will never fire in the future.
+     */
+    public void setIgnoreExpiredNextFireTime(boolean 
ignoreExpiredNextFireTime) {
+        this.ignoreExpiredNextFireTime = ignoreExpiredNextFireTime;
+    }
+
     public long getTriggerStartDelay() {
         return triggerStartDelay;
     }
@@ -355,6 +374,7 @@ public class QuartzEndpoint extends DefaultEndpoint {
 
         QuartzHelper.updateJobDataMap(getCamelContext(), jobDetail, 
getEndpointUri(), isUsingFixedCamelContextName());
 
+        boolean scheduled = true;
         if (triggerExisted) {
             // Reschedule job if trigger settings were changed
             if (hasTriggerChanged(oldTrigger, trigger)) {
@@ -362,8 +382,22 @@ public class QuartzEndpoint extends DefaultEndpoint {
             }
         } else {
             try {
-                // Schedule it now. Remember that scheduler might not be 
started it, but we can schedule now.
-                scheduler.scheduleJob(jobDetail, trigger);
+                // calculate whether the trigger can be triggered in the future
+                Calendar cal = null;
+                if (trigger.getCalendarName() != null) {
+                    cal = scheduler.getCalendar(trigger.getCalendarName());
+                }
+                OperableTrigger ot = (OperableTrigger) trigger;
+                Date ft = ot.computeFirstFireTime(cal);
+                if (ft == null && ignoreExpiredNextFireTime) {
+                    scheduled = false;
+                    LOG.warn("Job {} (cron={}, triggerType={}, jobClass={}) 
not scheduled, because it will never fire in the future",
+                            trigger.getKey(), cron, 
trigger.getClass().getSimpleName(),
+                            jobDetail.getJobClass().getSimpleName());
+                } else {
+                    // Schedule it now. Remember that scheduler might not be 
started it, but we can schedule now.
+                    scheduler.scheduleJob(jobDetail, trigger);
+                }
             } catch (ObjectAlreadyExistsException ex) {
                 // some other VM might may have stored the job & trigger in DB 
in clustered mode, in the mean time
                 if (!(getComponent().isClustered())) {
@@ -377,14 +411,16 @@ public class QuartzEndpoint extends DefaultEndpoint {
             }
         }
 
-        if (LOG.isInfoEnabled()) {
-            Object nextFireTime = trigger.getNextFireTime();
-            if (nextFireTime != null) {
-                nextFireTime = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(nextFireTime);
+        if (scheduled) {
+            if (LOG.isInfoEnabled()) {
+                Object nextFireTime = trigger.getNextFireTime();
+                if (nextFireTime != null) {
+                    nextFireTime = new 
SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").format(nextFireTime);
+                }
+                LOG.info("Job {} (cron={}, triggerType={}, jobClass={}) is 
scheduled. Next fire date is {}",
+                        trigger.getKey(), cron, 
trigger.getClass().getSimpleName(),
+                        jobDetail.getJobClass().getSimpleName(), nextFireTime);
             }
-            LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next 
fire date is {}",
-                    trigger.getKey(), trigger.getClass().getSimpleName(),
-                    jobDetail.getJobClass().getSimpleName(), nextFireTime);
         }
 
         // Increase camel job count for this endpoint
diff --git 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
index 7ef567fc5da..bab848ab635 100644
--- 
a/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
+++ 
b/dsl/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
@@ -459,6 +459,51 @@ public interface QuartzEndpointBuilderFactory {
             doSetProperty("customCalendar", customCalendar);
             return this;
         }
+        /**
+         * Whether to ignore quartz cannot schedule a trigger because the
+         * trigger will never fire in the future. This can happen when using a
+         * cron trigger that are configured to only run in the past. By 
default,
+         * Quartz will fail to schedule the trigger and therefore fail to start
+         * the Camel route. You can set this to true which then logs a WARN and
+         * then ignore the problem, meaning that the route will never fire in
+         * the future.
+         * 
+         * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param ignoreExpiredNextFireTime the value to set
+         * @return the dsl builder
+         */
+        default AdvancedQuartzEndpointBuilder ignoreExpiredNextFireTime(
+                boolean ignoreExpiredNextFireTime) {
+            doSetProperty("ignoreExpiredNextFireTime", 
ignoreExpiredNextFireTime);
+            return this;
+        }
+        /**
+         * Whether to ignore quartz cannot schedule a trigger because the
+         * trigger will never fire in the future. This can happen when using a
+         * cron trigger that are configured to only run in the past. By 
default,
+         * Quartz will fail to schedule the trigger and therefore fail to start
+         * the Camel route. You can set this to true which then logs a WARN and
+         * then ignore the problem, meaning that the route will never fire in
+         * the future.
+         * 
+         * The option will be converted to a &lt;code&gt;boolean&lt;/code&gt;
+         * type.
+         * 
+         * Default: false
+         * Group: advanced
+         * 
+         * @param ignoreExpiredNextFireTime the value to set
+         * @return the dsl builder
+         */
+        default AdvancedQuartzEndpointBuilder ignoreExpiredNextFireTime(
+                String ignoreExpiredNextFireTime) {
+            doSetProperty("ignoreExpiredNextFireTime", 
ignoreExpiredNextFireTime);
+            return this;
+        }
         /**
          * To configure additional options on the job.
          * 

Reply via email to