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: <code>boolean</code> 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 <code>boolean</code> + * 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. *