Apache camel 多次使用同一URI返回空正文

Apache camel 多次使用同一URI返回空正文,apache-camel,Apache Camel,我有两条路线。第一个路由使用轮询来检查文件是否存在。第二个路由使用同一uri上的轮询来读取和处理文件。第一条路线通过SEDA队列调用第二条路线,如下所示: public void configure() throws Exception { String myFile = "file://myDir?fileName=MyFile.zip&delete=false&readLock=none"; from("direct:test") .pollE

我有两条路线。第一个路由使用轮询来检查文件是否存在。第二个路由使用同一uri上的轮询来读取和处理文件。第一条路线通过SEDA队列调用第二条路线,如下所示:

public void configure() throws Exception {
    String myFile = "file://myDir?fileName=MyFile.zip&delete=false&readLock=none";

    from("direct:test")
       .pollEnrich(myFile, 10000)
    .to("seda:myQueue")
    ;

    from("seda:myQueue")
        .pollEnrich(myFile, 10000)
        .log("Do something with the body")
    ;
}
目前,如果我执行第一个路由,poll-enrich会找到一个文件,但是当第二个路由中的poll-enrich执行时,它会返回一个null体。如果我只是单独执行第二个路由,它会正确地检索文件

为什么第二次轮询返回null,文件是否已锁定?(我希望结合使用noop、、和delete=false可以防止任何锁定)

《骆驼》认为第二次投票是重复的,因此过滤掉了吗?(我已经尝试实现自己的幂等存储库,在contains()上返回false,但第二个pollRich仍然返回null)

您可能想知道为什么我要尝试从两个路由进行充实,第一个路由必须检查是否存在大量文件,只有当所有文件都存在时(即PollRich不返回null),第二个路由才能开始处理它们

有没有其他我可以使用的方法?我在想,也许我需要创建一个bean,通过URI检索文件并将其作为主体返回


我使用的是骆驼2.11.0

有什么具体的原因可以解释为什么你不使用一条路线


我不明白你为什么要用两条路线。文件组件可以检查文件是否存在,如果存在,则将其拉出。如果您担心要记住文件以避免重复,那么可以使用幂等存储库。至少,基于您的问题,我认为您不需要使用两条路由和content enricher EIP使逻辑复杂化。

第二条路由返回空值,因为文件已在第一条路由中被使用……如果您只是在所有文件都存在的情况下查找信号消息,然后将文件使用者与和(可能是)一起使用,以避免在内存中携带大量有效负载等。

我意识到这是一个老话题,但我也遇到了类似的问题。
我建议您尝试以下选项:

noop=true
你已经有了,而且

idempotent=false
要告诉驼峰
Camel
处理同一文件两次是
OK

测试后更新:

实际上,我使用上面建议的两种设置对此进行了测试,它有时会工作,但在中等负载下,它会失败,也就是说,对于某些交换返回null body,尽管不是全部


文档表明设置
noop=true
会自动设置
幂等元=true
,因此我不确定在这种情况下是否遵守幂等元设置。

请尝试使用strategyMethodAllowNull=“true”进行PollRich。默认情况下,此值为false。如果为false,聚合策略将查找现有的Exchange主体,以聚合从文件返回的内容。
当我们使strategyMethodAllowNull=“true”时,现有主体被视为null。因此,每次文件的内容都会被设置到当前的exchange正文中,正如您可能已经了解到的那样,这并不像预期的那样有效

noop=true&idempotent=false
我的猜测是,Camel忽略了
idempotent=false
,并使用MemoryMessageIdRepository的实例。要解决此问题,可以将文件端点配置为使用自定义幂等元repo:

noop=true&idempotentRepository=#myRepo
并在注册表或spring上下文中注册自定义存储库:

@Component("myRepo")
public class MyRepo implements IdempotentRepository {
    @Override
    public boolean contains(Object o) {
        return false;
    }
    ...
}

正如我提到的,如果所有文件都存在,我只想执行第二个路由。这些文件很大(大约2gb),所以我不想复制其中的4个文件,然后发现第5个文件丢失了。我在第一个路由中有一些其他逻辑,报告丢失的文件等。第二个路由如何知道文件已被使用?邮件交换上是否设置了标题?我在文件://uri上使用noop=true,因此如果有某种方法可以告诉camel该文件尚未被使用,那么exchange有自己的ID以避免重复