SftpRemoteFileTemplate не работает с RemoteDirectoryExpression при @Autowired

#java #spring #spring-boot #spring-integration #spring-integration-sftp

#java #весна #весенняя загрузка #spring-интеграция #spring-интеграция-sftp

Вопрос:

Ниже приведена конфигурация, которую я использую

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

Я создал Sessionfactory, CachingSessionfactory и SftpRemoteFileTemplte в отдельном классе конфигурации, и они создаются правильно, ниже приведены журналы для того же.

 2020-11-27 01:15:17.742 [main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'cachingSessionFactory'
2020-11-27 01:15:17.744 [main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'sftpSessionFactory'
2020-11-27 01:15:17.778 [main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'cachingSessionFactory' via factory method to bean named 'sftpSessionFactory'
2020-11-27 01:15:17.783 [main] o.s.integration.util.SimplePool          : Target pool size changed by -2147483637, now 10
2020-11-27 01:15:54.434 [main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'outboundTemplate'
2020-11-27 01:15:54.435 [main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'outboundTemplate' via factory method to bean named 'cachingSessionFactory'
 

Когда я выполняю этот код, журналы отладки Spring показывают, что файл успешно отправлен на сервер, но на самом деле файл не загружается на сервер.

но если я изменю реализацию MessageHandler на,

 SftpMessageHandler handler = new SftpMessageHandler(new SftpRemoteFileTemplate(cachingSessionFactory), FileExistsMode.APPEND);
 

он начинает работать, и файл фактически загружается на сервер, не уверен, почему это происходит?

Еще одно наблюдение, когда я использую @Autowired SftpRemoteFileTemplate с handler.setRemoteDirectoryExpressionString("headers['remote_directory']") ним, работает отлично.

Я хочу понять, как здесь работает SftpRemoteTemplate и какова наилучшая предлагаемая практика?

Примечание: SpringBoot v2.4.0 Spring integration: 5.4.1 столкнулся с аналогичной проблемой при загрузке v2.2.6.RELEASE

Ответ №1:

Вероятно, вы используете то же SftpRemoteFileTemplate самое в других местах, и вы также изменяете его там для других параметров. На самом деле что-то вроде handler.setRemoteDirectoryExpression() выполняет делегирование и, следовательно, мутацию предоставленного SftpRemoteFileTemplate :

 /**
 * 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);
}
 

Таким образом, когда в другом месте выполняется аналогичная модификация, вы получаете состояние гонки, и ваш файл может быть перенесен в другое место.

Лучше всего рассматривать a RemoteFileTemplate как a prototype и иметь экземпляр для каждого адаптера канала. Или просто используйте другой ctor — only на SessionFactory основе:

 /**
 * @param sessionFactory the session factory.
 * @see FileTransferringMessageHandler#FileTransferringMessageHandler
 * (SessionFactory)
 */
public SftpMessageHandler(SessionFactory<LsEntry> sessionFactory)
 

Вероятно, нам нужно пересмотреть логику в FileTransferringMessageHandler , чтобы отклонить мутацию для предоставленной извне RemoteFileTemplate . Не стесняйтесь поднимать проблему GH, и мы посмотрим, что мы можем сделать в следующей основной версии, где мы можем внести некоторые критические изменения.

Комментарии:

1. Спасибо, Артем, теперь я буду придерживаться только нового SftpRemoteFileTemplate. Я пытался использовать область ПРОТОТИПА и множество других параметров, а также устанавливать удаленный каталог при инициализации SftpRemoteFileTemplate, а не вызывать метод обработчика и т. Д., Но Результаты те же.. Я могу использовать другой ctor, который использует только SessionFactory, но не уверен, что это даст мне возможность записать файл в режиме добавления? Так что мне не нужно использовать SftpRemoteFileTemplate везде