使用 SFTP 入站重新下载本地删除的文件的过程是什么

What's the procedure to re-download locally deleted files using SFTP Inbound

根据这个 doc 无法找到从远程重新下载本地删除文件的正确过程SFTP。

要求是,删除已经从远程 SFTP 获取的本地文件并使用 sftp-inbound-adapter(DSL configuration) to re-fetch that same file when required. In this implementation, MetadataStore haven't been persisted into any external system like PropertiesPersistingMetadataStore or Redis Metadata Store. So as per docMetadataStore 存储在 内存中

无法找到任何方法从 MetadataStore 中删除该远程文件的元数据以使用 file_name 重新获取本地删除的文件。并且没有任何线索,这个 removeRemoteFileMetadata() 回调需要如何实现 (according to this doc).

配置class包含以下内容:

    @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();
    }

使用 ChainFileListFilter,使用 SftpSimplePatternFileListFilterSftpPersistentAcceptOnceFileListFilter

使用 SimpleMetadataStore 将状态存储在内存中(或其他一些 MetadataStore)。

new SftpPersistentAcceptOnceFileListFilter(store, "somePrefix");

然后,store.remove(key) 其中 keysomePrefix + fileName.

localFilterFileSystemPersistentAcceptOnceFileListFilter 中使用类似的过滤器。

我试图解决这个问题,我使用了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;
    }

}

我正在获取我想要的文件。它正在为我重新获取文件。