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 2022/08/01 10:17:37 UTC

[camel] branch camel-3.14.x updated: CAMEL-18318: camel-quartz - Add ignoreExpiredNextFireTime option.

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

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


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

commit 5a202d09db85f627568b9712844adb22cef53501
Author: Claus Ibsen <cl...@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     | 49 +++++++++++++++++++---
 .../endpoint/dsl/QuartzEndpointBuilderFactory.java | 45 ++++++++++++++++++++
 7 files changed, 118 insertions(+), 7 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 642c58f06a7..556ee0cc699 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
@@ -49,6 +49,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." },
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 143631c8d95..2b22f4685e4 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":
@@ -75,6 +77,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":
@@ -115,6 +119,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 4d657349bd9..09e74e0c25e 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
@@ -20,7 +20,7 @@ public class QuartzEndpointUriFactory extends org.apache.camel.support.component
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(19);
+        Set<String> props = new HashSet<>(20);
         props.add("cron");
         props.add("triggerName");
         props.add("customCalendar");
@@ -38,6 +38,7 @@ public class QuartzEndpointUriFactory extends org.apache.camel.support.component
         props.add("startDelayedSeconds");
         props.add("jobParameters");
         props.add("exceptionHandler");
+        props.add("ignoreExpiredNextFireTime");
         props.add("usingFixedCamelContextName");
         props.add("stateful");
         PROPERTY_NAMES = Collections.unmodifiableSet(props);
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 642c58f06a7..556ee0cc699 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
@@ -49,6 +49,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." },
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 9c43e283837..ec20dda8595 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;
@@ -81,6 +82,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() {
     }
@@ -202,6 +205,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 {
@@ -424,6 +443,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 10cfe802b5a..3474b2fe362 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
@@ -48,6 +48,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;
 
@@ -81,6 +82,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
@@ -130,6 +133,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;
     }
@@ -362,6 +381,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)) {
@@ -369,8 +389,23 @@ 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())) {
@@ -384,10 +419,12 @@ public class QuartzEndpoint extends DefaultEndpoint {
             }
         }
 
-        if (LOG.isInfoEnabled()) {
-            LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
-                    trigger.getKey(), trigger.getClass().getSimpleName(),
-                    jobDetail.getJobClass().getSimpleName(), trigger.getNextFireTime());
+        if (scheduled) {
+            if (LOG.isInfoEnabled()) {
+                LOG.info("Job {} (triggerType={}, jobClass={}) is scheduled. Next fire date is {}",
+                        trigger.getKey(), trigger.getClass().getSimpleName(),
+                        jobDetail.getJobClass().getSimpleName(), trigger.getNextFireTime());
+            }
         }
 
         // Increase camel job count for this endpoint
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
index 3361a15e07c..3b02a77c62e 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/QuartzEndpointBuilderFactory.java
@@ -487,6 +487,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.
          *