[英]How to set up ExpressionEvaluatingRequestHandlerAdvice to stop task from being cancelled
我有一个场景,我不确定我是否在 Integration Flow 中设置正确。 需要的是:
SftpPersistentAcceptOnceFileListFilter
存储该信息对于最后一点,我在另一个答案中发现我可以尝试ExpressionEvaluatingRequestHandlerAdvice
。 我提出了以下配置,但是添加Advice
完全破坏了流程(没有消息流过)
ExpressionEvaluatingRequestHandlerAdvice advice = new ExpressionEvaluatingRequestHandlerAdvice();
advice.setSuccessChannel(out);
advice.setFailureChannel(err);
advice.setTrapException(true);
IntegrationFlow integrationFlow = IntegrationFlows
.from(Sftp.inboundAdapter(cachingSessionFactory)
.remoteDirectory("sftpSource")
.deleteRemoteFiles(false)
.preserveTimestamp(true)
.localDirectory(getTargetLocalDirectory()), e -> e.id("sftpInboundAdapter")
.poller(Pollers.fixedDelay(100)
.maxMessagesPerPoll(3)
.advice(advice)))
.channel(out)
.get();
跳过已归档文件传输的要求来自现实世界的场景,我们的 SFTP 服务器拒绝传输空文件。 为了模拟这一点,我在SessionFactory
中添加了间谍:
CachingSessionFactory<ChannelSftp.LsEntry> cachingSessionFactory = Mockito.spy(sessionFactory());
CachingSessionFactory.CachedSession session = (CachingSessionFactory.CachedSession) Mockito.spy(cachingSessionFactory.getSession());
doReturn(session).when(cachingSessionFactory).getSession();
doThrow(new RuntimeException("test exception")).when(session).read(contains("sftpSource2.txt"), any(OutputStream.class));
和测试代码:
Message<?> message = out.receive(1000);
assertThat(message).isNotNull();
Object payload = message.getPayload();
assertThat(payload).isInstanceOf(File.class);
File file = (File) payload;
assertThat(file.getName()).isEqualTo(" sftpSource1.txt");
assertThat(file.getAbsolutePath()).contains("localTarget");
message = out.receive(1000);
assertThat(message).isNull();
message = err.receive(1000);
System.out.println("error was:" + message.getPayload());
message = out.receive(1000);
assertThat(message).isNotNull();
file = (File) message.getPayload();
assertThat(file.getName()).isIn("sftpSource3.txt");
assertThat(file.getAbsolutePath()).contains("localTarget");
我感到困惑的是 - 当我向Poller
添加advice
时,我应该从Poller
中删除.errorChannel(err)
吗? 但是,如果建议是处理消息结束的地方,我不应该也删除integrationFlow
上的.channel(out)
吗? 没有它,IntegrationFlow 不会构建,并出现错误outputChannel is required
。
我的第二个担心是——如果advice.setTrapException(true);
这是否意味着SftpPersistentAcceptOnceFileListFilter
会将文件标记为已成功处理? (过滤器不在示例代码中,但我会在实际代码中需要它)。
ExpressionEvaluatingRequestHandlerAdvice
适用于消费者端点,而不是源轮询通道适配器。 因此,您无法使用该建议处理来自轮询器的错误。
实际上,您不能仅使用SourcePollingChannelAdapter
来拥有IntegrationFlow
- 您需要以任何一种方式添加该channel(out)
。
您当前的配置不清楚您将这些文件传输到哪里。 因此,您可能正在谈论处理这些文件的错误,在那里ExpressionEvaluatingRequestHandlerAdvice
在那里有意义。 这样,您所有的远程文件实际上都会被传输到本地目录,并在SftpPersistentAcceptOnceFileListFilter
中标记为已监视。 只是因为您不会将异常从处理程序抛回给 SFTP 入站通道适配器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.