RequestHandlerRetryAdvice no se puede hacer que funcione con Ftp.outboundGateway en Spring Integration

Mi situación es similar a la descrita enesta pregunta SO. La diferencia es que no uso unaWebFlux.outboundGateway pero unFtp.outboundGateway en el que llamo unAbstractRemoteFileOutboundGateway.Command.GETcommand, el problema común es que no puedo obtener la @ definiRequestHandlerRetryAdvice para ser utilizado

La configuración se ve así (despojada a las partes relevantes):

@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;
   }
}

El controlador está principalmente allí para fines de prueba, en la implementación real hay un sondeo. MiFtpProperties mantenga una lista de servidores porque en la implementación real, uso unDelegatingSessionFactory para elegir una instancia basada en algunos parámetros.

De acuerdo a Comentario de Gary Russell, Espero que se vuelva a intentar una descarga fallida. Pero si interrumpo una descarga del lado del servidor (al emitir "Kick user" en una instancia de FileZilla), solo obtengo un seguimiento inmediato de la pila y no vuelvo a intentarlo:

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

También necesito subir archivos, para lo cual uso unFtp.outboundAdapter. En este caso y con el mismoRetryTemplate, si interrumpo una carga del lado del servidor, Spring Integration realiza dos intentos más con un retraso de 5 segundos cada uno, y solo luego registrajava.net.SocketException: Connection reset, todo como se esperaba.

ntenté depurar un poco y noté eso justo antes del primer intento de subir a través deFtp.outboundAdapter, un punto de quiebre enRequestHandlerRetryAdvice.doInvoke() es golpeado. Pero al descargar a través deFtp.outboundGateway, ese punto de quiebre esNunc golpear

Hay un problema con mi configuración, ¿podría alguien obtener elRequestHandlerRetryAdvice trabajar conFtp.outboundGateway/AbstractRemoteFileOutboundGateway.Command.GET?

Respuestas a la pregunta(1)

Su respuesta a la pregunta