Интеграция Spring - SFTP переименовывает или перемещает файл на удаленный сервер после копирования

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

Пожалуйста, помогите переименовать файл после загрузки.

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SessionFactory<LsEntry> sftpSessionFactory(
        final DataloadServiceProperties DataloadServiceProperties) {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(true);
    factory.setHost(DataloadServiceProperties.getSftpHost());
    factory.setPort(DataloadServiceProperties.getSftpPort());
    factory.setUser(DataloadServiceProperties.getSftpUser());
    if (DataloadServiceProperties.getSftpPrivateKey() != null) {
        factory.setPrivateKey(DataloadServiceProperties.getSftpPrivateKey());
        factory.setPrivateKeyPassphrase(
                DataloadServiceProperties.getSftpPrivateKeyPassphrase());
    }
    else {
        factory.setPassword(DataloadServiceProperties.getSftpPasword());
    }
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<LsEntry>(factory);
}

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE - 1)
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer(
        final SessionFactory<LsEntry> sftpSessionFactory,
        final DataloadServiceProperties DataloadServiceProperties) {
    SftpInboundFileSynchronizer fileSynchronizer =
            new SftpInboundFileSynchronizer(sftpSessionFactory);
    fileSynchronizer.setDeleteRemoteFiles(false);
    fileSynchronizer.setRemoteDirectory(
            DataloadServiceProperties.getSftpRemoteDirectoryDownload());
    fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter(
            DataloadServiceProperties.getSftpRemoteDirectoryDownloadFilter()));
    return fileSynchronizer;
}

Входящий канал для поиска файла на SFTP-сервере

@Bean
@Order(Ordered.HIGHEST_PRECEDENCE - 2)
@InboundChannelAdapter(
        channel = "fromSftpChannel",
        poller = @Poller(
                cron = "${sftp.poller.cron}"))
public MessageSource<File> sftpMessageSource(
        final SftpInboundFileSynchronizer sftpInboundFileSynchronizer,
        final DataloadServiceProperties DataloadServiceProperties) {
    SftpInboundFileSynchronizingMessageSource source =
            new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer);
    source.setLocalDirectory(
            new File(DataloadServiceProperties.getSftpLocalDirectoryDownload()));
    source.setAutoCreateLocalDirectory(true);
    source.setLocalFilter(new AcceptOnceFileListFilter<File>());
    return source;
}

Обработка файла после загрузки в локальную папку

@Bean
@Inject
@ServiceActivator(
        inputChannel = "fromSftpChannel")
public MessageHandler resultFileHandler() {
    return new MessageHandler() {
        @Override
        public void handleMessage(final Message<?> message) throws MessagingException {
            String payload = String.valueOf(message.getPayload());
            if (!StringUtils.isEmpty(payload) && payload.endsWith("gz")) {
                LOGGER.info("toRequest : {}", message.getPayload());
            }
        }
    };
}

Спасибо, Артем Билан, я добавил ниже код для перемещения файла в папку uat после загрузки. Теперь он работает так, как ожидалось.

private static final SpelExpressionParser PARSER = new SpelExpressionParser();

@Bean(name = "fromSftpChannel")
 public MessageChannel fromSftpChannel() {
     return new PublishSubscribeChannel();
 }

 @Bean
@Inject
@ServiceActivator(inputChannel = "fromSftpChannel")
@Order(Ordered.LOWEST_PRECEDENCE)
public MessageHandler moveFile() {
    SftpOutboundGateway sftpOutboundGateway = new  SftpOutboundGateway(sftpSessionFactory(), Command.MV.getCommand(), "'/test/'.concat(" + PARSER.parseExpression("payload.getName()").getExpressionString() + ")");
    sftpOutboundGateway.setRenameExpressionString("'/test/uat/'.concat(" + PARSER.parseExpression("payload.getName()").getExpressionString() + ")");
    sftpOutboundGateway.setRequiresReply(false);
    sftpOutboundGateway.setOutputChannelName("nullChannel");
    sftpOutboundGateway.setOrder(Ordered.LOWEST_PRECEDENCE);
    sftpOutboundGateway.setAsync(true);
    return sftpOutboundGateway;
}    
3
0
2 246
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам необходимо сделать этот fromSftpChannel как PublishSubscribeChannel и иметь второго подписчика с SftpOutboundGateway. Тот, который вы действительно настраиваете для Command.MV, и все! Не забудьте настроить setRenameExpression(), чтобы указать удаленный путь для перемещения!

Спасибо, я думаю, что это способ изменить канал для публикации канала подписки, но я не знал, как установить выражение переименования. @ Bean (name = "fromSftpChannel") public MessageChannel fromSftpChannel () {return new PublishSubscribeChannel (); }

nmanandhan 03.10.2018 18:41

См. Описание команды MV: docs.spring.io/spring-integration/docs/5.0.8.RELEASE/referen‌ ce /…

Artem Bilan 03.10.2018 18:45

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

Artem Bilan 03.10.2018 18:56

Я внес рекомендованные изменения для перемещения файла, но исключение из доступного заголовка output-channel или replyChannel не было, я добавил соответствующие изменения кода. не могли бы вы помочь решить эту проблему?

nmanandhan 05.10.2018 12:45

Поскольку SftpOutboundGateway на самом деле является компонентом запроса-ответа и здесь нет режима только для отправки, вам необходимо добавить sftpOutboundGateway.setOutputChannelName("nullChannel");, чтобы впоследствии прекратить обработку.

Artem Bilan 05.10.2018 15:38

еще раз спасибо, это устранило исключение. Поллер запускается каждые 5 секунд для поиска нового файла на сервере sftp. первый файл обработан и перемещен в папку правильно, однако после первого успешного запуска поллер перестал выбирать файл из sftp. это из-за конфигурации нулевого канала?

nmanandhan 05.10.2018 15:53

Нет, это не связано. Возможно, у вас просто не будет новых файлов для опроса. Или что-то еще произошло в вашем потоке. Я думаю, мы можем рассмотреть это в отдельном вопросе SO, поскольку текущая тема касается команды MV. Примите, пожалуйста, ответ: stackoverflow.com/help/someone-answers

Artem Bilan 05.10.2018 15:55

конечно, еще раз спасибо за то, что внимательно следили за этим. Я просто поместил файл обратно на sftp-сервер для обработки, но он его не выбрал.

nmanandhan 05.10.2018 15:57

Верный. Потому что у вас есть `source.setLocalFilter (new AcceptOnceFileListFilter <File> ()); . So, the same file is not processed again until after application restart. You should consider to use some persistent FileListFilter` (SftpPersistentAcceptOnceFileListFilter ), чтобы сохранять состояние между перезапусками приложения и не обрабатывать одни и те же файлы снова: docs.spring.io/spring-integration/docs/current/reference/htm‌ l /…

Artem Bilan 05.10.2018 16:03

да, все работает нормально. изменил имя файла на сервере sftp, и он был взят для обработки. Спасибо

nmanandhan 05.10.2018 16:06

Большой! Итак, тогда нет необходимости в новом SO-вопросе!

Artem Bilan 05.10.2018 16:06

Другие вопросы по теме