2014-06-13 23 views
0

我有一個ErrorHandlerDefaultErrorHandler),我已經提供了onRedelivery ref。默認情況下,ErrorHandler重試次數不限。但是,如果存在某種條件(目前由onRedelivery ref確定),我想退出重新遞送循環並執行不同的路線。從onRedelivery觸發新的onException路由

我最初的想法是讓onRedelivery參考拋出和異常,並有一個適當的onException指示適當的路線。但是,我發現RedeliveryErrorHandler捕獲此異常並保持循環。

我也發現,我可以將Exchange.REDELIVERY_EXHAUSTED設置爲true,它將退出重新遞送循環,但不會將我指向我的恢復路線。

有什麼建議嗎?

Edit

所以我發現,如果我在RouteBuilder加上原有的異常類型的異常類型的onException中,我有我的ErrorHandler,如果我設置Exchange.REDELIVERY_EXHAUSTED爲真,原始異常將被拋到RouteBuilder範圍並被onException抓住。但是,我真的更喜歡拋出並捕獲新的異常類型,以便對這種情況進行明確的處理。

Answer

因此,使用retryWhilePeter's建議是巨大的,因爲它可以讓我以編程方式確定何時停止重試。它太。它只有一半的想法。第二部分是將發生故障的交換機發送到新的/不同的路由以進行錯誤處理。這是通過使用DeadLetterChannel而不是DefaultErrorHandler來完成的。

回答

1

使用retryWhile結合deadLetterChannel

public class MyRouteBuilder extends RouteBuilder { 
    @Override 
    public void configure() { 
     errorHandler(deadLetterChannel("direct:special") 
      .retryWhile(method(new MyPredicate()))); 

     from("direct:start") 
      .log("Starting...") 
      .throwException(new Exception("dummy")); 

     from("direct:special") 
      .log("...Special"); 
    } 
} 

public class MyPredicate implements Predicate { 
    @Override 
    public boolean matches(final Exchange exchange) { 
     AtomicInteger counter = exchange.getProperty("myCounter"); 
     if (counter == null) { 
      counter = new AtomicInteger(0); 
      exchange.setProperty("myCounter", counter); 
     } 
     int count = counter.incrementAndGet(); 
     LOG.info("Count = {}", count); 
     return count < 3; // or whatever condition is suitable 
    } 
} 

此打印:

INFO Starting... 
INFO Count = 1 
INFO Count = 2 
INFO Count = 3 
INFO ...Special 
+1

你好彼得,你不應該存儲狀態信息(計數)到比如說myPredicate實例。當需要處理多個異常時,保持Predicate實例無狀態可以避免一些有線錯誤。 –

+0

@WillemJiang感謝您的提示。我相應地更新了我的示例。 –

+0

+1這看起來完全正確。在打分爲正確答案之前,我要測試它是否有效。謝謝! –