在ftp完成之前拾取文件的Camel路由

时间:2012-12-12 16:48:03

标签: java spring apache-camel

我有一个客户将ftp的文件发送到我们的服务器。我有一个路由定义从该目录中选择某些文件,并将它们移动到另一个目录进行处理。问题是它只要看到它就会立即使用它,并且不会等到ftp完成。结果是在uri中描述的路径中的0字节文件。我已经尝试了每个readLock选项(masterFile,rename,changed,fileLock),但没有一个有效。我使用spring DSL来定义我的骆驼路线。这是一个不起作用的例子。骆驼版是2.10.0

    <route>
        <from uri="file:pathName?initialDelay=10s&amp;move=ARCHIVE&amp;sortBy=ignoreCase:file:name&amp;readLock=fileLock&amp;readLockCheckInterval=5000&amp;readLockTimeout=10m&amp;filter=#FileFilter" />
        <to uri="file:pathName/newDirectory/" />
    </route>

任何帮助将不胜感激。谢谢!

请注意......有一次,这条路由在不同的服务器上运行,我不得不将文件ftp到另一台处理它的服务器上。当我在骆驼中使用ftp组件时,该路由工作正常。那就是在执行ftp之前它一直等到收到文件。我在定义的路线上有相同的选项。这就是为什么我认为应该有一种方法来实现它,因为ftp组件使用camel中的文件组件选项。


我正在接受@ PeteH的建议#2并做了以下事情。我仍然希望有另一种方式,但这会有效。

我添加了以下方法,它返回一个Date.minus(x秒)

的日期
public static Date getDateMinusSeconds(Integer seconds) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, seconds);
return  cal.getTime();
}

然后在我的过滤器中检查初始过滤是否为真。如果是,我将Last修改日期与getDateMinusSeconds()进行比较。如果比较结果为真,我会为过滤器返回false。

    if(filter){
        if(new Date(pathname.getLastModified()).after(DateUtil.getDateMinusSeconds(-30))){
            return false;
        }
    } 

3 个答案:

答案 0 :(得分:5)

我在您的环境中没有做过这些,但在使用FTP之前遇到过这种问题。

我建议的两个更好的选择是,如果你可以让客户发送两个文件。 File1是他们的数据,File2可以是任何东西。他们按顺序发送。你在File2到达时陷阱,但你所做的只是将它作为File1安全抵达的“信号”。

不太好的选项(这是我们最终实现的选项,因为我们无法控制正在发送的文件)是编写代码,以便您拒绝处理任何文件,直到其上次修改时间戳至少为< em> x 分钟。我想我们5分钟就定了。这非常可怕,因为你基本上是开枪,检查,睡觉,检查等等。

但是你描述的问题在FTP上是众所周知的。就像我说的,我不知道这些方法中的任何一种是否适用于您的环境,但肯定是在高水平它们是合理的。

答案 1 :(得分:3)

camel继承自文件组件。这是描述这件事的最高层......

请注意JDK File IO API在检测另一个应用程序当前是否正在写入/复制文件方面有点受限。并且实现可以根据OS平台而不同。这可能导致Camel认为该文件未被其他进程锁定并开始使用它。因此,您必须自己调查适合您环境的套件。为了帮助解决这个问题,Camel提供了可以使用的不同readLock选项和doneFileName选项。另请参阅“从其他人直接删除文件的文件夹中使用文件”一节。

为了解决这个问题,我让我的发布商推出了一个“完成”文件。这解决了这个问题

答案 2 :(得分:0)

这样做的一种方法是使用观察者,一旦文件被废弃,它将触发作业并将文件的消耗延迟到相当长的时间,以确保它的上传完成。

from("file-watch://{{ftp.file_input}}?events=CREATE&recursive=false")
                .id("FILE_WATCHER")
                .log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}")
                .delay(20000)
                .to("direct:file_processor");

from("direct:file_processor")
                .id("FILE_DISPATCHER")
                .log("Sending To SFTP Uploader")
                .to("sftp://{{ftp.user}}@{{ftp.host}}:{{ftp.port}}//upload?password={{ftp.password}}&fileName={{file_pattern}}-${date:now:yyyyMMdd-HH:mm}.csv")
                .log("File sent to SFTP");

回复永远不晚。 希望它可以帮助那些在 SFTP 世界最深的令人毛骨悚然的地方挣扎的人......