Spring integration + cron + quartz in a cluster?

I have a spring integration thread called by a cron expression, for example:

<int-ftp:inbound-channel-adapter id="my-input-endpoint" ...> <int:poller trigger="my-trigger"/> </int-ftp:inbound-channel-adapter> <bean id="my-trigger" class="org.springframework.scheduling.support.CronTrigger"> <constructor-arg value="0 * * * * *" /> </bean> 

It works great. But now I have to expand the implementation to make it ready for the cluster (doing the job on only one node cluster at the same time).

My desire would be to use the quartz framework in cluster mode (while keeping the job status in the database) to initiate this integration flow. Quartz provides the perfect solution out of the box. The only problem is how to integrate quartz with an existing inbout-channeler adapter? The trigger attribute for poller accepts only subclasses of org.springframework.scheduling.Trigger. I could not find a single bridge between the "polling trigger" and the quartz frame.

Thank you very much in advance!

+7
source share
4 answers

Here is one way ...

Set the autorun attribute of the inbound adapter to false.

Create a custom trigger that runs only once, right away ...

 public static class FireOnceTrigger implements Trigger { boolean done; public Date nextExecutionTime(TriggerContext triggerContext) { if (done) { return null; } done = true; return new Date(); } public void reset() { done = false; } } 

In your quartz assignment, get a link to the trigger and SourcePollingChannelAdapter .

When the quartz trigger fires, do the quartz task

  • adapter.stop ()
  • trigger.reset ()
  • adapter.start ()
+6
source

Gary's solution works. This spring context:

 <int-ftp:inbound-channel-adapter id="my-endpoint" auto-startup="false"> <int:poller trigger="my-endpoint-trigger"/> </int-ftp:inbound-channel-adapter> <bean id="my-endpoint-trigger" class="com.my.FireOnceTrigger"/> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="my-job-trigger" /> </list> </property> <property name="schedulerContextAsMap"> <map> <entry key="inputEndpoint"><ref bean="my-input-endpoint" /></entry> <entry key="inputEndpointTrigger"><ref bean="my-endpoint-trigger" /></entry> </map> </property> </bean> <bean id="my-job-trigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="cronExpression" value="0 * * * * ?" /> <property name="jobDetail" ref="my-job" /> </bean> <bean name="my-job" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.my.MyActivatorJob " /> </bean> 

and class MyActivatorJob:

 public class MyActivatorJob extends QuartzJobBean implements { private AbstractEndpoint inputEndpoint; private FireOnceTrigger inputEndpointTrigger; public void setInputEndpoint(final AbstractEndpoint pInputEndpoint) { this.inputEndpoint = pInputEndpoint; } public void setInputEndpointTrigger(final FireOnceTrigger pInputEndpointTrigger) { this.inputEndpointTrigger = pInputEndpointTrigger; } @Override protected void executeInternal(final JobExecutionContext pParamJobExecutionContext) throws JobExecutionException { inputEndpoint.stop(); inputEndpointTrigger.reset(); inputEndpoint.start(); } 

}

As a next step, this spring context should be reorganized to replace the use of schedulerContextAsMap with something more flexible and be able to define more tasks that activate and deactivate many different endpoints.

Thanks Gary so far!

+2
source

tried to integrate quartz and spring, as you suggested, but ran into two other problems:

1.) IncompatibleClassChangeError exception when using Quartz 2.x and spring 3.x. This is a known issue, but I did not find any solution for it.

2.) Injecting another spring bean into the Quarz job instance. I found some solutions, but no one works for me. I tried one with

 <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="jobFactory"> <bean class="org.springframework.scheduling.quartz.SpringBeanJobFactory" /> </property> <property name="triggers"> ... </property> <property name="schedulerContextAsMap"> <map> <entry key="inputEndpoint" value-ref="my-endpoint" /> </map> </property> </bean> 

to enter other beans into the task, but after adding this property to the SchedulerFactoryBean, the tasks are not executed (and I see no exception). Removing the "schedulerContextAsMap" property makes the job run again.

0
source

I have not tried, but I see that compatibility issues with Quartz 2 and Spring seem to have been fixed in Spring 3.1.1. See https://jira.springsource.org/browse/SPR-8889

0
source

All Articles