繁体   English   中英

如何设置 ExpressionEvaluatingRequestHandlerAdvice 以阻止任务被取消

[英]How to set up ExpressionEvaluatingRequestHandlerAdvice to stop task from being cancelled

我有一个场景,我不确定我是否在 Integration Flow 中设置正确。 需要的是:

  • 轮询文件的 SFTP 位置
  • 传输所有新的/已更改的信息并使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM