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 d02b0bb CAMEL-16773: camel-quartz - ScheduledPollConsumer should support quartz trigger and job parameters d02b0bb is described below commit d02b0bb4c0db68ba2158971868f844c8f77a20be Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Jul 1 14:25:45 2021 +0200 CAMEL-16773: camel-quartz - ScheduledPollConsumer should support quartz trigger and job parameters --- components/camel-quartz/pom.xml | 42 ++++++++ ...tzScheduledPollConsumerSchedulerConfigurer.java | 108 +++++++++++++++++++++ ...mer.quartz.QuartzScheduledPollConsumerScheduler | 2 + .../QuartzScheduledPollConsumerScheduler.java | 36 +++++++ .../quartz/FromFileQuartzSchedulerTest.java | 58 +++++++++++ .../camel/support/ScheduledPollConsumer.java | 7 ++ 6 files changed, 253 insertions(+) diff --git a/components/camel-quartz/pom.xml b/components/camel-quartz/pom.xml index ecad85f..fd2f139 100644 --- a/components/camel-quartz/pom.xml +++ b/components/camel-quartz/pom.xml @@ -113,4 +113,46 @@ </dependency> </dependencies> + <build> + <plugins> + <plugin> + <!-- we need to generate additional configurer classes --> + <groupId>org.apache.camel</groupId> + <artifactId>camel-package-maven-plugin</artifactId> + <executions> + <execution> + <id>generate-configurer</id> + <phase>process-classes</phase> + <goals> + <goal>generate-configurer</goal> + </goals> + </execution> + </executions> + </plugin> + <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/pollconsumer/quartz/QuartzScheduledPollConsumerSchedulerConfigurer.java b/components/camel-quartz/src/generated/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerSchedulerConfigurer.java new file mode 100644 index 0000000..66a7ce9 --- /dev/null +++ b/components/camel-quartz/src/generated/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerSchedulerConfigurer.java @@ -0,0 +1,108 @@ +/* Generated by camel build tools - do NOT edit this file! */ +package org.apache.camel.pollconsumer.quartz; + +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.spi.ExtendedPropertyConfigurerGetter; +import org.apache.camel.spi.PropertyConfigurerGetter; +import org.apache.camel.spi.ConfigurerStrategy; +import org.apache.camel.spi.GeneratedPropertyConfigurer; +import org.apache.camel.util.CaseInsensitiveMap; +import org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler; + +/** + * Generated by camel build tools - do NOT edit this file! + */ +@SuppressWarnings("unchecked") +public class QuartzScheduledPollConsumerSchedulerConfigurer extends org.apache.camel.support.component.PropertyConfigurerSupport implements GeneratedPropertyConfigurer, PropertyConfigurerGetter { + + @Override + public boolean configure(CamelContext camelContext, Object obj, String name, Object value, boolean ignoreCase) { + org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler target = (org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": target.setCamelContext(property(camelContext, org.apache.camel.CamelContext.class, value)); return true; + case "cron": + case "Cron": target.setCron(property(camelContext, java.lang.String.class, value)); return true; + case "deletejob": + case "DeleteJob": target.setDeleteJob(property(camelContext, boolean.class, value)); return true; + case "jobparameters": + case "JobParameters": target.setJobParameters(property(camelContext, java.util.Map.class, value)); return true; + case "quartzscheduler": + case "QuartzScheduler": target.setQuartzScheduler(property(camelContext, org.quartz.Scheduler.class, value)); return true; + case "timezone": + case "TimeZone": target.setTimeZone(property(camelContext, java.util.TimeZone.class, value)); return true; + case "triggergroup": + case "TriggerGroup": target.setTriggerGroup(property(camelContext, java.lang.String.class, value)); return true; + case "triggerid": + case "TriggerId": target.setTriggerId(property(camelContext, java.lang.String.class, value)); return true; + case "triggerparameters": + case "TriggerParameters": target.setTriggerParameters(property(camelContext, java.util.Map.class, value)); return true; + default: return false; + } + } + + @Override + public Class<?> getOptionType(String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": return org.apache.camel.CamelContext.class; + case "cron": + case "Cron": return java.lang.String.class; + case "deletejob": + case "DeleteJob": return boolean.class; + case "jobparameters": + case "JobParameters": return java.util.Map.class; + case "quartzscheduler": + case "QuartzScheduler": return org.quartz.Scheduler.class; + case "timezone": + case "TimeZone": return java.util.TimeZone.class; + case "triggergroup": + case "TriggerGroup": return java.lang.String.class; + case "triggerid": + case "TriggerId": return java.lang.String.class; + case "triggerparameters": + case "TriggerParameters": return java.util.Map.class; + default: return null; + } + } + + @Override + public Object getOptionValue(Object obj, String name, boolean ignoreCase) { + org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler target = (org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler) obj; + switch (ignoreCase ? name.toLowerCase() : name) { + case "camelcontext": + case "CamelContext": return target.getCamelContext(); + case "cron": + case "Cron": return target.getCron(); + case "deletejob": + case "DeleteJob": return target.isDeleteJob(); + case "jobparameters": + case "JobParameters": return target.getJobParameters(); + case "quartzscheduler": + case "QuartzScheduler": return target.getQuartzScheduler(); + case "timezone": + case "TimeZone": return target.getTimeZone(); + case "triggergroup": + case "TriggerGroup": return target.getTriggerGroup(); + case "triggerid": + case "TriggerId": return target.getTriggerId(); + case "triggerparameters": + case "TriggerParameters": return target.getTriggerParameters(); + default: return null; + } + } + + @Override + public Object getCollectionValueType(Object target, String name, boolean ignoreCase) { + switch (ignoreCase ? name.toLowerCase() : name) { + case "jobparameters": + case "JobParameters": return java.lang.Object.class; + case "triggerparameters": + case "TriggerParameters": return java.lang.Object.class; + default: return null; + } + } +} + diff --git a/components/camel-quartz/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler b/components/camel-quartz/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler new file mode 100644 index 0000000..df68194 --- /dev/null +++ b/components/camel-quartz/src/generated/resources/META-INF/services/org/apache/camel/configurer/org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerScheduler @@ -0,0 +1,2 @@ +# Generated by camel build tools - do NOT edit this file! +class=org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerSchedulerConfigurer diff --git a/components/camel-quartz/src/main/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerScheduler.java b/components/camel-quartz/src/main/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerScheduler.java index 7276a93..c5bfaf3 100644 --- a/components/camel-quartz/src/main/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerScheduler.java +++ b/components/camel-quartz/src/main/java/org/apache/camel/pollconsumer/quartz/QuartzScheduledPollConsumerScheduler.java @@ -16,6 +16,8 @@ */ package org.apache.camel.pollconsumer.quartz; +import java.util.HashMap; +import java.util.Map; import java.util.TimeZone; import org.apache.camel.CamelContext; @@ -26,7 +28,9 @@ import org.apache.camel.RuntimeCamelException; import org.apache.camel.component.quartz.QuartzComponent; import org.apache.camel.component.quartz.QuartzConstants; import org.apache.camel.component.quartz.QuartzHelper; +import org.apache.camel.spi.Configurer; import org.apache.camel.spi.ScheduledPollConsumerScheduler; +import org.apache.camel.support.PropertyBindingSupport; import org.apache.camel.support.service.ServiceSupport; import org.apache.camel.util.StringHelper; import org.quartz.CronScheduleBuilder; @@ -48,6 +52,7 @@ import org.slf4j.LoggerFactory; * A quartz based {@link ScheduledPollConsumerScheduler} which uses a {@link CronTrigger} to define when the poll should * be triggered. */ +@Configurer public class QuartzScheduledPollConsumerScheduler extends ServiceSupport implements ScheduledPollConsumerScheduler, NonManagedService { @@ -59,6 +64,8 @@ public class QuartzScheduledPollConsumerScheduler extends ServiceSupport private Runnable runnable; private String cron; private String triggerId; + private Map<String, Object> triggerParameters; + private Map<String, Object> jobParameters; private String triggerGroup = "QuartzScheduledPollConsumerScheduler"; private TimeZone timeZone = TimeZone.getDefault(); private boolean deleteJob = true; @@ -157,6 +164,22 @@ public class QuartzScheduledPollConsumerScheduler extends ServiceSupport this.triggerGroup = triggerGroup; } + public Map<String, Object> getTriggerParameters() { + return triggerParameters; + } + + public void setTriggerParameters(Map<String, Object> triggerParameters) { + this.triggerParameters = triggerParameters; + } + + public Map<String, Object> getJobParameters() { + return jobParameters; + } + + public void setJobParameters(Map<String, Object> jobParameters) { + this.jobParameters = jobParameters; + } + public boolean isDeleteJob() { return deleteJob; } @@ -203,6 +226,13 @@ public class QuartzScheduledPollConsumerScheduler extends ServiceSupport map.put(QuartzConstants.QUARTZ_TRIGGER_CRON_TIMEZONE, getTimeZone().getID()); job = JobBuilder.newJob(QuartzScheduledPollConsumerJob.class).usingJobData(map).build(); + // Let user parameters to further set JobDetail properties. + if (jobParameters != null && jobParameters.size() > 0) { + // need to use a copy to keep the parameters + Map<String, Object> copy = new HashMap<>(jobParameters); + LOG.debug("Setting user extra jobParameters {}", copy); + PropertyBindingSupport.bindProperties(camelContext, job, copy); + } // store additional information on job such as camel context etc QuartzHelper.updateJobDataMap(getCamelContext(), job, null); @@ -210,6 +240,12 @@ public class QuartzScheduledPollConsumerScheduler extends ServiceSupport trigger = TriggerBuilder.newTrigger().withIdentity(id, triggerGroup) .withSchedule(CronScheduleBuilder.cronSchedule(getCron()).inTimeZone(getTimeZone())) .build(); + if (triggerParameters != null && triggerParameters.size() > 0) { + // need to use a copy to keep the parameters + Map<String, Object> copy = new HashMap<>(triggerParameters); + LOG.debug("Setting user extra triggerParameters {}", copy); + PropertyBindingSupport.bindProperties(camelContext, trigger, copy); + } LOG.debug("Scheduling job: {} with trigger: {}", job, trigger.getKey()); quartzScheduler.scheduleJob(job, trigger); diff --git a/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/FromFileQuartzSchedulerTest.java b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/FromFileQuartzSchedulerTest.java new file mode 100644 index 0000000..fd82888 --- /dev/null +++ b/components/camel-quartz/src/test/java/org/apache/camel/component/quartz/FromFileQuartzSchedulerTest.java @@ -0,0 +1,58 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.quartz; + +import java.io.File; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.util.FileUtil; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class FromFileQuartzSchedulerTest extends BaseQuartzTest { + protected MockEndpoint resultEndpoint; + + @Override + @BeforeEach + public void setUp() throws Exception { + FileUtil.removeDir(new File("target/inbox")); + super.setUp(); + } + + @Test + public void testQuartzRoute() throws Exception { + resultEndpoint = getMockEndpoint("mock:result"); + resultEndpoint.expectedMessageCount(2); + + template.sendBody("file:target/inbox", "Hello World"); + template.sendBody("file:target/inbox", "Bye World"); + + resultEndpoint.assertIsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new RouteBuilder() { + public void configure() { + from("file:target/inbox?scheduler=quartz&scheduler.trigger.misfireInstruction=2&scheduler.cron=0/2+*+*+*+*+?") + .routeId("myRoute") + .to("mock:result"); + } + }; + } +} diff --git a/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollConsumer.java b/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollConsumer.java index 68d4c18..098f719 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollConsumer.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/ScheduledPollConsumer.java @@ -33,6 +33,7 @@ import org.apache.camel.spi.PollingConsumerPollStrategy; import org.apache.camel.spi.ScheduledPollConsumerScheduler; import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.PropertiesHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -465,6 +466,12 @@ public abstract class ScheduledPollConsumer extends DefaultConsumer // need to use a copy in case the consumer is restarted so we keep the properties Map<String, Object> copy = new LinkedHashMap<>(schedulerProperties); PropertyBindingSupport.build().bind(getEndpoint().getCamelContext(), scheduler, copy); + // special for trigger and job parameters + Map<String, Object> triggerParameters = PropertiesHelper.extractProperties(copy, "trigger."); + Map<String, Object> jobParameters = PropertiesHelper.extractProperties(copy, "job."); + PropertyBindingSupport.build().bind(getEndpoint().getCamelContext(), scheduler, "triggerParameters", + triggerParameters); + PropertyBindingSupport.build().bind(getEndpoint().getCamelContext(), scheduler, "jobParameters", jobParameters); if (copy.size() > 0) { throw new FailedToCreateConsumerException( getEndpoint(), "There are " + copy.size()