[英]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.
这是我在骆驼处理器类型中如何进一步发展的发现。
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 )可以在此处定义异常处理程序。 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 在上述情况下,我一直在追问
RouterBuilder
types? RouterBuilder
类型中划分功能是否是一种好习惯? UnitOfWork
to resolve the exception policy? UnitOfWork
来解决异常策略吗? RouteBuilder
types? RouteBuilder
类型,Camel是否可以通过某种方式调用我的自定义处理程序? Edit I can't move to have a single RouterBuilder
. 编辑我不能只拥有一个
RouterBuilder
。
Transformer
. Transformer
来转换到我的JPA实体。 This arrangement doesn't fit with how Camel invokes the Validator
(see ContractAdvice
). Validator
方式不匹配(请参见ContractAdvice
)。 ContractAdvice is a CamelInternalProcessorAdvice
which applies Transformer
(if intype != outtype) and Validator
. CamelInternalProcessorAdvice
,它应用Transformer
(如果intype!= outtype)和Validator
。 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. 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 BaseRouteBuilder和InboxRouteBuilder和OrderRouteBuilder
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.