A continuación se muestra la configuración que estoy usando
@Autowired private SftpRemoteFileTemplate outboundTemplate; @Autowired private SftpConfig config; @Bean @ServiceActivator(inputChannel = "sftpOutputGenericChannel") public MessageHandler simplehandler() { SftpMessageHandler handler = new SftpMessageHandler(outboundTemplate, FileExistsMode.APPEND); handler.setRemoteDirectoryExpression(new LiteralExpression(config.getDirectory())); handler.setFileNameGenerator((Message<?> message) -> ((String) message.getHeaders().get(KEY))); handler.setUseTemporaryFileName(false); return handler; }Creé Sessionfactory, CachingSessionfactory y SftpRemoteFileTemplte en una clase de configuración separada y se están instanciando correctamente, a continuación se encuentran los registros de lo mismo.
2020-11-27 01:15:17.742 [main] osbfsDefaultListableBeanFactory : Creating shared instance of singleton bean 'cachingSessionFactory' 2020-11-27 01:15:17.744 [main] osbfsDefaultListableBeanFactory : Creating shared instance of singleton bean 'sftpSessionFactory' 2020-11-27 01:15:17.778 [main] osbfsDefaultListableBeanFactory : Autowiring by type from bean name 'cachingSessionFactory' via factory method to bean named 'sftpSessionFactory' 2020-11-27 01:15:17.783 [main] osintegration.util.SimplePool : Target pool size changed by -2147483637, now 10 2020-11-27 01:15:54.434 [main] osbfsDefaultListableBeanFactory : Creating shared instance of singleton bean 'outboundTemplate' 2020-11-27 01:15:54.435 [main] osbfsDefaultListableBeanFactory : Autowiring by type from bean name 'outboundTemplate' via factory method to bean named 'cachingSessionFactory'Cuando ejecuto este código, los registros de Spring DEBUG muestran que el archivo se envió al servidor con éxito, pero en realidad el archivo no se carga en el servidor.
pero si cambio la implementación de MessageHandler a,
SftpMessageHandler handler = new SftpMessageHandler(new SftpRemoteFileTemplate(cachingSessionFactory), FileExistsMode.APPEND);comienza a funcionar y el archivo se carga en el servidor, ¿no está seguro de por qué sucede esto?
Una observación más cuando uso @Autowired SftpRemoteFileTemplate con handler.setRemoteDirectoryExpressionString("headers['remote_directory']") funciona perfectamente bien.
Quiero entender cómo funciona SftpRemoteTemplate aquí y cuál es la mejor práctica sugerida.
Nota: SpringBoot v2.4.0 Integración de Spring: 5.4.1, se enfrentó al problema similar con el arranque v2.2.6.RELEASE
Probablemente use el mismo SftpRemoteFileTemplate en otros lugares y también lo modifique allí para otras opciones. De hecho, algo como handler.setRemoteDirectoryExpression() hace una delegación y, por lo tanto, una mutación a la SftpRemoteFileTemplate proporcionada:
/** * Specify a remote directory path SpEL expression. * @param remoteDirectoryExpression the remote directory expression * @see RemoteFileTemplate#setRemoteDirectoryExpression(Expression) */ public void setRemoteDirectoryExpression(Expression remoteDirectoryExpression) { this.remoteFileTemplate.setRemoteDirectoryExpression(remoteDirectoryExpression); }Entonces, cuando otro lugar hace una modificación similar, termina con una condición de carrera y su archivo puede transferirse a un lugar diferente.
La mejor práctica es tratar un RemoteFileTemplate como un prototype y tener una instancia por adaptador de canal. O simplemente use otro ctor, solo un basado en SessionFactory :
/** * @param sessionFactory the session factory. * @see FileTransferringMessageHandler#FileTransferringMessageHandler * (SessionFactory) */ public SftpMessageHandler(SessionFactory<LsEntry> sessionFactory) Probablemente necesitemos revisar la lógica en FileTransferringMessageHandler para rechazar una mutación para RemoteFileTemplate proporcionado externamente. Siéntase libre de plantear un problema de GH y veremos qué podemos hacer en la próxima versión principal, donde podemos hacer algunos cambios importantes.