1
votes

We have Quartz Job + File Integration adapter using XML configurations and is working fine, however since trying to move to Spring Boot and these configurations to annotations

Below is the XML configuration for which I am looking for equivalent annotations and bindings

<bean id="scheduler" 
        class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="schedulerContextAsMap">
            <map>
                <entry key="inboundadapterendpoint"><ref bean="incomingfiles" /></entry>
                <entry key="inboundendpointtrigger"><ref bean="incomingfiles-trigger"/></entry>
            </map>
        </property>
</bean>

<bean id="inboundendpointtrigger" class="abc.xyz.Trigger" />

<file:inbound-channel-adapter id="incomingfiles" channel="xyz" directory=""  scanner="recursiveScanner" auto-startup="false" prevent-duplicates="false">
    <integration:poller task-executor="fileChannelTaskExecutor" trigger="incomingfiles-trigger" max-messages-per-poll="1">
    </integration:poller>
</file:inbound-channel-adapter>

How do we get the Inbound Adapter Bean & poller trigger created using annotations below is injected during scheduler factory creation in spring Boot quartz config

@Bean
@InboundChannelAdapter(poller = @Poller(trigger="customTrigger")
public MessageSource<File> fileReadingMessageSource() {

}

Thanks in advance for any help or suggestions regarding the same

Artem Bilan, thanks very much for the response.

Follow up question post trying out the code provided in response

@Configuration
public class QuartzConfig {

    @Autowired
    private CustomTrigger inboundEndPointTrigger;

    @Autowired
    private AbstractEndpoint incomingFiles;


    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {

    System.out.println("incomingFiles value is  " + incomingFiles);

    }   
}



@Bean(name = "incomingFiles")
@InboundChannelAdapter(autoStartup = "false", value = "xyz", poller = @Poller(trigger = "inboundEndPointTrigger", maxMessagesPerPoll = "2", errorChannel = "abc"))
public MessageSource<File> fileReadingMessageSource() {

}

Output of above is reference for errorLogger instead of Inbound Channel Adapter.

incomingFiles value is bean '_org.springframework.integration.errorLogger'

How do i bind the exact Inbound Adapter with name incomingFiles to scheduler factory ?


Update after trying out with @EndPointId...

  @Bean
  @EndPointId("incomingFiles")
    @InboundChannelAdapter(autoStartup = "false", value = "xyz", poller = @Poller(trigger = "inboundEndPointTrigger", maxMessagesPerPoll = "2", errorChannel = "abc"))
    public MessageSource<File> fileReadingMessageSource() {

    }

System.out.println("incomingFiles value is  " + incomingFiles);  print in  QuartzConfig class above is still giving a reference to  Logger object 

incomingFiles value is  bean '_org.springframework.integration.errorLogger'

Found the response in below SO (Spring Cloud Stream + Quartz ) on how the bean will be created for Inbound Channel Adapter.

Since the AbstractEndPoint is returning the logger reference instead of InboundChannelAdapter , 
is it ok to  get the Inbound Adapter channel bean reference via application context  in scheduler factory ? are there any issues with this ?

try {
    ApplicationContext applicationContext = (ApplicationContext) context.getScheduler().getContext().get("applicationContext");
    AbstractEndpoint abstractEndPoint = (AbstractEndpoint) applicationContext
                    .getBean("fileConfig.fileReadingMessageSource.inboundChannelAdapter");
} catch(SchedulerException ex) {
}


fileConfig is the Spring File integration configuration class name where InboundChannelAdapter is defined.. 
1

1 Answers

0
votes

I'm not sure why you have closed your old question - you could just edit it properly and we would have a link to other question. But anyway, the answer is like this:

Any XML bean definition could be declared in Java & annotation config with a @Bean method definition.

So, that <bean id="inboundendpointtrigger" class="abc.xyz.Trigger" /> would be in Java like this:

@Bean
Trigger customTrigger() {
   return new abc.xyz.Trigger();
}

You already use its bean name as a reference in the @Poller.

The same you do for the SchedulerFactoryBean and configure its setSchedulerContextAsMap() in that @Bean method. You have already a customTrigger() bean for reference and do get access to the SourcePollingChannelAdapter endpoint based on the @InboundChannelAdapter, you need to inject into a @Bean method. Kinda this:

 @Bean
 SchedulerFactoryBean schedulerFactory(Trigger trigger, SourcePollingChannelAdapter endpoint) {

 }

Don't forget to use an @InboundChannelAdapter(autoStartup = "false") as Gary recommends in other SO question.