Spring boot Spring批处理作业只应在Spring集成文件轮询器轮询文件后执行一次

Spring boot Spring批处理作业只应在Spring集成文件轮询器轮询文件后执行一次,spring-boot,spring-integration,spring-batch,spring-integration-dsl,poller,Spring Boot,Spring Integration,Spring Batch,Spring Integration Dsl,Poller,我正在尝试轮询系统文件夹中的文件,其中可能有一个或多个文件,对于这些文件,我必须仅触发一次批处理作业,而不是触发次数等于文件夹中的文件数。在我的例子中,我的批处理一次处理多个文件,我只希望轮询器只向批处理发送一次信号以开始它的工作 尝试了poller.maxMessagesPerPoll(1)等,但有所不同。。我面临的问题是,触发的批处理作业数等于轮询器在轮询文件夹中获得的文件数。我只想执行一次批处理 @Bean public FileMessageToJobRequest fileMessag

我正在尝试轮询系统文件夹中的文件,其中可能有一个或多个文件,对于这些文件,我必须仅触发一次批处理作业,而不是触发次数等于文件夹中的文件数。在我的例子中,我的批处理一次处理多个文件,我只希望轮询器只向批处理发送一次信号以开始它的工作

尝试了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");
        }
    };
}
@Bean
公共文件MessageToJobRequest文件MessageToJobRequest(){
FileMessageToJobRequest FileMessageToJobRequest=新建FileMessageToJobRequest();
fileMessageToJobRequest.setJob(fileMessageBatchJob);
返回fileMessageToJobRequest;
}
@豆子
public JobLaunchingGateway JobLaunchingGateway(){
simplejoblancher simplejoblancher=新的simplejoblancher();
setJobRepository(jobRepository);
setTaskExecutor(新的SyncTaskExecutor());
JobLaunchingGateway JobLaunchingGateway=新的JobLaunchingGateway(SimpleZoblancher);
返回作业启动网关;
}
@豆子
公共集成流集成流(JobLaunchingGateway JobLaunchingGateway){
System.out.println(“&&&&&&&&&&&&&&&&&&&&&&内部集成流!!!!”);
返回积分流
.from(Files.inboundAdapter(新文件(“C:\\apps\u data\\recv”)),
c->c.poller(Pollers.fixedDelay(1000.maxMessagesPerPoll(1)))
.filter(仅限YT4F2())
.handle(fileMessageToJobRequest)
.句柄(jobLaunchingGateway)
.log(LoggingHandler.Level.WARN,“headers.id+”:“+payload”).get();
}
@豆子
仅限公共GenericSelector YT4F2(){
System.out.println(“@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@;
返回新的GenericSelector(){
@凌驾
公共布尔接受(文件源){
返回source.getName()包含(“XXX”);
}
};
}
当前行为-当轮询器检测到给定位置上的文件时,配置的批处理作业会触发多次。如果文件为4,则批处理作业将触发4次

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


如果您需要我这边的任何其他信息,请告诉我。请提供所需的优先级帮助

您可以在只返回一个文件的入站通道适配器上使用自定义的
文件列表过滤器

.filter(myFilterThatOnlyReturnsOneFile)
编辑

public类OnlyOneFileListFilter实现FileListFilter{
@凌驾
公共列表筛选器文件(文件[]文件){
返回集合.singletonList(文件[0]);
}
}

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

.filter(myFilterThatOnlyReturnsOneFile)
编辑

public类OnlyOneFileListFilter实现FileListFilter{
@凌驾
公共列表筛选器文件(文件[]文件){
返回集合.singletonList(文件[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;
        }
    };
}
@Bean
public GenericSelector triggerJobOnlyOnce(){
返回新的GenericSelector(){
@凌驾
公共布尔接受(文件源){
if(source.getName()包含(“XXX”)&&source.exists()
返回true;
返回标志;
}
};
}

@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;
        }
    };
}
@Bean
public GenericSelector triggerJobOnlyOnce(){
返回新的GenericSelector(){
@凌驾
公共布尔接受(文件源){
if(source.getName()包含(“XXX”)&&source.exists()
返回true;
返回标志;
}
};
}

Spring batch Job从轮询位置显式读取所有文件,因此我在这里只是使用轮询器查看文件的特定格式是否出现,然后触发批处理Job..Spring batch Job从轮询位置显式读取所有文件,因此我在这里只是使用轮询器查看文件的特定格式是否出现接下来触发批处理作业..你能给我一段代码吗。。我理解你的逻辑,但对如何融入集成流感到困惑..Russel-感谢你的解决方案,我尝试了,但没有达到异常,看起来筛选器方法接受布尔值,请您提供帮助,原因是:java.lang.IllegalArgumentException:需要布尔结果:org.springframework.util.Assert.assignableCheckFailed(Assert.java:655)org.springframework.util.Assert.isAssignable(Assert.java:586)上的class java.util.Collections$SingletonList在org.springframework.integration.filter.MessageFilter.doHandlerRequestMessage(MessageFilter.java:165)中,您已经将
.filter()
应用于主流,而不是我在an中显示的适配器