簡體   English   中英

Apache 駱駝聚合路由異常

[英]Apache Camel aggregate route with exception

我想將 Apache Camel 並行多播用於 3 條路由並聚合(並等待)其中 2 條,同時單獨留下第 3 條 go(第 3 條不應阻止前兩條)。 我還需要在“所有”情況下處理這兩個,這意味着如果其中一個失敗(例如,在處理過程中拋出異常),它也應該被聚合。

根據我從 Camel 文檔中了解到的情況,只要您不指定 stopOnException,該行為就應該是“默認的”。 但是發生的是異常交換永遠不會進入我的聚合策略。 有點奇怪的是,即使有 completionSize(2),聚合后面的處理器也會被執行。

所以我的問題是:聚合后的路由怎么可能繼續而不處理 AggregationStrategy 中的交換? 以及如何正確解決我的案子? 請注意 doing.to("direct:sync") 不是這種情況,因為此異常可能會從完全超出路由的多播聚合部分的路由中拋出。

下面是示例代碼(ExceptionThrowingProcessor 拋出 MyException,PropertySetterProcessor 不重要):

CamelContext context = new DefaultCamelContext();
RouteBuilder builder = new RouteBuilder() {
    @Override
    public void configure() throws Exception {
    }
};

builder.onException(MyException.class)
        .process(new PropertySetterProcessor("a", "onException"))
        .handled(true);

builder.from("direct:input")
        .process(new PropertySetterProcessor("a", "before-multicast"))
        .multicast()
        .parallelProcessing()
        .shareUnitOfWork()
        .to("direct:part1", "direct:part2", "direct:part3")

builder.from("direct:part1")
        .process(new PropertySetterProcessor("a", "part1"))
        .to("direct:sync");

builder.from("direct:part2")
        .process(new PropertySetterProcessor("a", "part2"))
        .process(new ExceptionThrowingProcessor("oops")) // throws MyException
        .to("direct:sync");

builder.from("direct:part3")
        .process(new PropertySetterProcessor("a", "part3"));
// don't want this to be aggregated within direct:sync

builder.from("direct:sync")
        .aggregate(new TestAggregationStrategy())
        // strategy.aggregate is called only once (from part1) but not from part2 :(
        .constant(true)
        .completionSize(2)
        .process(new PropertySetterProcessor("a", "after-aggregation"));

context.addRoutes(builder);
context.start();

ProducerTemplate template = context.createProducerTemplate();
template.send("direct:input", new DefaultExchange(context, ExchangePattern.InOut));

我有一個可能的解決方案:

  1. onException()結束時continued(true)
  2. 在異常處理器中,添加一些 prop 到 exchange 中,比如skipNextStep = true
  3. 在異常處理程序的末尾,添加您想要的聚合體
  4. .choice().when(simple("${exchangeProperty.skipNextStep == null}")).end()包圍你的路線的 rest ,這樣如果它沒有設置,意味着前面的步驟工作,處理; 如果不是,則什么都不做並返回相同的交換。 所以可以跳過split路由的rest和go直接聚合。

不是完美的解決方案,而是解決方法。

我認為拆分部分可以添加when().skipRestAndAggregate()之類的關鍵字,以便它跳過路由和短路的 rest。

在onException塊上用continue(true)替換處理(true)。 有關詳細信息,請參閱此http://camel.apache.org/exception-clause.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM