Файл FTP не загружается с помощью Spring Integration после локального удаления - PullRequest
0 голосов
/ 28 октября 2019

Мы пишем пакетное задание, которое принимает файл в качестве ввода с FTP, генерирует несколько новых файлов и записывает их в корзину S3, и для этого мы используем Spring Integration.

Файл вFTP является извлечением из БД и обновляется каждую ночь.

Проблема в том, что, когда мы запускаем приложение в первый раз, оно хорошо подключается к FTP, загружает файл и загружает результат генерации S3,Затем мы удаляем загруженный файл локально и ожидаем следующего поколения файла на FTP, чтобы перезапустить процесс. Но он никогда не загружает файл снова.

Есть идеи?

    @Bean
    public IntegrationFlow ftpInboundFlow() {
        return IntegrationFlows
                .from(ftpReader(),
                        spec -> spec.id("ftpInboundAdapter")
                                .autoStartup(true)
                                .poller(Pollers.fixedDelay(period)))
                .transform(stockUnmarshaller)
                .transform(stockTransformer)
                .transform(stockMarshaller)
                .transform(picturesDownloader)
                .transform(picturesZipper)
                .transform(stockIndexer)
                .handle(directoryCleaner)
                .nullChannel();
    }

    @Bean
    public FtpInboundChannelAdapterSpec ftpReader() {
        return Ftp.inboundAdapter(ftpSessionFactory())
                .preserveTimestamp(true)
                .remoteDirectory(rootFolder)
                .autoCreateLocalDirectory(true)
                .localDirectory(new File(localDirectory));
    }

    @Bean
    public SessionFactory<FTPFile> ftpSessionFactory() {
        DefaultFtpSessionFactory sessionFactory = new DefaultFtpSessionFactory();
        sessionFactory.setHost(host);
        sessionFactory.setUsername(userName);
        sessionFactory.setPassword(password);
        sessionFactory.setClientMode(FTPClient.PASSIVE_LOCAL_DATA_CONNECTION_MODE);
        return sessionFactory;
    }

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Похоже, вы говорите о том же файле. В этом случае удаление его из локального каталога недостаточно. В процессе участвуют несколько FileListFilter экземпляров, которые содержат запись для обработанного файла. И в соответствии с вашей конфигурацией вы имеете дело с вариантами в памяти. Они действительно ничего не знают о вашем локальном удалении файла.

Если быть точным, есть два фильтра, о которых вам нужно беспокоиться: FtpPersistentAcceptOnceFileListFilter для удаленной записи и FileSystemPersistentAcceptOnceFileListFilter для локальной копии файла. Оба они реализуют ResettableFileListFilter, поэтому вы можете вызывать их remove() всякий раз, когда выполняете файловый процесс.

FtpInboundChannelAdapterSpec в Java DSL имеет следующие параметры:

/**
 * Configure a {@link FileListFilter} to be applied to the remote files before
 * copying them.
 * @param filter the filter.
 * @return the spec.
 */
public S filter(FileListFilter<F> filter) {

/**
 * A {@link FileListFilter} used to determine which files will generate messages
 * after they have been synchronized.
 * @param localFileListFilter the localFileListFilter.
 * @return the spec.
 * @see AbstractInboundFileSynchronizingMessageSource#setLocalFilter(FileListFilter)
 */
public S localFilter(FileListFilter<File> localFileListFilter) {

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

Существует также опциянапример:

/**
 * Switch the local {@link FileReadingMessageSource} to use its internal
 * {@code FileReadingMessageSource.WatchServiceDirectoryScanner}.
 * @param useWatchService the {@code boolean} flag to switch to
 * {@code FileReadingMessageSource.WatchServiceDirectoryScanner} on {@code true}.
 * @since 5.0
 */
public void setUseWatchService(boolean useWatchService) {

И событие DELETE также настроено для наблюдателя. Когда это происходит, удаленный файл также удаляется из локального фильтра.

Вы также можете правильно обращаться с удаленным файлом при настройке:

/**
 * Set to true to enable the preservation of the remote file timestamp when transferring.
 * @param preserveTimestamp true to preserve.
 * @return the spec.
 */
public S preserveTimestamp(boolean preserveTimestamp) {

Таким образом, более новый файл с тем жеимя будет рассматриваться как другой файл, а его запись в упомянутых фильтрах будет перезаписана. Хотя я вижу, что вы уже используете его, но вы все еще жалуетесь, что это не работает. Это может быть в случае со старой версией Spring Integration, когда FileSystemPersistentAcceptOnceFileListFilter не использовался для локальных файлов.

0 голосов
/ 28 октября 2019

Адаптер входящего канала имеет два фильтра .filter и .localFilter.

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

По умолчаниюfilter - это FtpPersistentAcceptOnceFileListFilter, который будет извлекать только новые или измененные файлы.

По умолчанию localFilter - это FileSystemPersistentAcceptOnceFileListFilter, который, опять же, пропустит файл только второй раз, если онотметка времени изменилась.

Таким образом, файл будет повторно обработан только при изменении его отметки времени.

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

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