Обработка исключений верблюда не работает, если предложение об исключении определено в отдельном классе

Я пытаюсь создать приложение с несколькими верблюжьими маршрутами, которые повторно используют множество общих маршрутов. Поэтому я пытаюсь разделить маршруты в нескольких различных классах 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"));
  }
}
Другие вопросы по тегам