Apache Camel如何用于监控文件变化?

20

我想要监视给定目录中所有文件的更改,例如更新的时间戳。使用文件组件似乎是Camel自然的用例,但我似乎找不到配置此行为的方法。

像这样的uri:

file:/some/directory

这将消耗所提供目录中的文件,但会删除它们。

像这样的uri:

file:/some/directory?noop=true

当文件被添加或路由启动时,它只会被消费一次。

令人惊讶的是,没有类似以下选项:

consumeOnChange=true

有没有一种简单的方法来监视文件更改并在使用后不删除该文件?

5个回答

26

您可以通过设置idempotentKey告诉Camel如何判断文件是否已更改,例如,如果文件大小或时间戳等发生变化。

有关详细信息,请参阅Camel文件文档:https://camel.apache.org/components/latest/file-component.html

请查看“避免多次读取相同文件(幂等消费者)”部分,并了解有关幂等和idempotentKey的信息。

因此,类似于:

from("file:/somedir?noop=true&idempotentKey=${file:name}-${file:size}")

或者

from("file:/somedir?noop=true&idempotentKey=${file:name}-${file:modified}")
你可以在这里阅读有关各种${file:xxx}令牌的信息:http://camel.apache.org/file-language.html

谢谢你抽出时间回复,Claus。我非常感激你在Camel方面的工作。在下一次会议前我试了20分钟,但好像无法让它正常运行。我尝试了size和modified,但都没有成功。现在我明白noop默认将幂等变为true,这很合理。当我有更多时间时,我会继续查看文件标记,但我期望添加${file:name}-${file:modified}后它能开始捕获修改的文件。还有别的需要注意的吗?再次感谢! - Janx
啊,我刚想起来最近修复了一个关于幂等键(idempotentKey)的 bug,尽管是针对 FTP 报告的。它的编号是 CAMEL-6936。所以这个问题将在即将发布的版本中得到解决。很抱歉造成了不便。 - Claus Ibsen
不用担心 - 所以您发布的第二个URL应该在未来版本中有效吗? SNAPSHOT构件是否在任何地方发布? - Janx
嗯 - 我尝试了最新的2.12.2-SNAPSHOT和2.13-SNAPSHOT,但没有成功。为了明确起见,我的URL现在看起来像“? noop = true&idempotentKey = $ {file:name} - $ {file:modified} ”也许它还没有被构建进去? - Janx
啊,谢谢CAMEL-6936的第一个修复,但它并没有完全解决问题。我已经再次修复了这个问题。所以任何未来的SNAPSHOT更新都应该包含这个修复。 - Claus Ibsen
显示剩余2条评论

2

noop设置为true会导致Camel设置idempotent=true,尽管默认情况下idempotentfalse

监视文件的最简单解决方案是:

.from("file:path?noop=true&idempotent=false&delay=60s")

每分钟监控给定目录中所有文件的更改。 此内容可在Camel文档中找到:http://camel.apache.org/file2.html

1

我遇到了同样的问题,即想复制更新的文件(以及新文件)。以下是我的配置:

public static void main(String[] a) throws Exception {

    CamelContext cc = new DefaultCamelContext();

    cc.addRoutes(createRouteBuilder());

    cc.start();

    Thread.sleep(10 * 60 * 1000);

    cc.stop();
}


protected static RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from("file://D:/Production"
                    + "?idempotent=true"
                    + "&idempotentKey=${file:name}-${file:size}"
                    + "&include=.*.log"
                    + "&noop=true"
                    + "&readLock=changed")

            .to("file://D:/LogRepository");
        }
    };
}

我的测试步骤:

  1. 运行程序,它会将一些.log文件从D:/Production复制到D:/LogRepository,然后继续轮询D:/Production目录
  2. 我打开了一个已经从D:/Production复制过来的日志,比如A.log(因为noop=true,所以没有移动任何文件),并用编辑工具进行了编辑。这使得文件大小翻了一倍,并保存。

此时我认为Camel应该再次复制那个特定的文件,因为它的大小已经修改,在我的路由定义中我使用了“idempotent=true&idempotentKey=${file:name}-${file:size}&readLock=changed”。但camel忽略了这个文件。 当我使用TRACE进行日志记录时,它说“Skipping as file is already in progress...”,但是当我编辑并保存文件时,我在D:/Production目录中没有找到任何锁定文件。

我还检查了一下,如果我从外部替换D:/Production目录中的A.log(同名但更大),camel仍然会忽略这个文件。

但是我发现,如果我删除noop=true选项,一切都按预期工作

我错过了什么吗?


1
你有没有尝试将这个问题作为一个单独的问题发布? - JustBlossom
有没有任何标志可以在监视文件夹中的文件被删除而不是修改时触发路由? - Gagan

1

我认为Camel不支持该特定功能,但通过现有选项,您可以想出一个类似的解决方案来监视目录。

您需要设置一个小的延迟值来检查目录,并维护已读取文件的存储库。根据您如何配置存储库(按大小、按文件名、按混合方式...),此解决方案将能够向您提供有关新文件和修改文件的信息。作为一个警告,它会经常消耗目录中的文件。

也许您可以使用与Camel不同的其他解决方案,如Apache Commons VFS2(我写了一篇关于如何将其用于此场景的说明:WatchService locks some files?


说得好。这是务实的答案 :-) 在我的情况下(一个Camel FTP客户端,一旦文件可用就会发送文件),我添加了一个JMS队列,其中文件生产者发布一个消息,唤醒FTP客户端。 - Marco Faustinelli

1
如果你想监控camel中的文件更改,请使用file-watch组件。
示例->递归监视所有事件(文件创建、文件删除、文件修改):
from("file-watch://some-directory")
.log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}");

你可以在这里查看完整的文档: Camel文件监视组件

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接