Какова процедура повторной загрузки локально удаленных файлов с помощью входящего SFTP - PullRequest
2 голосов
/ 28 мая 2020

Согласно этому do c не удалось найти правильный процесс для повторной загрузки локально удаленного файла с удаленного SFTP.

Требуется удалить локальный файл, который уже был получен с удаленного SFTP, и использовать sftp-inbound-adapter ( конфигурация DSL ) для повторной загрузки того же файла, когда это необходимо. В этой реализации MetadataStore не сохраняется в какой-либо внешней системе, например PropertiesPersistingMetadataStore или Redis Metadata Store . Итак, согласно do c, MetadataStore хранится в In-Memory .

Не удалось найти способ удалить метаданные этого удаленного файла из MetadataStore, чтобы повторно получить локально удаленный файл с помощью file_name. И понятия не имею, как должен быть реализован этот обратный вызов removeRemoteFileMetadata() ( в соответствии с этим do c).

Класс конфигурации содержит следующие:

    @Bean
    public IntegrationFlow fileFlow() {
        SftpInboundChannelAdapterSpec spec = Sftp.inboundAdapter(sftpConfig.getSftpSessionFactory())
                .preserveTimestamp(true)
                .patternFilter(Constants.FILE_NAME_CONVENTION)
                .remoteDirectory(sftpConfig.getSourceLocation())
                .autoCreateLocalDirectory(true)
                .deleteRemoteFiles(false)
                .localDirectory(new File(sftpConfig.getDestinationLocation()));

        return IntegrationFlows
                .from(spec, e -> e.id("sftpInboundAdapter").autoStartup(false)
                        .poller(Pollers.fixedDelay(5000).get()))
                .channel(MessageChannels.direct().get())
                .handle(message -> {
                    log.info("Fetching File : " + message.getHeaders().get("file_name").toString());
                })
                .get();
    }

Ответы [ 2 ]

6 голосов
/ 29 мая 2020

Я попытался решить эту проблему и использовал ссылочный код Tanvir Hossain . Я кодировал вот так.

@Bean
public IntegrationFlow fileFlow() {
    SftpInboundChannelAdapterSpec spec = Sftp
            .inboundAdapter(sftpConfig.getSftpSessionFactory())
            .preserveTimestamp(true)
            .filter(sftpFileListFilter())
            .localFilter(systemFileListFilter())
            .remoteDirectory(sftpConfig.getSourceLocation())
            .autoCreateLocalDirectory(true)
            .deleteRemoteFiles(false)
            .localDirectory(new File(sftpConfig.getDestinationLocation()));

    return IntegrationFlows
            .from(spec, e -> e.id("sftpInboundAdapter").autoStartup(false)
                    .poller(Pollers.fixedDelay(5000).get()))
            .channel(MessageChannels.direct().get())
            .handle(message -> {
                log.info("Fetching File : " 
                        + message.getHeaders().get("file_name").toString());
            })
            .get();
}


private FileSystemPersistentAcceptOnceFileListFilter systemFileListFilter() {

    return new FileSystemPersistentAcceptOnceFileListFilter(store(), prefix);
}


private ChainFileListFilter<ChannelSftp.LsEntry> sftpFileListFilter() {

    ChainFileListFilter<ChannelSftp.LsEntry> chainFileListFilter = 
                                                new ChainFileListFilter<>();
    chainFileListFilter.addFilters(
            new SftpPersistentAcceptOnceFileListFilter(store(), prefix),
            new SftpSimplePatternFileListFilter(sftpConfig.getFileFilterValue())
    );
    return chainFileListFilter;
}

@Bean
public SimpleMetadataStore store() {
    return new SimpleMetadataStore();
}

и мой Controller для удаления метаданных, как показано ниже:

public class Controller { 

    private final SimpleMetadataStore simpleMetadataStore;

    public Controller(SimpleMetadataStore simpleMetadataStore) {

           this.simpleMetadataStore = simpleMetadataStore;

    }

    @GetMapping("/test/remove-metadata/{type}/{fileName}")
    @ResponseBody
    public String removeFileMetadata(
             @PathVariable("fileName") String fileName,
             @PathVariable("type") String type
    ) {
        String prefix = definedPrefix;
        String filePath = "";
        if(type.equals("local")){
            filePath = "/local/storage/path/" + fileName;
        }else if(type.equals("remote")){
            filePath = fileName
        }
        String key = prefix + filePath;

        simpleMetadataStore.remove(key);
        return key;
    }

}

Я получаю желаемый файл. Для меня это повторная загрузка файла.

1 голос
/ 28 мая 2020

Используйте ChainFileListFilter, с SftpSimplePatternFileListFilter и SftpPersistentAcceptOnceFileListFilter.

Используйте SimpleMetadataStore для сохранения состояния в памяти (или какой-нибудь другой MetadataStore).

new SftpPersistentAcceptOnceFileListFilter(store, "somePrefix");

Тогда store.remove(key), где key это somePrefix + fileName.

Используйте аналогичный фильтр в localFilter с FileSystemPersistentAcceptOnceFileListFilter.

...