Igor
Igor

Reputation: 1464

How to create my own RouteBuilder with Apache Camel?

I'm trying to create my own RouteBuilder but I'm getting the following error:

java.lang.IllegalArgumentException: onException must be defined before any routes in the RouteBuilder
    at org.apache.camel.builder.RouteBuilder.onException(RouteBuilder.java:214)
    at com.mdw360.ttt.mongo.fab.route.ExceptionBuilder.configure(ExceptionBuilder.java:18)
    at org.apache.camel.builder.RouteBuilder.checkInitialized(RouteBuilder.java:322)
    at org.apache.camel.builder.RouteBuilder.configureRoutes(RouteBuilder.java:276)
    at org.apache.camel.builder.RouteBuilder.addRoutesToCamelContext(RouteBuilder.java:262)
    at org.apache.camel.impl.DefaultCamelContext.addRoutes(DefaultCamelContext.java:679)
    at org.apache.camel.test.junit4.CamelTestSupport.doSetUp(CamelTestSupport.java:302)
    at org.apache.camel.test.junit4.CamelTestSupport.setUp(CamelTestSupport.java:217)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.rules.TestWatcher$1.evaluate(TestWatcher.java:55)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

On my ExceptionBuilder I have this code:

public class ExceptionBuilder extends RouteBuilder{
    @Override
    public void configure() throws Exception {
        ExceptionProcessor exceptionProcessor = new ExceptionProcessor();
        onException(Exception.class).process(exceptionProcessor);
    }
}

And on my test I have that:

 @Test
    public void testExceptionWhileRouting() throws Exception {
        getMockEndpoint("mock:http").expectedBodiesReceived("Camel rocks");

        getMockEndpoint("mock:http").whenAnyExchangeReceived(new Processor() {
            public void process(Exchange exchange) throws Exception {
                System.out.println("ERROR");
                exchange.setException(new ConnectException("Simulated connection error"));
            }
        });

        template.sendBody("direct:file", "Camel rocks");

        assertMockEndpointsSatisfied();
    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        ExceptionBuilder routeBuilder = new ExceptionBuilder();
        routeBuilder.from("direct:file").to("mock:http");
        return routeBuilder;
    }

As I'm adding the onException into the configure, why it's saying that I must define it before any route?

Upvotes: 1

Views: 2993

Answers (1)

mdnghtblue
mdnghtblue

Reputation: 1117

You need to move this:

from("direct:file").to("mock:http");

to the configure() method, after you call onException(). So it looks like this:

public class ExceptionBuilder extends RouteBuilder{
   @Override
   public void configure() throws Exception {
       onException(Exception.class).process(new ExceptionProcessor());
       from("direct:file").to("mock:http");
   }
}

Then your createRouteBuilder() method should look like this:

@Override
protected RouteBuilder createRouteBuilder() {
    return new ExceptionBuilder();
}

I think the reason it's giving you an error is because routes are expected to contain the from() method call.


You might be able to do something like this if you're trying to create a common exception handling route:

public class ExceptionBuilder extends RouteBuilder{
   @Override
   public void configure() throws Exception {
       from("direct:onException").process(new ExceptionProcessor());
   }
}

public class TestRouteBuilder extends RouteBuilder{
   @Override
   public void configure() throws Exception {
       onException(Exception.class).to("direct:onException");
       from("direct:start").to("mock:end");
   }
}

Upvotes: 2

Related Questions