SftpInboundFileSynchronizer不同步

时间:2017-07-24 19:31:03

标签: spring spring-integration spring-integration-sftp

我有以下SFTP文件同步器:

@Bean
public SftpInboundFileSynchronizer sftpInboundFileSynchronizer() {
    SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sftpSessionFactory());
    fileSynchronizer.setDeleteRemoteFiles(false);
    fileSynchronizer.setRemoteDirectory(applicationProperties.getSftpDirectory());
    CompositeFileListFilter<ChannelSftp.LsEntry> compositeFileListFilter = new CompositeFileListFilter<ChannelSftp.LsEntry>();
    compositeFileListFilter.addFilter(new SftpPersistentAcceptOnceFileListFilter(store, "sftp"));
    compositeFileListFilter.addFilter(new SftpSimplePatternFileListFilter(applicationProperties.getLoadFileNamePattern()));
    fileSynchronizer.setFilter(compositeFileListFilter);
    fileSynchronizer.setPreserveTimestamp(true);
    return fileSynchronizer;
}

首次运行应用程序时,它将与远程SFTP站点目录同步到本地目录。但是,它无法获取远程SFTP目录文件中的任何后续更改。

计划按以下方式进行投票:

@Bean
@InboundChannelAdapter(autoStartup="true", channel = "sftpChannel", poller = @Poller("pollerMetadata"))
public SftpInboundFileSynchronizingMessageSource sftpMessageSource() {
    SftpInboundFileSynchronizingMessageSource source =
            new SftpInboundFileSynchronizingMessageSource(sftpInboundFileSynchronizer());
    source.setLocalDirectory(applicationProperties.getScheduledLoadDirectory());
    source.setAutoCreateLocalDirectory(true);
    ChainFileListFilter<File> chainFileFilter = new ChainFileListFilter<File>();
    chainFileFilter.addFilter(new LastModifiedFileListFilter());
    FileSystemPersistentAcceptOnceFileListFilter fs = new FileSystemPersistentAcceptOnceFileListFilter(store, "dailyfilesystem");
    fs.setFlushOnUpdate(true);
    chainFileFilter.addFilter(fs);
    source.setLocalFilter(chainFileFilter);
    source.setCountsEnabled(true);
    return source;
}

@Bean
public PollerMetadata pollerMetadata(RetryCompoundTriggerAdvice retryCompoundTriggerAdvice) {
    PollerMetadata pollerMetadata = new PollerMetadata();
    List<Advice> adviceChain = new ArrayList<Advice>();
    adviceChain.add(retryCompoundTriggerAdvice);
    pollerMetadata.setAdviceChain(adviceChain);
    pollerMetadata.setTrigger(compoundTrigger());
    pollerMetadata.setMaxMessagesPerPoll(1);
    return pollerMetadata;
}

@Bean
public CompoundTrigger compoundTrigger() {
    CompoundTrigger compoundTrigger = new CompoundTrigger(primaryTrigger());
    return compoundTrigger;
}

@Bean
public CronTrigger primaryTrigger() {
    return new CronTrigger(applicationProperties.getSchedule());
}

@Bean
public PeriodicTrigger secondaryTrigger() {
    return new PeriodicTrigger(applicationProperties.getRetryInterval());
}

在扩展afterReceive的{​​{1}} RetryCompoundTriggerAdvice方法中,我在第一次运行后得到一个空结果。

如何配置同步器以使其定期同步(而不是仅在应用启动时进行一次)?

更新

我发现当SFTP站点在我的应用程序启动时其目录中没有文件时,AbstractMessageSourceAdvice会在每个轮询间隔同步。所以我可以在每次民意调查中看到SftpInboundFileSynchronizer日志语句。但是只要在SFTP站点上找到文件,它就会同步以在本地获取该文件,然后不再同步。

更新2

我道歉......这是自定义代码:

com.jcraft.jsch

1 个答案:

答案 0 :(得分:1)

你有逻辑:

@Override
public boolean beforeReceive(MessageSource<?> source) {
    logger.debug("!inProcess is " + !inProcess);
    return !inProcess;
}

让我们研究一下它的JavaDoc:

/**
 * Subclasses can decide whether to proceed with this poll.
 * @param source the message source.
 * @return true to proceed.
 */
public abstract boolean beforeReceive(MessageSource<?> source);

围绕这种方法的逻辑:

    Message<?> result = null;
    if (beforeReceive((MessageSource<?>) target)) {
        result = (Message<?>) invocation.proceed();
    }
    return afterReceive(result, (MessageSource<?>) target);

因此,仅当invocation.proceed()返回beforeReceive()时,我们才会调用true(SFTP同步)。在您的情况下,仅在!inProcess

的情况下才是这种情况

afterReceive()实施中,如果您有inProcess = true;,则首次尝试result。并且看起来只有当有人拨打false时才会将其重置为foundExpectedMessage()

那么,您对我们的期望是什么?它实际上在您的自定义代码中,与Framework无关。遗憾...