我的要求是在我的spring-batch应用程序中从文件服务器中的远程目录下载多个文件。其中一个示例here建议使用SourcePollingChannelAdapter。在此示例中,适配器已启动adapter.start()但未停止。那么这项工作的生命周期如何?我的要求是先下载&仅在下载所有文件时,才继续读取文件。但这似乎是一种下载文件的异步过程。那么如何在下载所有文件时收到通知&准备好继续吗?我没有看到任何其他方法将任何处理程序注入到adapter / pollablechannel。
使用的示例配置:
<int-sftp:inbound-channel-adapter id="sftpInbondAdapterBean"
auto-startup="false" channel="receiveChannelBean" session-factory="sftpSessionFactory"
local-directory="${sftp.download.localDirResource}"
remote-directory="${sftp.download.remoteFilePath}"
auto-create-local-directory="true" delete-remote-files="false"
filename-regex=".*\.csv$">
<int:poller fixed-rate="5000" max-messages-per-poll="3" />
</int-sftp:inbound-channel-adapter>
<int:channel id="receiveChannelBean">
<int:queue/>
</int:channel>
如果显式调用adapter.stop(),则抛出InterruptedException。如果没有调用stop,则会以异步方式下载文件而不会阻塞&amp;因此,下一步不知道下载是否已完成或正在进行中。
编辑:DownloadingTasklet的代码片段
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
try {
sftpInbondAdapter.start();
Thread.sleep(15000); // ---Is this mandatory ?
} catch (Exception e) {
throw new BatchClientException("Batch File Download was un-successful !", e);
} finally {
// sftpInbondAdapter.stop();
Logger.logDebug("BATCH_INPUT_FILE_DOWNLOAD", "COMPLETED");
}
return RepeatStatus.FINISHED;
}
答案 0 :(得分:0)
SftpInboundFileSynchronizingMessageSource
分为两个阶段:
首先,它执行从远程目录到本地目录的同步:
Message<File> message = this.fileSource.receive();
if (message == null) {
this.synchronizer.synchronizeToLocalDirectory(this.localDirectory);
message = this.fileSource.receive();
}
正如您所看到的那样,它开始将文件作为消息发出。但是只有本地文件。因此,从FTP下载已经完成。
只有在发送过程中清除所有本地文件时才会发生下一次下载尝试。
所以,你想要的是内置功能。
修改强>
我们测试中的一些DEBUG日志:
19:29:32,005 DEBUG task-scheduler-1 util.SimplePool:190 - Obtained new org.springframework.integration.sftp.session.SftpSession@26f16625.
19:29:32,036 DEBUG task-scheduler-1 inbound.SftpInboundFileSynchronizer:287 - cannot copy, not a file: /sftpSource/subSftpSource
19:29:32,036 DEBUG task-scheduler-1 session.CachingSessionFactory:187 - Releasing Session org.springframework.integration.sftp.session.SftpSession@26f16625 back to the pool.
19:29:32,036 DEBUG task-scheduler-1 util.SimplePool:221 - Releasing org.springframework.integration.sftp.session.SftpSession@26f16625 back to the pool
19:29:32,037 DEBUG task-scheduler-1 inbound.SftpInboundFileSynchronizer:270 - 3 files transferred
19:29:32,037 DEBUG task-scheduler-1 file.FileReadingMessageSource:380 - Added to queue: [local-test-dir\rollback\ sftpSource1.txt, local-test-dir\rollback\sftpSource2.txt]
19:29:32,043 INFO task-scheduler-1 file.FileReadingMessageSource:368 - Created message: [GenericMessage [payload=local-test-dir\rollback\ sftpSource1.txt, headers={id=40f75bd1-2150-72a4-76f0-f5c619a246da, timestamp=1465514972043}]]
配置如:
<int-sftp:inbound-channel-adapter
session-factory="sftpSessionFactory"
channel="requestChannel"
remote-directory="/sftpSource"
local-directory="local-test-dir/rollback"
auto-create-local-directory="true"
local-filter="acceptOnceFilter">
<int:poller fixed-delay="1" max-messages-per-poll="0"/>
</int-sftp:inbound-channel-adapter>
注意它是如何显示3 files transferred
的,其中一个是目录,所以跳过。
如何说Added to queue:
然后才开始将它们作为消息发出。
一切都只是因为我有fixed-delay="1"
。即使它只有1毫秒。
max-messages-per-poll="0"
表示使用一个轮询任务处理所有内容。