如何使用Apache Camel创建自己的RouteBuilder?

时间:2015-08-04 18:27:32

标签: apache-camel

我试图创建自己的RouteBuilder,但我收到以下错误:

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)

在我的ExceptionBuilder上,我有这段代码:

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

在我的测试中,我有:

 @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;
    }

当我将onException添加到configure中时,为什么它说我必须在任何路由之前定义它?

1 个答案:

答案 0 :(得分:2)

你需要移动它:

from("direct:file").to("mock:http");
致电configure()后,

onException()方法。所以它看起来像这样:

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

然后你的createRouteBuilder()方法应如下所示:

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

我认为它给你一个错误的原因是因为路由预计会包含from()方法调用。

如果您尝试创建常见的异常处理路径,则可能会执行此类操作:

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");
   }
}