这个问题更像是一个设计问题,而不是一个真正的问题。给出以下基本流程:
@Bean
public DirectChannel getFileToSftpChannel() {
return new DirectChannel();
}
@Bean
public IntegrationFlow sftpOutboundFlow() {
return IntegrationFlows.from(getFileToSftpChannel())
.handle(Sftp.outboundAdapter(this.sftpSessionFactory)
.useTemporaryFileName(false)
.remoteDirectory("test")).get();
}
@Bean
public IntegrationFlow filePollingInboundFlow() {
return from(s -> s.file(new File("path")).patternFilter("*.ext"),
e -> e.poller(fixedDelay(60, SECONDS).channel(getFileToSftpChannel()).get();
}
有一个入站文件轮询流,它通过DirectChannel将消息发布到上传文件的出站SFTP流。 整个流程完成后,我想执行“成功”操作:将原始文件(本地)移动到存档文件夹。 使用DirectChannel,我知道上传将发生在与文件轮询相同的线程中。 换句话说,文件轮询器阻止直到上载完成(或者返回错误消息,然后将其推送到错误通道)。 知道了这一点,我想在入站流程中放置“成功”动作(=移动原始文件)。我已经知道并且不想使用的事情:
我尝试的另一件事是在入站流程中添加“句柄”。但是,我了解到入站流没有真正的'回复',句柄在发送消息之前执行,所以这不起作用,因为必须在成功处理消息后执行移动。
简而言之:在消费者(=出站流)通过DirectChannel成功处理消息后,执行生产者(=入站流)提供的操作的标准方法是什么?
答案 0 :(得分:0)
嗯,做类似事情的标准方法是transaction
,这就是为什么我们前一段时间介绍PseudoTransactionManager
和类似任务的XML示例看起来像:
<int-file:inbound-channel-adapter id="realTx" channel="txInput" auto-startup="false"
directory="${java.io.tmpdir}/si-test2">
<int:poller fixed-rate="500">
<int:transactional synchronization-factory="syncFactory"/>
</int:poller>
</int-file:inbound-channel-adapter>
<bean id="transactionManager" class="org.springframework.integration.transaction.PseudoTransactionManager"/>
<int:transaction-synchronization-factory id="syncFactory">
<int:after-commit expression="payload.delete()"/>
</int:transaction-synchronization-factory>
如您所见,我们在交易结束时删除了文件,这是在您转移到SFTP之后造成的。
我说这是与制片人联系的最佳方式。
另一种方法是在getFileToSftpChannel()
之前引入另一个频道,并应用最终将被调用的ChannelInterceptor.afterSendCompletion
,同样的单线程原因。使用这种方法,您应该bridge
所有生产者使用特定DirectChannel
s到SFTP适配器的单getFileToSftpChannel()
。
所以,它取决于你选择什么。从架构的角度来看,你有很好的论据可以将逻辑划分为责任层,但正如你所看到的,没有那么多的选择......
欢迎任何其他想法!
答案 1 :(得分:0)
您可以尝试以下内容
@Bean
public DirectChannel getFileToSftpChannel() {
DirectChannel directChannel = new DirectChannel();
directChannel.addInterceptor(new ChannelInterceptorAdapter() {
@Override
public void afterSendCompletion(final Message<?> message,
final MessageChannel channel, final boolean sent, final Exception ex) {
if (ex == null) {
new Archiver().archive((File) message.getPayload());
}
}
});
return directChannel;
}