2012-02-14 15 views
7

Tôi đang cố gắng xây dựng một ứng dụng với một số tuyến đường lạc đà sử dụng lại nhiều tuyến đường chung trong nội bộ. Do đó, tôi đang cố gắng tách biệt các tuyến đường trong một số lớp Route Builder khác nhau và sau đó kết nối các tuyến đường khi cần.Xử lý ngoại lệ Camel không hoạt động nếu mệnh đề ngoại lệ được xác định trong một lớp riêng biệt

Ví dụ: tất cả các tuyến liên quan đến việc gửi email đi vào lớp EmailRouteBuilder và tất cả các tuyến xử lý một Hàng đợi JMS cụ thể sẽ chuyển sang lớp MyQueueRouteBuilder. Tôi cho rằng điều này sẽ ổn thôi vì Camel không phân biệt giữa các lớp và chỉ tìm đường định nghĩa.

Ngoài ra, tôi cũng đang nhóm một số tuyến xử lý ngoại lệ thành một ExceptionHandlingRouteBuilder riêng biệt.

Tôi cũng kết nối tất cả các lớp khác nhau với nhau bằng cách xác định bối cảnh con lạc đà trong mùa xuân như vậy -

<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring"> 
    <propertyPlaceholder id="properties" location="classpath:${env}/autoimport.properties"/> 
    <!-- Common Routes --> 
    <routeBuilder ref="emailRouteBuilder" /> 
    <routeBuilder ref="myQueueRouteBuilder" /> 
    <routeBuilder ref="httpRouteBuilder" /> 
    <routeBuilder ref="exceptionsRouteBuilder" /> 
    <routeBuilder ref="customer1RouteBuilder" /> 
    <routeBuilder ref="customer2RouteBuilder" /> 

</camelContext> 

My exceptionsRouteBuilder chứa nhiều điều khoản ngoại lệ như -

onException(ConnectException.class) 
      .routeId("connectExceptionEP") 
      .handled(true) 
      .log("Caught Exception: ") 
      .to("direct:gracefulExit"); 

.. 
.. 
.. 

Tuy nhiên, có vẻ như có một vấn đề với các ngoại lệ được định nghĩa trong một lớp khác, hoặc cho vấn đề đó, được định nghĩa riêng biệt ngoài định nghĩa tuyến đường chính.

Tôi đã xác minh điều này trong nhật ký bằng cách tìm kiếm các tuyến đường đang được khởi động (bởi routeId) và cũng kiểm tra khi một ngoại lệ được ném.

Ngoài ra, để xác nhận thêm, tôi đã sử dụng đường kết nối http xử lý ngoại lệ kết nối và đặt trực tiếp vào httpRouteBuilder và lo ..! , xử lý ngoại lệ bây giờ đá chỉ phạt cho ngoại lệ này ..

Tôi có thiếu thứ gì đó ở đây để có được tất cả ngoại lệ khi làm việc trong khi được định nghĩa độc đáo trong lớp riêng của nó. ?

Tôi đang sử dụng Apache Camel 2.9.0, nhưng tôi đã xác minh hành vi tương tự cũng trong 2.8.3.

Cảm ơn, Anand

Trả lời

11

chính xác, onException() khoản chỉ áp dụng cho các định nghĩa tuyến đường hiện tại RouteBuilder của ...

những gì đã nói, bạn có thể tái sử dụng những định nghĩa bằng việc có tất cả RouteBuilders của bạn kéo dài tuổi ExceptionRouteBuilder và gọi super.configure() ... cái gì đó như

public class MyRouteBuilder extends ExceptionRouteBuilder { 
    @Override 
    public void configure() throws Exception { 
     super.configure(); 
     from("direct:start").throwException(new Exception("error")); 
    } 
} 
... 
public class ExceptionRouteBuilder implements RouteBuilder { 
    @Override 
    public void configure() throws Exception { 
     onException(Exception.class).handled(true).to("mock:error"); 
    } 
} 

hoặc thậm chí chỉ có một phương pháp tĩnh này trong một lớp ExceptionBuilder để thiết lập các điều khoản cho một RouteBuilder dụ cho

public class MyRouteBuilder extends RouteBuilder { 
    @Override 
    public void configure() throws Exception { 
     ExceptionBuilder.setup(this); 
     from("direct:start").throwException(new Exception("error")); 
    } 
} 
... 
public class ExceptionBuilder { 
    public static void setup(RouteBuilder routeBuilder) { 
     routeBuilder.onException(Exception.class).handled(true).to("mock:error"); 
    } 
} 
+0

nice .. thanks for that ... –

+0

Mẹo tuyệt vời! Đã đấu tranh để quấn đầu của tôi xung quanh lý do tại sao onException đã không được kích hoạt. –

0

Dựa trên câu trả lời được chấp nhận, tôi đã tìm thấy cách dọn dẹp ngoại lệ hiệu quả hơn, vì vậy bạn không phải gọi super.configure() trong mọi tuyến đường. Chỉ cần gọi một phương thức xử lý onException trong hàm khởi tạo của lớp cơ sở.

//Base class that does exception handling 
public abstracExceptionRouteBuildert class BaseAbstractRoute extends RouteBuilder { 
    protected BaseAbstractRoute() { 
    handleException(); 
    } 

    private void handleException() { 
    onException(Exception.class).handled(true).to("mock:error"); 
    } 
} 

//Extend the base class 
public class MyRouteBuilder extends BaseAbstractRoute { 
    @Override 
    public void configure() throws Exception { 
    from("direct:start").throwException(new Exception("error")); 
    } 
}