apache camel幂等消费者密钥删除

时间:2016-04-25 15:02:27

标签: apache-camel

我有如下设置。

我遇到的问题是,在seda中使用OnException组件时,如果抛出异常(在下面说明),则不会删除Idempotent存储库中的密钥。当我更改为在direct中使用OnException时,密钥将从缓存中删除。在两次试验中,电子邮件也正确发送。

我的疑问是:

  1. 为什么在seda中使用OnException时,密钥未从存储库缓存中删除?
  2. seda
  3. 中使用OnException是否存在问题

    这是路线:

    MyRouteClass1

    onException(Exception.class)
      .setHeader("subjectText", simple("failure email!"))
      .to("seda:notifySupportOnFailure")
      .end();
    
    from("direct:findWorkItems")
        .bean(someService, "findWorkItems")
        .split(body())
          .throttle(1).timePeriodMillis(5000L)
          .to("direct:handleWorkItem")
          .choice().when(header("resultId").isGreaterThan(0))
          .bean(someService, "updateWorkItemToHandled")
          .end();
    
    from("direct:handleWorkItem")
        .idempotentConsumer(simple("${body.workItemId}"), duplicatesRepo)
        .bean(someService, "handleWorkItem")  // e.g. exception would be thrown within here
        .setHeader("resultId", body())
        .end();
    

    MyRouteClass2

    from("seda:notifySupportOnFailure")
      .setHeader("from", simple("sender@mail.com"))
      .setHeader("to", simple("recipient@mail.com"))
      .setBody(simple("Failure:\n ${exception.message} \n\ndetail: \n${body}"))
      .to("smtp://localhost")
      .log("Failure email now sent.")
      .end();
    

    我还尝试了另一种解决方法。我修改了 onException 子句,如下所示。这确实允许在抛出异常时从存储库中删除密钥。我想知道这是否是一种正确的方法?

    onException(Exception.class)
      .setHeader("subjectText", simple("failure email!"))
      .multicast().to("seda:notifySupportOnFailure").end()
      .end();
    

1 个答案:

答案 0 :(得分:0)

解决方法是将idempotentConsumer调用放在父路径“findWorkItems”中,并将其上的completionEager标志设置为true。

onException(Exception.class)
  .setHeader("subjectText", simple("failure email!"))
  .to("seda:notifySupportOnFailure")
  .end();

from("direct:findWorkItems")
    .idempotentConsumer(simple("${body.workItemId}"), duplicatesRepo).completionEager(true)
    .bean(someService, "findWorkItems")
    .split(body())
      .throttle(1).timePeriodMillis(5000L)
      .to("direct:handleWorkItem")
      .choice().when(header("resultId").isGreaterThan(0))
      .bean(someService, "updateWorkItemToHandled")
      .end();

from("direct:handleWorkItem")
    .bean(someService, "handleWorkItem")  // e.g. exception would be thrown within here
    .setHeader("resultId", body())
    .end();