весенняя интеграция + cron + кварц в кластере?

У меня есть поток интеграции spring, вызванный выражением cron следующим образом:

<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>

Он работает нормально. Но теперь я должен расширить реализацию, чтобы сделать ее готовой к кластеру (выполнение задания только на одном узле кластера в тот же момент времени).

Я хотел бы использовать Quartz framework в режиме кластера (сохранение статуса задания в базе данных) для запуска этого потока интеграции. Кварц обеспечивает beautful разрешение из коробки. Единственный проблема в том, как интегрировать кварц с существующим inbout-channer-adaptor? Атрибут "trigger" "poller" принимает только подклассы организации.springframework.планирование.Спусковой крючок. Я не мог найти никакого моста между "poller trigger" и кварцевым каркасом.

заранее большое спасибо!

4 ответов


вот один из способов...

установите для атрибута автозапуска входящего адаптера значение false.

создайте пользовательский триггер, который срабатывает только один раз, немедленно...

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;
    }
}

в вашей кварцевой работе получите ссылку на триггер и SourcePollingChannelAdapter.

когда кварцевый триггер срабатывает, есть кварцевая работа

  1. адаптер.stop ()
  2. триггер.reset ()
  3. адаптер.start ()

решение от Гэри работает. Это мой весенний контекст:

<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>

и класс 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();
}

}

в качестве следующего шага этот весенний контекст должен быть переработан, чтобы заменить использование schedulerContextAsMap чем-то более гибким и иметь возможность определять больше заданий, активирующих и деактивирующих много разных конечных точек.

спасибо Гэри до сих пор!


попытался интегрировать кварц и пружину, как вы предложили, но столкнулся с двумя другими проблемами:

1.) Исключение IncompatibleClassChangeError при использовании кварца 2.x и Весна 3.X. Это известная проблема, но я не нашел для нее решения.

2.) Инъекция другого весеннего Боба в экземпляр задания Quarz. Я нашел несколько решений, но никто не работает для меня. Я пробовал использовать

<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>

ввести другие бобы в задание, но после добавления это свойство в SchedulerFactoryBean задания не выполняются (и я не вижу никаких исключений). Удаление свойства "schedulerContextAsMap" делает задание запущенным снова.


Я не пробовал, но вижу, что проблемы совместимости Quartz 2 и Spring, похоже, были исправлены весной 3.1.1. См.https://jira.springsource.org/browse/SPR-8889