在 Spring Integration 中,RequestHandlerRetryAdvice 无法与 Ftp.outboundGateway 一起使用

2023-12-13

我的情况与描述的类似这个问题。区别在于我不使用WebFlux.outboundGateway but an Ftp.outboundGateway我称之为AbstractRemoteFileOutboundGateway.Command.GET命令,常见的问题是我无法获得定义的RequestHandlerRetryAdvice要使用的。

配置如下所示(精简到相关部分):

@RestController
@RequestMapping( value = "/somepath" )
public class DownloadController
{
   private DownloadGateway downloadGateway;

   public DownloadController( DownloadGateway downloadGateway )
   {
      this.downloadGateway = downloadGateway;
   }

   @PostMapping( "/downloads" )
   public void download( @RequestParam( "filename" ) String filename )
   {
      Map<String, Object> headers = new HashMap<>();

      downloadGateway.triggerDownload( filename, headers );
   }
}    
@MessagingGateway
public interface DownloadGateway
{
   @Gateway( requestChannel = "downloadFiles.input" )
   void triggerDownload( Object value, Map<String, Object> headers );
}
@Configuration
@EnableIntegration
public class FtpDefinition
{
   private FtpProperties ftpProperties;

   public FtpDefinition( FtpProperties ftpProperties )
   {
      this.ftpProperties = ftpProperties;
   }

   @Bean
   public DirectChannel gatewayDownloadsOutputChannel()
   {
      return new DirectChannel();
   }

   @Bean
   public IntegrationFlow downloadFiles( RemoteFileOutboundGatewaySpec<FTPFile, FtpOutboundGatewaySpec> getRemoteFile )
   {
      return f -> f.handle( getRemoteFile, getRetryAdvice() )
                   .channel( "gatewayDownloadsOutputChannel" );
   }

   private Consumer<GenericEndpointSpec<AbstractRemoteFileOutboundGateway<FTPFile>>> getRetryAdvice()
   {
      return e -> e.advice( ( (Supplier<RequestHandlerRetryAdvice>) () -> {
         RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
         advice.setRetryTemplate( getRetryTemplate() );
         return advice;
      } ).get() );
   }

   private RetryTemplate getRetryTemplate()
   {
      RetryTemplate result = new RetryTemplate();

      FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
      backOffPolicy.setBackOffPeriod( 5000 );

      result.setBackOffPolicy( backOffPolicy );
      return result;
   }

   @Bean
   public RemoteFileOutboundGatewaySpec<FTPFile, FtpOutboundGatewaySpec> getRemoteFile( SessionFactory sessionFactory )
   {
      return 
         Ftp.outboundGateway( sessionFactory,
                              AbstractRemoteFileOutboundGateway.Command.GET,
                              "payload" )
            .fileExistsMode( FileExistsMode.REPLACE )
            .localDirectoryExpression( "'" + ftpProperties.getLocalDir() + "'" )
            .autoCreateLocalDirectory( true );
   }

   @Bean
   public SessionFactory<FTPFile> ftpSessionFactory()
   {
      DefaultFtpSessionFactory sessionFactory = new DefaultFtpSessionFactory();
      sessionFactory.setHost( ftpProperties.getServers().get( 0 ).getHost() );
      sessionFactory.setPort( ftpProperties.getServers().get( 0 ).getPort() );
      sessionFactory.setUsername( ftpProperties.getServers().get( 0 ).getUser() );
      sessionFactory.setPassword( ftpProperties.getServers().get( 0 ).getPassword() );
      return sessionFactory;
   }
}
@SpringBootApplication
@EnableIntegration
@IntegrationComponentScan
public class FtpTestApplication {

    public static void main(String[] args) {
        SpringApplication.run( FtpTestApplication.class, args );
    }
}
@Configuration
@PropertySource( "classpath:ftp.properties" )
@ConfigurationProperties( prefix = "ftp" )
@Data
public class FtpProperties
{
   @NotNull
   private String localDir;

   @NotNull
   private List<Server> servers;

   @Data
   public static class Server
   {
      @NotNull
      private String host;

      @NotNull
      private int port;

      @NotNull
      private String user;

      @NotNull
      private String password;
   }
}

控制器主要只是用于测试目的,在实际实现中有一个轮询器。我的FtpProperties保存服务器列表,因为在实际实现中,我使用DelegatingSessionFactory根据一些参数选择一个实例。

根据加里·拉塞尔的评论,我希望重试失败的下载。但是,如果我中断下载服务器端(通过在 FileZilla 实例中发出“Kick user”),我只会立即获得堆栈跟踪,而无需重试:

org.apache.commons.net.ftp.FTPConnectionClosedException: FTP response 421 received.  Server closed connection.
[...]

我还需要上传文件,为此我使用Ftp.outboundAdapter。在这种情况下并且具有相同的RetryTemplate,如果我中断上传服务器端,Spring Integration 会再执行两次尝试,每次延迟 5 秒,然后才记录java.net.SocketException: Connection reset,一切如预期。

我尝试进行一些调试,并注意到在第一次尝试通过Ftp.outboundAdapter,断点RequestHandlerRetryAdvice.doInvoke()被击中。但通过下载时Ftp.outboundGateway,该断点是never hit.

我的配置有问题吗,谁能帮我解决一下RequestHandlerRetryAdvice跟...共事Ftp.outboundGateway/AbstractRemoteFileOutboundGateway.Command.GET?


抱歉耽搁了;本周我们在 SpringOne 平台。

问题是由于网关规范是一个 bean - 网关最终在应用建议之前被初始化。

我像这样改变了你的代码......

@Bean
public IntegrationFlow downloadFiles(SessionFactory<FTPFile> sessionFactory) {
    return f -> f.handle(getRemoteFile(sessionFactory), getRetryAdvice())
            .channel("gatewayDownloadsOutputChannel");
}

...

private RemoteFileOutboundGatewaySpec<FTPFile, FtpOutboundGatewaySpec> getRemoteFile(SessionFactory<FTPFile> sessionFactory) {
    return Ftp.outboundGateway(sessionFactory,
            AbstractRemoteFileOutboundGateway.Command.GET,
            "payload")
            .fileExistsMode(FileExistsMode.REPLACE)
            .localDirectoryExpression("'/tmp'")
            .autoCreateLocalDirectory(true);
}

...它起作用了。

通常最好不要直接处理规范,而只是将它们内联到流程定义中......

@Bean
public IntegrationFlow downloadFiles(SessionFactory<FTPFile> sessionFactory) {
    return f -> f.handle(Ftp.outboundGateway(sessionFactory,
            AbstractRemoteFileOutboundGateway.Command.GET,
            "payload")
            .fileExistsMode(FileExistsMode.REPLACE)
            .localDirectoryExpression("'/tmp'")
            .autoCreateLocalDirectory(true), getRetryAdvice())
        .channel("gatewayDownloadsOutputChannel");
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Spring Integration 中,RequestHandlerRetryAdvice 无法与 Ftp.outboundGateway 一起使用 的相关文章

随机推荐

  • 使用安全登录进行 PHP 网站抓取

    我正在尝试减少我的一位经销商的每种产品的库存数量 他们不知道如何导出这些数据 所以我想知道是否有人可以帮助我指明如何使用 PHP 抓取必须登录才能获取数据的网站的正确方向 它不是一个使用 SSL 的安全站点 感谢您的任何提示 克里斯 爱德华
  • C 中是否有 strtoull() 函数的替代方案?

    我需要转换char to unsigned long long int有一个函数叫做strtoull in the C标准库 但需要很多时间 我需要在之间快速转换char to unsigned long long int 如何编写比标准转
  • 日期列中的 Kendo 网格格式时间问题[重复]

    这个问题在这里已经有答案了 我有一个剑道网格 它有一个日期列 我想在那里显示日期和时间 我在列定义中使用以下格式 format 0 dd MMM yyyy hh mm ss tt 在模态中我使用了日期类型Updated Date type
  • UnsupportedAudioFileException 的解决方法?

    我正处于用 Java 编写小型音乐 节奏游戏的早期阶段 通过 Slick 框架 该框架又使用 OpenAL 但这可能与这里无关 游戏需要读取 并播放 多个 WAV 格式的声音文件 但某些文件抛出 javax sound sampled Un
  • 在 cookie 中存储数组

    我需要在 cookie 中存储一些数组数据 我一直在研究最好的方法来做到这一点 很多人似乎说使用serialize是要走的路 但在这个线程中 PHP如何字符串化数组并存储在cookie中 有人建议不要使用它 因为 序列化将调用序列化类的构造
  • 在函数中使用 dplyr group_by

    我试图在本地函数中使用 dplyr 的 group by 例如 testFunction lt function df x df gt group by x gt summarize mean Petal Width mean Petal
  • 使用 Bootstrap Datepicker 时如何获取选定的日期值?

    使用 jquery 和 Bootstrap Datepicker 如何获取我使用 Bootstrap Datepicker 选择的新日期值 仅供参考 我正在使用 Rails 3 和 Coffescript 我使用以下方法设置日期选择器
  • 具有多对多关系的 MVC4 控制器

    我有两个实体 Arena 和 Regulator 它们之间具有多对多的关系 我已经实现了 EF 代码首先接受的解决方案 见下文 我现在一直致力于实现控制器视图 以便当用户创建调节器时 他可以选择一个或多个竞技场 可能使用复选框或多选列表 并
  • 通过 xpath Selenium java 选择具有动态生成的 id 的 WebElements

    我需要在下拉窗口中选择一个元素 每次我在正在测试的网站中打开下拉窗口时 网站都会随机生成该下拉窗口的 ID 下拉窗口的先前实例可见 使用 Firebug 但不可选择 有一个静态路径 但仅当我使用 ChromeDriver 测试它时才有效 而
  • 用于任意对象的 python 哈希函数的替代方案

    在python2 7中 我成功使用hash 将对象放入持久存储在磁盘上的存储桶中 样机代码如下所示 class PersistentDict object def setitem self key value bucket index ha
  • 基本 Docker 容器报告运行级别未知

    当我像这样运行一个基本的 Docker 容器 从 Google Cloud Shell 中 时 docker pull debian docker run i t debian wheezy bin bash 然后输入runlevel在运行
  • 查找给定矩阵的子矩阵

    我正在尝试编写一种算法来在给定的子矩阵中查找子矩阵 为了解决这个问题我编写了以下代码 public class SubMatTry param args public static void main String args TODO Au
  • 添加到 Google 日历呈现链接不显示用户的当地时间

    我可以使用此谷歌日历链接创建一个活动 但我认为 UTC 时间即将到来 比我想要的活动时间提前了 5 30 小时 例子 这个链接将创建一个活动 但显示时间为中午 12 30 至下午 4 点 该活动预计在上午 6 30 至上午 10 点进行 根
  • 是否可以使用单个 SQL 语句将记录从一个表移动到另一个表?

    我需要一个查询将记录从一个表移动到另一个表而不使用多个语句 不可以 您不能在一条 SQL 语句中移动记录 你必须使用一个INSERT随后是一个DELETE陈述 您应该将这些语句包装成交易 以确保复制操作保持原子性 START TRANSAC
  • 使用 oauth2 和 Google API 时无法识别的参数

    我在一些脚本中使用 Google API 服务 但遇到了一些问题 这个错误有点奇怪 但我们开始了 我有一个列出我的 Google 云端硬盘文件的脚本 from apiclient import discovery from httplib2
  • 如何获取成员变量的注解?

    我想知道一个类的一些成员变量的注释 我使用BeanInfo beanInfo Introspector getBeanInfo User class 反思一个类 并使用BeanInfo getPropertyDescriptors 查找特定
  • 如何从一个元组到一个元组引用元组中的元素?

    我有一个 C 11 元组 我想要一个元组std reference wrappers 到元组的相同元素 有没有简单的方法可以做到这一点 映射一个元组很容易一组索引 e g include
  • 在代码中处理语音命令以执行命令的智能方法

    我想知道是否可以寻求更好的方法来处理和处理命令 而不是使用可能变得非常长且非常乏味的 Switch Case 或 IF 布尔检查 E G if settings getName Command Speak I am here if Get
  • 如何用 Python 可视化回归树

    我正在寻找可视化回归使用 scikit learn 中的任何集成方法构建的树 梯度增强回归器 随机森林回归器 装袋回归器 我看过这个问题很接近 并且这个问题它处理分类树 但这些问题需要 树 方法 而该方法不适用于 SKLearn 中的回归模
  • 在 Spring Integration 中,RequestHandlerRetryAdvice 无法与 Ftp.outboundGateway 一起使用

    我的情况与描述的类似这个问题 区别在于我不使用WebFlux outboundGateway but an Ftp outboundGateway我称之为AbstractRemoteFileOutboundGateway Command G