Обработка исключений верблюда не работает, если предложение об исключении определено в отдельном классе
Я пытаюсь создать приложение с несколькими верблюжьими маршрутами, которые повторно используют множество общих маршрутов. Поэтому я пытаюсь разделить маршруты в нескольких различных классах Route Builder, а затем соединить маршруты, где это необходимо.
Например, все маршруты, относящиеся к отправке электронных писем, переходят в класс EmailRouteBuilder, а все маршруты, связанные с определенной очередью JMS, переходят в класс MyQueueRouteBuilder. Я предполагаю, что это должно быть хорошо, так как Верблюд не различает классы, а только ищет определения маршрутов.
Кроме того, я также группирую несколько маршрутов обработки исключений в отдельный ExceptionHandlingRouteBuilder.
Я также соединяю все разные классы, определяя контекст верблюда в Spring следующим образом:
<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>
Мои исключения RouteBuilder содержит много исключений, таких как -
onException(ConnectException.class)
.routeId("connectExceptionEP")
.handled(true)
.log("Caught Exception: ")
.to("direct:gracefulExit");
..
..
..
Тем не менее, похоже, что существует проблема с исключениями, которые определены в другом классе, или, в этом отношении, определены отдельно от определения основного маршрута.
Я проверял это в журналах, просматривая загружаемые маршруты (с помощью routeId), а также проверяя, когда возникает исключение.
Кроме того, для дальнейшего подтверждения я выбрал маршрут обработки исключений http Connect и поместил его прямо в httpRouteBuilder и вот! обработка исключений теперь включается просто отлично для этого исключения.
Я что-то здесь упускаю, чтобы заставить работать все исключения, будучи хорошо определенным в своем собственном классе.?
Я использую Apache Camel 2.9.0, но я проверил то же поведение в 2.8.3.
Спасибо ананд
2 ответа
Правильно, предложения onException() применяются только к определениям текущего маршрута RouteBuilder...
Тем не менее, вы можете повторно использовать эти определения, если все ваши RouteBuilders расширяют ExceptionRouteBuilder и вызывают super.configure()... что-то вроде этого
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");
}
}
или даже просто иметь статический метод в классе ExceptionBuilder для настройки предложений для данного экземпляра RouteBuilder
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");
}
}
Основываясь на принятом ответе, я нашел более понятный способ реализации обработки исключений, поэтому вам не нужно вызывать super.configure() на каждом маршруте. Просто вызовите метод, который обрабатывает onException в конструкторе базового класса.
//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"));
}
}