Как направить любой загруженный файл в канал ошибок, когда БД не работает, и как обрабатывать их после того, как БД работает? - PullRequest
1 голос
/ 25 апреля 2019

В моем приложении Springboot реализован опрос. Этот код регулярно проверяет удаленный каталог и загружает любой новый файл из удаленного каталога. После загрузки файла мы обрабатываем файл и сохраняем данные в базе данных. Предположим, что база данных не работает. мои обработанные данные файла не сохраняются в БД. Когда БД снова работает, мой файл не берется для обработки и, следовательно, данные файла не сохраняются. быть сохраненным в БД в канал ошибок, тогда при каждом запуске БД файл будет обработан

Ниже мой код, который загружает файл

@Bean

  Properties configProperties(){

Properties config = new Properties();

config.setProperty("PreferredAuthentications", "password");

            return config;

        }

@Bean(name = PollerMetadata.DEFAULT_POLLER)

    public PollerMetadata pollRemoteDirectory() {

        PollerMetadata pollerMetadata = new PollerMetadata();

        pollerMetadata.setTrigger(
                new PeriodicTrigger(getSftpConfig().getPollingInterval(), TimeUnit.MINUTES));

        pollerMetadata.setMaxMessagesPerPoll(1000);

        return pollerMetadata;

        }

    @Bean

    SftpInboundFileSynchronizer syncRemoteFilesToLocalDirectory() throws MalformedURLException {

        SftpInboundFileSynchronizer fileSync = new VsSftpInboundFileSynchronizer(getSftpConfig().sftpSessionFactory());

        fileSync.setDeleteRemoteFiles(true);

        fileSync.setRemoteDirectory(getSftpConfig().getRemoteFilePath());

        CompositeFileListFilter<ChannelSftp.LsEntry> compositeFileListFilter = new 
        CompositeFileListFilter<ChannelSftp.LsEntry>();

        compositeFileListFilter.addFilter(new SftpSimplePatternFileListFilter("*.xml"));

        fileSync.setFilter(compositeFileListFilter);

        return fileSync;

    }

@Bean

    @InboundChannelAdapter(value = "sftpChannel")

    public MessageSource setMessageSourceAndLocalDirectory() throws MalformedURLException {

        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(
                syncRemoteFilesToLocalDirectory());

        source.setLocalDirectory(new File(getSftpConfig().getArchiveFilePath()));

        source.setAutoCreateLocalDirectory(true);

        return source;
    }

@Bean

    @ServiceActivator(inputChannel = "sftpChannel")

    SftpFileHandler messageHandler() {

        return new SftpFileHandler();

    }

@Bean

    public static ResourceBundleMessageSource emailMessageSource() {

        final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

        messageSource.setBasename("mail/MailMessages");

        return messageSource;

    }

@Bean

    public static SpringTemplateEngine emailTemplateEngine() {

        final SpringTemplateEngine templateEngine = new SpringTemplateEngine();

        templateEngine.addTemplateResolver(textTemplateResolver());

        templateEngine.addTemplateResolver(htmlTemplateResolver());

        templateEngine.addTemplateResolver(stringTemplateResolver());

        templateEngine.setTemplateEngineMessageSource(emailMessageSource());

        return templateEngine;

    }

1 Ответ

1 голос
/ 25 апреля 2019

Проблема в том, что опрошенные файлы хранятся во внутренней FileSystemPersistentAcceptOnceFileListFilter для SftpInboundFileSynchronizingMessageSource.

Вам необходимо настроить внешний компонент следующим образом:

@Bean
public FileSystemPersistentAcceptOnceFileListFilter localFilefilter() {
    return new FileSystemPersistentAcceptOnceFileListFilter(new SimpleMetadataStore(), "sftpFiles");
}

Затем введите это так:

 source.setLocalFilter(localFilefilter());

Когда происходит исключение из файла, сохраняемого в БД, вам просто нужно вызвать метод delete() этого фильтра с файлом, который вы не можете сохранить. См ResettableFileListFilter:

/**
 * A {@link FileListFilter} that can be reset by removing a specific file from its
 * state.
 * @author Gary Russell
 * @since 4.1.7
 *
 */
public interface ResettableFileListFilter<F> extends FileListFilter<F> {

    /**
     * Remove the specified file from the filter so it will pass on the next attempt.
     * @param f the element to remove.
     * @return true if the file was removed as a result of this call.
     */
    boolean remove(F f);

}

Я могу предположить, что ваш SftpFileHandler выполняет эту тяжелую работу, поэтому вы можете настроить adviceChain для его @ServiceActivator с ExpressionEvaluatingRequestHandlerAdvice и настроить его failureChannel для выполнения упомянутой операции delete().

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

Другой способ достижения цели - использовать retry . Для этой цели вы можете использовать RequestHandlerRetryAdvice по той же причине @ServiceActivator.adviceChain(). В этом случае один и тот же файл будет пытаться снова и снова сохраняться в БД без какой-либо необходимой логики обработки ошибок.

См. Дополнительную информацию в Справочном руководстве: https://docs.spring.io/spring-integration/reference/html/#message-handler-advice-chain, а также: https://docs.spring.io/spring-integration/reference/html/#recovering-from-failures-2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...