我有以下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
答案 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无关。遗憾...