发布订阅流程后,从入站适配器移动文件

时间:2019-05-08 20:12:10

标签: spring-integration spring-integration-dsl

我正在尝试实现以下流程: 1)从入站适配器读取文件 2)使用具有应用顺序的发布-订阅通道将它们发送到不同的流 3)所有订户流准备就绪后,文件被移动

这是主要流程

return IntegrationFlows
                .from(Files.inboundAdapter(inboundOutDirectory)
                           .regexFilter(pattern)
                           .useWatchService(true)
                           .watchEvents(FileReadingMessageSource.WatchEventType.CREATE),
                        e -> e.poller(Pollers.fixedDelay(period)
                                             .taskExecutor(Executors.newFixedThreadPool(poolSize))
                                             .maxMessagesPerPoll(maxMessagesPerPoll)))
                .publishSubscribeChannel(s -> s
                        .applySequence(true)
                        .subscribe(f -> f
                                .transform(Files.toStringTransformer())
                                .<String>handle((p, h) -> {
                                       return "something"
                                    }
                                })                                
                                .channel("consolidateFlow.input"))
                        .subscribe(f -> f
                                .transform(Files.toStringTransformer())
                                .handle(Http.outboundGateway(testUri)
                                            .httpMethod(HttpMethod.GET)
                                            .uriVariable("text", "payload")                                            .expectedResponseType(String.class))
                                .<String>handle((p, h) -> {
                                    return "something";
                                })
                                .channel("consolidateFlow.input")))
                .get();

聚合:

public IntegrationFlow consolidateFlow()
return flow -> flow
                .aggregate()
                .<List<String>>handle((p, h) -> "something").log()
    }
}

发布-订阅后在主流中使用以下代码

.handle(Files.outboundGateway(this.inboundProcessedDirectory).deleteSourceFiles(true))

最终

Caused by: org.springframework.messaging.core.DestinationResolutionException: no output-channel or replyChannel header available

如果我这样做,将根本无法达到合并/聚合流程。

.handle(Files.outboundAdapter(this.inboundProcessedDirectory))

有什么办法可以解决吗?目前,我正在聚合后通过从标题中读取原始文件名来移动文件,但这似乎不是正确的解决方案。 我也在考虑使用成功逻辑将规范/建议应用于入站适配器以移动文件,但不确定是否正确的方法。

EDIT1 正如Artem所建议的,我向发布-订阅添加了另一个订阅者,如下所示:

...
.channel("consolidateNlpFlow.input"))
                        .subscribe(f -> f
                                .handle(Files.outboundAdapter(this.inboundProcessedDirectory).deleteSourceFiles(true))
...

文件已正确移动,但未完全执行consolidateFlow。任何想法? 我还尝试过将频道添加到新流程.channel("consolidateNlpFlow.input")中,但是并没有改变行为。

1 个答案:

答案 0 :(得分:2)

您的问题是consolidateFlow无法将结果返回到主流中。仅仅因为有网关之类的东西。您在此处进行了明确的.channel("consolidateFlow.input")的处理,这意味着不会再回头了。 那是您到目前为止遇到的问题。

关于可能的解决方案。

根据您的配置,publishSubscribeChannel中的两个订户都是在同一线程上一对一执行的。因此,您将很容易用Files.outboundAdapter()deleteSourceFiles(true)添加一个订户。在已有的订阅者之后,这个名字将被调用。