Spring интеграция SFTP - не загружайте повторно локально удаленные файлы

Из прочтения документации Spring SFTP (http://docs.spring.io/spring-integration/reference/html/sftp.html) не совсем понятно, можно ли предотвратить повторную загрузку успешно переданных файлов, которые впоследствии удаляются.

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

Однако Spring SFTP обнаруживает, что они были удалены (либо во время выполнения, либо при перезапуске), и повторно загружает их.

Я уже использую SftpPersistentAcceptOnceFileListFilter, чтобы выжить после перезапуска.

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

Кроме того, если вы настроите фильтр для использования FtpPersistentAcceptOnceFileListFilter, а временная метка удаленного файла изменится (что приведет к ее повторной выборке), локальный фильтр по умолчанию не позволит обрабатывать этот новый файл.

Используйте атрибут local-filter для настройки поведения фильтра локальной файловой системы. Чтобы решить эти конкретные варианты использования, вы можете вместо этого использовать FileSystemPersistentAcceptOnceFileListFilter в качестве локального фильтра. Этот фильтр также сохраняет принятые имена файлов и измененную временную метку в экземпляре стратегии theMetadataStore (Раздел 9.5, «Хранилище метаданных») и обнаруживает изменение времени изменения локального файла.

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

Вот моя соответствующая конфигурация:

<int-sftp:inbound-channel-adapter id="sftpInboundAdapter"
        auto-startup="true" channel="receiveChannel" session-factory="sftpSessionFactory"
        local-directory="file:local-dir" remote-directory="files"
        auto-create-local-directory="true" delete-remote-files="false"
        filter="compositeFilter">
        <int:poller fixed-rate="1000" max-messages-per-poll="1" />
    </int-sftp:inbound-channel-adapter>

<bean id="compositeFilter"
        class="org.springframework.integration.file.filters.CompositeFileListFilter">
        <constructor-arg>
            <list>
                <bean
                    class="org.springframework.integration.sftp.filters.SftpSimplePatternFileListFilter">
                    <constructor-arg value="*.zip" />
                </bean>
                <bean
                    class="org.springframework.integration.sftp.filters.SftpPersistentAcceptOnceFileListFilter">
                    <constructor-arg name="store" ref="metadataStore" />
                    <constructor-arg value="foo/bar" />
                </bean>
            </list>
        </constructor-arg>
    </bean>

person J Doe    schedule 05.05.2016    source источник


Ответы (1)


Отредактируйте свой вопрос, указав свою конфигурацию - SftpPersistentAcceptOnceFileListFilter должен предотвращать повторную загрузку файлов, если только временная метка файла не изменится.

F[] files = session.list(remoteDirectory);
if (!ObjectUtils.isEmpty(files)) {
    List<F> filteredFiles = filterFiles(files);
    for (F file : filteredFiles) {
        try {
            if (file != null) {
                copyFileToLocalDirectory(
                        remoteDirectory, file, localDirectory,
                        session);
            }
        }
...
person Gary Russell    schedule 05.05.2016
comment
Гэри, это отметка времени на удаленном сайте? - person J Doe; 05.05.2016
comment
Да; удаленный и локальный фильтры независимы - если постоянный (удаленный) filter обнаруживает файл, который еще не был загружен, или временная метка на удаленном сервере изменилась, он загружается, в противном случае он пропускается. Если вы используете Redis для своего хранилища метаданных, вы можете использовать redis-cli и monitor для просмотра обновлений в режиме реального времени. - person Gary Russell; 05.05.2016
comment
В этом есть смысл, Гарри. Я обновил свой вопрос конфигурацией и дважды проверил, что файлы все еще загружаются повторно после локального удаления. - person J Doe; 06.05.2016
comment
А вы смотрели данные в хранилище метаданных? Включите ведение журнала DEBUG, если вы все еще не можете это понять, опубликуйте журнал где-нибудь, например, в github gist или pastebin и т. Д. (Он, вероятно, будет слишком большим для переполнения стека). - person Gary Russell; 06.05.2016
comment
Магазин пуст, я не знаю почему - он находится в / tmp / и доступен для записи - person J Doe; 06.05.2016
comment
Если ваш магазин - PropertiesPersistingMetadataStore, а версия Spring интеграции меньше 4.1.5, файл обновляется только тогда, когда контекст приложения закрывается нормально; он сохраняет состояние в памяти. Если вы используете версию 4.1.5 или новее, фильтр имеет свойство flushOnUpdate, которое будет постоянно обновлять файл. Кроме того, помещать его в /tmp - не лучшая идея, потому что ОС уничтожит его при перезагрузке. Обычно мы рекомендуем более надежное хранилище метаданных, такое как redis. - person Gary Russell; 06.05.2016