简体   繁体   English

Apache Camel-使用多个RouteBuilder进行异常处理

[英]Apache Camel - Exception handling with multiple RouteBuilders

I am using Apache Camel to implement Rest APIs. 我正在使用Apache Camel来实现Rest API。 I've 2 RouteBuilder types defining all the Camel routes, my application needs. 我有2种RouteBuilder类型定义了我的应用程序需要的所有骆驼路线。 All REST endpoints reside in RestRouter , and it frames the execution using CustomRouter . 所有REST端点都驻留在RestRouter ,并使用CustomRouter框架执行。 For example, I've RestRouter to hold my REST routes 例如,我有RestRouter来保存我的REST路由

public class RestRouter extends RouteBuilder
{
    @Override
    public void configure() throws Exception
    {
        rest("/sample")
                .post()
                .route()
                .routeId("postSample")
                .to("direct:validate")
                .to("direct:save")
                .endRest();
    }
}

And another RouteBuilder called CustomRouter to bundle non-REST routes. 另一个名为CustomRouter RouteBuilder捆绑了非REST路由。

public class CustomRouter extends RouteBuilder
{

    @Override
    public void configure() throws Exception
    {
        onException(ValidationException.class)
                .handled(true)
                .setBody(simple("${exchangeProperty[CamelExceptionCaught]}"))
                .to("bean:exceptionHandler?method=constraintViolationHandler")
                .setHeader(Exchange.CONTENT_TYPE, constant(ErrorResponse.class.getName()))
                .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(HttpStatus.SC_BAD_REQUEST));

        validator()
                .type(Sample.class)
                .withBean("sampleValidator");

        from("direct:validate")
                .to("bean-validator://x"); // Runs javax/Hibernate annotated validations

        from("direct:save")
                .routeId("saveSample")
                .inputTypeWithValidate(Sample.class)
                .to("bean:sampleRepository?method=save");
    }
}

Validation bean SampleValidator is a Camel org.apache.camel.spi.Validator which throws org.apache.camel.ValidationException for any violations. 验证bean SampleValidator是一个Camel org.apache.camel.spi.Validator ,它会针对任何违规抛出org.apache.camel.ValidationException

Problem with setup is that Camel doesn't invoke my custom exception handler for ValidationException . 设置问题是Camel不会为ValidationException调用我的自定义异常处理程序。 Validation exception occurs for route saveSample . 路由saveSample发生验证异常。 Here's my finding on how it goes further inside Camel processor types. 这是我在骆驼处理器类型中如何进一步发展的发现。

  • Control goes to RedeliveryErrorHandler's handleException() where it looks for the exception policy. 控制转到RedeliveryErrorHandler's handleException() ,在其中查找异常策略。 Root of failing exchange (ie RestRouter -> postSample ) is expected here to define the exception handler. 交换失败的根源(即RestRouter > postSample )可以在此处定义异常处理程序。
  • Later, Camel goes to failing UnitOfWork (ie to saveSample ) to identify the exception handler. 后来,骆驼转到失败的UnitOfWork (即saveSample )来识别异常处理程序。
  • That means, for below expression, routeId is from CustomRouter and exceptionPolicy is from the RestRouter . 这意味着,对于下面的表达式,routeId来自CustomRouter ,exceptionPolicy来自RestRouter Combination never exists and Camel fails to find the exception processor. 组合永远不存在,并且Camel无法找到异常处理器。

    processor = exceptionPolicy.getErrorHandler(routeId)

In above context, I've following questions 在上述情况下,我一直在追问

  1. Is it a good practice to divide a functionality within multiple RouterBuilder types? 在多个RouterBuilder类型中划分功能是否是一种好习惯?
  2. Shouldn't Camel use current UnitOfWork to resolve the exception policy? 骆驼不应该使用当前的UnitOfWork来解决异常策略吗?
  3. Is there some way Camel can invoke my custom handler, provided different RouteBuilder types? 如果提供不同的RouteBuilder类型,Camel是否可以通过某种方式调用我的自定义处理程序?

Edit I can't move to have a single RouterBuilder . 编辑我不能只拥有一个RouterBuilder

  • One, because I've an Apache Avro object coming in payload for post from another orchestration service, and then transformation to my JPA entities is done via the bean methods, not using Camel's Transformer . 一个,因为我有一个Apache Avro对象进入有效负载以从另一个业务流程服务中发布,然后通过bean方法而不是使用Camel的Transformer来转换到我的JPA实体。 This arrangement doesn't fit with how Camel invokes the Validator (see ContractAdvice ). 这种安排与Camel调用Validator方式不匹配(请参见ContractAdvice )。 ContractAdvice is a CamelInternalProcessorAdvice which applies Transformer (if intype != outtype) and Validator . ContractAdvice是一个CamelInternalProcessorAdvice ,它应用Transformer (如果intype!= outtype)和Validator
  • Second, moving to single RouterBuilder will need me to move Avro-to-Entity logic to a Camel Transformer , and that approach would differ greatly with the way we're doing currently. 其次,转移到单个RouterBuilder将需要我将Avro-to-Entity逻辑转移到Camel Transformer ,并且该方法将与我们目前的工作方式大不相同。 But yes, single RouterBuilder + Transformer + Validator should work. 但是可以,单个RouterBuilder + Transformer + Validator应该可以工作。

Have a look at this example from Camel In Action which demonstrates how to reuse the error-handling across route builders defined in Java DSL. 看一下Camel In Action中的这个示例,该示例演示了如何在Java DSL中定义的路由构建器之间重用错误处理。

BaseRouteBuilder and InboxRouteBuilder and OrderRouteBuilder BaseRouteBuilderInboxRouteBuilderOrderRouteBuilder

You can create a base class where you setup the context-scoped error configuration.Then your RouteBuilder classes are extending this base class and calling calling super.configure to get the common configuration. 您可以创建一个用于设置上下文范围的错误配置的基类。然后,RouteBuilder类将扩展此基类并调用调用super.configure以获得通用配置。

See if it works when you have all the routes in a single RouteBuilder . 在单个RouteBuilder拥有所有路由时,看看它是否RouteBuilder "Global" exception handlers such as yours are not really global as they are applied to all routes built by that specific builder, so I wouldn't expect your onException to be applied to the REST route. 像您这样的“全局”异常处理程序并不是真正的全局处理程序,因为它们应用于该特定生成器构建的所有路由,因此,我不希望将onException应用于REST路由。

Alternatively move the onException in to the REST builder. 或者,将onException移到REST构建器中。 The handler sets HTTP status codes, so on the surface looks like it would be better packaged with REST routes. 该处理程序设置HTTP状态代码,因此从表面上看,最好将其与REST路由打包在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM