在春季集成文件轮询器轮询文件后,春季批处理作业应仅执行一次

时间:2019-07-15 14:29:18

标签: spring-boot spring-integration spring-batch spring-integration-dsl poller

我正在尝试从可能包含一个或多个文件的系统文件夹中轮询文件,对于这些文件,我仅需触发一次批处理作业,而不是次数不等于该文件夹中的文件数。就我而言,我的批处理一次要处理多个文件,我只希望轮询器将信号发送给批处理仅一次即可开始工作。

尝试了poller.maxMessagesPerPoll(1)等,但是有所不同。我面临的问题是,批处理作业被触发等于轮询器在轮询文件夹中获取的文件数。我只想执行一次批处理

@Bean
public FileMessageToJobRequest fileMessageToJobRequest() {
    FileMessageToJobRequest fileMessageToJobRequest = new FileMessageToJobRequest();
    fileMessageToJobRequest.setJob(fileMessageBatchJob);
    return fileMessageToJobRequest;
}
@Bean
public JobLaunchingGateway jobLaunchingGateway() {
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
    simpleJobLauncher.setJobRepository(jobRepository);
    simpleJobLauncher.setTaskExecutor(new SyncTaskExecutor());
    JobLaunchingGateway jobLaunchingGateway = new JobLaunchingGateway(simpleJobLauncher);
    return jobLaunchingGateway;
}
@Bean
public IntegrationFlow integrationFlow(JobLaunchingGateway jobLaunchingGateway) {
    System.out.println("&&&&&&&&&&&&&&&&&&Inside Integration Flow!!!!");
    return IntegrationFlows
            .from(Files.inboundAdapter(new File("C:\\apps_data\\recv")),
                    c -> c.poller(Pollers.fixedDelay(1000).maxMessagesPerPoll(1)))
            .filter(onlyT4F2())
            .handle(fileMessageToJobRequest)
            .handle(jobLaunchingGateway)
            .log(LoggingHandler.Level.WARN, "headers.id + ': ' + payload").get();
}

@Bean
public GenericSelector<File> onlyT4F2() {
    System.out.println("@@@@@@@Inside GenericSelector of XXX");
    return new GenericSelector<File>() {
        @Override
        public boolean accept(File source) {
          return source.getName().contains("XXX");
        }
    };
}

当前行为--当轮询器在给定位置检测到一个或多个文件时,配置的批处理作业将触发多次。如果文件为4,则批处理作业将触发4次。

预期的行为-文件轮询后,对于任何数量的文件,批处理作业应仅执行一次。由于批处理作业一次要处理多个文件,因此不需要多次执行。

让我知道您是否还需要其他信息。请优先提供帮助

2 个答案:

答案 0 :(得分:0)

您可以在入站通道适配器上使用自定义FileListFilter,该适配器仅返回一个文件。

.filter(myFilterThatOnlyReturnsOneFile)

编辑

public class OnlyOneFileListFilter implements FileListFilter<File> {

    @Override
    public List<File> filterFiles(File[] files) {
        return Collections.singletonList(files[0]);
    }

}
        return IntegrationFlows
                .from(Files.inboundAdapter(new File("C:\\apps_data\\recv"))
                            .filter(new OnlyOneFileListFilter()),
                        c -> c.poller(Pollers.fixedDelay(1000).maxMessagesPerPoll(1)))
                ...

答案 1 :(得分:0)

@Gary Russell-问题已解决,仅按以下方式使用GenericSelector。谢谢你的帮助。在首次运行时触发批处理作业后,它会处理所有当前文件并将其移至其他文件夹,因此我添加了file.exists(),并且按我的期望工作良好。但是我观察到,即使在提供了预期的文件后1个小时甚至有时也没有进行轮询,还是需要您的帮助/建议。

@Bean
public GenericSelector<File> triggerJobOnlyOnce() {
    return new GenericSelector<File>() {
        @Override
        public boolean accept(File source) {
                if(source.getName().contains("XXX") && source.exists())
                    return true;
            return flag;
        }
    };
}