Обработка исключений верблюда не работает, если предложение об исключении определено в отдельном классе - PullRequest
7 голосов
/ 15 февраля 2012

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

11 голосов
/ 15 февраля 2012

правильно, предложения onException () применяются только к текущим определениям маршрутов RouteBuilder ...

при этом вы можете повторно использовать эти определения, если все ваши RouteBuilder расширяют 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");
    }  
}
0 голосов
/ 09 сентября 2017

Основываясь на принятом ответе, я нашел более чистый способ реализации обработки исключений, поэтому вам не нужно вызывать 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"));
  }
}
...