masT
masT

Reputation: 850

Apache Camel - Exception handling with multiple RouteBuilders

I am using Apache Camel to implement Rest APIs. I've 2 RouteBuilder types defining all the Camel routes, my application needs. All REST endpoints reside in RestRouter, and it frames the execution using CustomRouter. For example, I've RestRouter to hold my REST routes

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.

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.

Problem with setup is that Camel doesn't invoke my custom exception handler for ValidationException. Validation exception occurs for route saveSample. Here's my finding on how it goes further inside Camel processor types.

In above context, I've following questions

  1. Is it a good practice to divide a functionality within multiple RouterBuilder types?
  2. Shouldn't Camel use current UnitOfWork to resolve the exception policy?
  3. Is there some way Camel can invoke my custom handler, provided different RouteBuilder types?

Edit I can't move to have a single RouterBuilder.

Upvotes: 1

Views: 6926

Answers (2)

batwad
batwad

Reputation: 3665

See if it works when you have all the routes in a single 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.

Alternatively move the onException in to the REST builder. The handler sets HTTP status codes, so on the surface looks like it would be better packaged with REST routes.

Upvotes: 0

ltsallas
ltsallas

Reputation: 1948

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.

BaseRouteBuilder and InboxRouteBuilder and 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.

Upvotes: 1

Related Questions