This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new cc61bb8 [CAMEL-17133] camel-quartz: allow missfire execution for cron
triggers (#6344)
cc61bb8 is described below
commit cc61bb8c75231f5b6c3ee115831705f6ee9ed641
Author: Alexey Markevich <[email protected]>
AuthorDate: Wed Oct 27 12:15:22 2021 +0000
[CAMEL-17133] camel-quartz: allow missfire execution for cron triggers
(#6344)
* CAMEL-17133 camel-quartz: allow missfire execution for cron triggers
Allow to set 'triggerStartDelay' in the past to have missfire execution
for cron triggers.
Existing 'fireNow' can be avoided due to new TriggerBuilder already have
'startAt' now.
* update migration guide
* fix checkstyle
---
.../apache/camel/catalog/components/quartz.json | 3 +-
components/camel-quartz/pom.xml | 28 --------
.../component/quartz/QuartzEndpointConfigurer.java | 6 --
.../component/quartz/QuartzEndpointUriFactory.java | 3 +-
.../org/apache/camel/component/quartz/quartz.json | 3 +-
.../camel/component/quartz/QuartzEndpoint.java | 74 ++++++----------------
...owTest.java => QuartzCronRouteFireNowTest.java} | 17 ++---
.../quartz/QuartzRouteFireNowOnlyOnceTest.java | 2 +-
.../component/quartz/QuartzRouteFireNowTest.java | 2 +-
.../ROOT/pages/camel-3x-upgrade-guide-3_13.adoc | 4 ++
10 files changed, 38 insertions(+), 104 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 63f376b..e57820f 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
@@ -54,8 +54,7 @@
"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." },
"usingFixedCamelContextName": { "kind": "parameter", "displayName": "Using
Fixed Camel Context Name", "group": "advanced", "label": "advanced",
"required": false, "type": "boolean", "javaType": "boolean", "deprecated":
false, "autowired": false, "secret": false, "defaultValue": false,
"description": "If it is true, JobDataMap uses the CamelContext name directly
to reference the CamelContext, if it is false, JobDataMap uses use the
CamelContext management name which could be changed d [...]
"autoStartScheduler": { "kind": "parameter", "displayName": "Auto Start
Scheduler", "group": "scheduler", "label": "scheduler", "required": false,
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": true, "description": "Whether or not
the scheduler should be auto started." },
- "fireNow": { "kind": "parameter", "displayName": "Fire Now", "group":
"scheduler", "label": "scheduler", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "description": "If it is true will fire the
trigger when the route is start when using SimpleTrigger." },
"startDelayedSeconds": { "kind": "parameter", "displayName": "Start
Delayed Seconds", "group": "scheduler", "label": "scheduler", "required":
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired":
false, "secret": false, "description": "Seconds to wait before starting the
quartz scheduler." },
- "triggerStartDelay": { "kind": "parameter", "displayName": "Trigger Start
Delay", "group": "scheduler", "label": "scheduler", "required": false, "type":
"duration", "javaType": "long", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "500", "description": "In case of scheduler
has already started, we want the trigger start slightly after current time to
ensure endpoint is fully started before the job kicks in." }
+ "triggerStartDelay": { "kind": "parameter", "displayName": "Trigger Start
Delay", "group": "scheduler", "label": "scheduler", "required": false, "type":
"duration", "javaType": "long", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "500", "description": "In case of scheduler
has already started, we want the trigger start slightly after current time to
ensure endpoint is fully started before the job kicks in. Negative value shifts
trigger start time in the past." }
}
}
diff --git a/components/camel-quartz/pom.xml b/components/camel-quartz/pom.xml
index 3c8951d..88182771 100644
--- a/components/camel-quartz/pom.xml
+++ b/components/camel-quartz/pom.xml
@@ -113,32 +113,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>build-helper-maven-plugin</artifactId>
- <executions>
- <execution>
- <phase>generate-sources</phase>
- <goals>
- <goal>add-source</goal>
- <goal>add-resource</goal>
- </goals>
- <configuration>
- <sources>
- <source>src/generated/java</source>
- </sources>
- <resources>
- <resource>
-
<directory>src/generated/resources</directory>
- </resource>
- </resources>
- </configuration>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>
-
</project>
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 9c4bfca..143631c 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,8 +36,6 @@ 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 "firenow":
- case "fireNow": target.setFireNow(property(camelContext,
boolean.class, value)); return true;
case "jobparameters":
case "jobParameters": target.setJobParameters(property(camelContext,
java.util.Map.class, value)); return true;
case "pausejob":
@@ -77,8 +75,6 @@ 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 "firenow":
- case "fireNow": return boolean.class;
case "jobparameters":
case "jobParameters": return java.util.Map.class;
case "pausejob":
@@ -119,8 +115,6 @@ public class QuartzEndpointConfigurer extends
PropertyConfigurerSupport implemen
case "exceptionHandler": return target.getExceptionHandler();
case "exchangepattern":
case "exchangePattern": return target.getExchangePattern();
- case "firenow":
- case "fireNow": return target.isFireNow();
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 ce2f299..4d65734 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<>(20);
+ Set<String> props = new HashSet<>(19);
props.add("cron");
props.add("triggerName");
props.add("customCalendar");
@@ -40,7 +40,6 @@ public class QuartzEndpointUriFactory extends
org.apache.camel.support.component
props.add("exceptionHandler");
props.add("usingFixedCamelContextName");
props.add("stateful");
- props.add("fireNow");
PROPERTY_NAMES = Collections.unmodifiableSet(props);
SECRET_PROPERTY_NAMES = Collections.emptySet();
}
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 63f376b..e57820f 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
@@ -54,8 +54,7 @@
"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." },
"usingFixedCamelContextName": { "kind": "parameter", "displayName": "Using
Fixed Camel Context Name", "group": "advanced", "label": "advanced",
"required": false, "type": "boolean", "javaType": "boolean", "deprecated":
false, "autowired": false, "secret": false, "defaultValue": false,
"description": "If it is true, JobDataMap uses the CamelContext name directly
to reference the CamelContext, if it is false, JobDataMap uses use the
CamelContext management name which could be changed d [...]
"autoStartScheduler": { "kind": "parameter", "displayName": "Auto Start
Scheduler", "group": "scheduler", "label": "scheduler", "required": false,
"type": "boolean", "javaType": "boolean", "deprecated": false, "autowired":
false, "secret": false, "defaultValue": true, "description": "Whether or not
the scheduler should be auto started." },
- "fireNow": { "kind": "parameter", "displayName": "Fire Now", "group":
"scheduler", "label": "scheduler", "required": false, "type": "boolean",
"javaType": "boolean", "deprecated": false, "autowired": false, "secret":
false, "defaultValue": false, "description": "If it is true will fire the
trigger when the route is start when using SimpleTrigger." },
"startDelayedSeconds": { "kind": "parameter", "displayName": "Start
Delayed Seconds", "group": "scheduler", "label": "scheduler", "required":
false, "type": "integer", "javaType": "int", "deprecated": false, "autowired":
false, "secret": false, "description": "Seconds to wait before starting the
quartz scheduler." },
- "triggerStartDelay": { "kind": "parameter", "displayName": "Trigger Start
Delay", "group": "scheduler", "label": "scheduler", "required": false, "type":
"duration", "javaType": "long", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "500", "description": "In case of scheduler
has already started, we want the trigger start slightly after current time to
ensure endpoint is fully started before the job kicks in." }
+ "triggerStartDelay": { "kind": "parameter", "displayName": "Trigger Start
Delay", "group": "scheduler", "label": "scheduler", "required": false, "type":
"duration", "javaType": "long", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "500", "description": "In case of scheduler
has already started, we want the trigger start slightly after current time to
ensure endpoint is fully started before the job kicks in. Negative value shifts
trigger start time in the past." }
}
}
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 3b5ca97..f7a6415 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
@@ -81,8 +81,6 @@ public class QuartzEndpoint extends DefaultEndpoint {
private String cron;
@UriParam
private boolean stateful;
- @UriParam(label = "scheduler")
- private boolean fireNow;
@UriParam(defaultValue = "true")
private boolean deleteJob = true;
@UriParam
@@ -132,10 +130,6 @@ public class QuartzEndpoint extends DefaultEndpoint {
return stateful;
}
- public boolean isFireNow() {
- return fireNow;
- }
-
public long getTriggerStartDelay() {
return triggerStartDelay;
}
@@ -159,7 +153,7 @@ public class QuartzEndpoint extends DefaultEndpoint {
/**
* In case of scheduler has already started, we want the trigger start
slightly after current time to ensure
- * endpoint is fully started before the job kicks in.
+ * endpoint is fully started before the job kicks in. Negative value
shifts trigger start time in the past.
*/
public void setTriggerStartDelay(long triggerStartDelay) {
this.triggerStartDelay = triggerStartDelay;
@@ -175,13 +169,6 @@ public class QuartzEndpoint extends DefaultEndpoint {
}
/**
- * If it is true will fire the trigger when the route is start when using
SimpleTrigger.
- */
- public void setFireNow(boolean fireNow) {
- this.fireNow = fireNow;
- }
-
- /**
* Uses a Quartz @PersistJobDataAfterExecution and
@DisallowConcurrentExecution instead of the default job.
*/
public void setStateful(boolean stateful) {
@@ -441,52 +428,40 @@ public class QuartzEndpoint extends DefaultEndpoint {
private Trigger createTrigger(JobDetail jobDetail) throws Exception {
// use a defensive copy to keep the trigger parameters on the endpoint
- Map<String, Object> copy = new HashMap<>(triggerParameters);
+ final Map<String, Object> copy = new HashMap<>(triggerParameters);
- Trigger result;
- Date startTime = new Date();
- if (getComponent().getScheduler().isStarted()) {
- startTime = new Date(System.currentTimeMillis() +
triggerStartDelay);
+ final TriggerBuilder<Trigger> triggerBuilder =
TriggerBuilder.newTrigger().withIdentity(triggerKey);
+
+ if (getComponent().getScheduler().isStarted() || triggerStartDelay <
0) {
+ triggerBuilder.startAt(new Date(System.currentTimeMillis() +
triggerStartDelay));
}
if (cron != null) {
LOG.debug("Creating CronTrigger: {}", cron);
- String timeZone = (String) copy.get("timeZone");
+ final String timeZone = (String) copy.get("timeZone");
if (timeZone != null) {
if (ObjectHelper.isNotEmpty(customCalendar)) {
- result = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(cronSchedule(cron)
.withMisfireHandlingInstructionFireAndProceed()
.inTimeZone(TimeZone.getTimeZone(timeZone)))
-
.modifiedByCalendar(QuartzConstants.QUARTZ_CAMEL_CUSTOM_CALENDAR)
- .build();
+
.modifiedByCalendar(QuartzConstants.QUARTZ_CAMEL_CUSTOM_CALENDAR);
} else {
- result = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(cronSchedule(cron)
.withMisfireHandlingInstructionFireAndProceed()
-
.inTimeZone(TimeZone.getTimeZone(timeZone)))
- .build();
+
.inTimeZone(TimeZone.getTimeZone(timeZone)));
}
jobDetail.getJobDataMap().put(QuartzConstants.QUARTZ_TRIGGER_CRON_TIMEZONE,
timeZone);
} else {
if (ObjectHelper.isNotEmpty(customCalendar)) {
- result = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(cronSchedule(cron)
.withMisfireHandlingInstructionFireAndProceed())
-
.modifiedByCalendar(QuartzConstants.QUARTZ_CAMEL_CUSTOM_CALENDAR)
- .build();
+
.modifiedByCalendar(QuartzConstants.QUARTZ_CAMEL_CUSTOM_CALENDAR);
} else {
- result = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(cronSchedule(cron)
-
.withMisfireHandlingInstructionFireAndProceed())
- .build();
+
.withMisfireHandlingInstructionFireAndProceed());
}
}
@@ -511,35 +486,26 @@ public class QuartzEndpoint extends DefaultEndpoint {
// need to update the parameters
copy.put("repeatInterval", interval);
}
- TriggerBuilder<SimpleTrigger> triggerBuilder;
if (ObjectHelper.isNotEmpty(customCalendar)) {
- triggerBuilder = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(simpleSchedule().withMisfireHandlingInstructionFireNow()
.withRepeatCount(repeat).withIntervalInMilliseconds(interval))
.modifiedByCalendar(QuartzConstants.QUARTZ_CAMEL_CUSTOM_CALENDAR);
} else {
- triggerBuilder = TriggerBuilder.newTrigger()
- .withIdentity(triggerKey)
- .startAt(startTime)
+ triggerBuilder
.withSchedule(simpleSchedule().withMisfireHandlingInstructionFireNow()
.withRepeatCount(repeat).withIntervalInMilliseconds(interval));
}
- if (fireNow) {
- triggerBuilder = triggerBuilder.startNow();
- }
-
- result = triggerBuilder.build();
-
// enrich job map with details
jobDetail.getJobDataMap().put(QuartzConstants.QUARTZ_TRIGGER_TYPE,
"simple");
jobDetail.getJobDataMap().put(QuartzConstants.QUARTZ_TRIGGER_SIMPLE_REPEAT_COUNTER,
repeat);
jobDetail.getJobDataMap().put(QuartzConstants.QUARTZ_TRIGGER_SIMPLE_REPEAT_INTERVAL,
interval);
}
- if (copy.size() > 0) {
+ final Trigger result = triggerBuilder.build();
+
+ if (!copy.isEmpty()) {
LOG.debug("Setting user extra triggerParameters {}", copy);
setProperties(result, copy);
}
diff --git
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzCronRouteFireNowTest.java
similarity index 77%
copy from
components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
copy to
components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzCronRouteFireNowTest.java
index 8beb6b4..c8e77ea 100644
---
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
+++
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzCronRouteFireNowTest.java
@@ -16,20 +16,22 @@
*/
package org.apache.camel.component.quartz;
+import java.util.concurrent.TimeUnit;
+
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.junit.jupiter.api.Test;
+import org.quartz.SchedulerException;
-public class QuartzRouteFireNowTest extends BaseQuartzTest {
+public class QuartzCronRouteFireNowTest extends BaseQuartzTest {
protected MockEndpoint resultEndpoint;
@Test
public void testQuartzRoute() throws Exception {
resultEndpoint = getMockEndpoint("mock:result");
- resultEndpoint.expectedMinimumMessageCount(2);
-
resultEndpoint.message(0).header("triggerName").isEqualTo("myTimerName");
- resultEndpoint.message(0).header("triggerGroup").isEqualTo("myGroup");
+ resultEndpoint.expectedMinimumMessageCount(1);
+ resultEndpoint.message(0).header("triggerName").isEqualTo("daily");
// lets test the receive worked
resultEndpoint.assertIsSatisfied();
@@ -38,12 +40,11 @@ public class QuartzRouteFireNowTest extends BaseQuartzTest {
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
- public void configure() {
- // START SNIPPET: example
-
from("quartz://myGroup/myTimerName?fireNow=true&trigger.repeatInterval=100&trigger.repeatCount=2")
+ public void configure() throws SchedulerException {
+ // daily trigger strarted a day ago
+ from("quartz://daily?triggerStartDelay=" +
TimeUnit.DAYS.toMillis(-1L) + "&cron=0+0+0+*+*+?")
.to("log:quartz")
.to("mock:result");
- // END SNIPPET: example
}
};
}
diff --git
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowOnlyOnceTest.java
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowOnlyOnceTest.java
index 9d84e7b..26fcaf7 100644
---
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowOnlyOnceTest.java
+++
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowOnlyOnceTest.java
@@ -40,7 +40,7 @@ public class QuartzRouteFireNowOnlyOnceTest extends
BaseQuartzTest {
return new RouteBuilder() {
public void configure() {
// START SNIPPET: example
-
from("quartz://myGroup/myTimerName?fireNow=true&trigger.repeatInterval=100&trigger.repeatCount=0")
+
from("quartz://myGroup/myTimerName?trigger.repeatInterval=100&trigger.repeatCount=0")
.to("log:quartz")
.to("mock:result");
// END SNIPPET: example
diff --git
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
index 8beb6b4..e80845a 100644
---
a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
+++
b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/QuartzRouteFireNowTest.java
@@ -40,7 +40,7 @@ public class QuartzRouteFireNowTest extends BaseQuartzTest {
return new RouteBuilder() {
public void configure() {
// START SNIPPET: example
-
from("quartz://myGroup/myTimerName?fireNow=true&trigger.repeatInterval=100&trigger.repeatCount=2")
+
from("quartz://myGroup/myTimerName?trigger.repeatInterval=100&trigger.repeatCount=2")
.to("log:quartz")
.to("mock:result");
// END SNIPPET: example
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_13.adoc
b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_13.adoc
index 25758d8..b585e69 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_13.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-3x-upgrade-guide-3_13.adoc
@@ -114,3 +114,7 @@ This is i.e. needed when using `camel-servlet` which runs
under a specific `cont
Support for rendering api docs by discovering other CamelContext via JMX in
the same JVM has been removed.
Rendering of api docs is now only supported for the same CamelContext.
+=== camel-quartz
+
+The `fireNow` parameter was removed because have no effect.
+The `triggerStartDelay` parameter supports negative value to shift trigger
start time in the past. It allows to fire the trigger immediately by configured
`MISFIRE_INSTRUCTION_FIRE_ONCE_NOW`.