调用子路由后出现意外行为

时间:2014-11-20 10:21:28

标签: java apache-camel

我有一个可以调用不同子路由的包装路由(WrapperRoute)。 我的问题是,根据子路由中的异常处理,包装路由在调用后会以不同的方式进行。

当子路由没有错误(NoErrorRoute),没有异常处理(ErrorRouteUnhandled)或处理try-catch块(ErrorRouteTryCatch)中的异常时,WrapperRoute正常工作。这意味着WrapperRoute一直工作到结束并写入最后一个日志。

当子路由具有onException-definition(ErrorRouteHandled)时,只会执行WrapperRoute中的finally块。路线的最后一个日志将不会显示。

为什么在try-catch块之后停止WrapperRoute?

这是我测试此行为的完整代码。在每个测试用例中,我都写了日志。

在测试用例中,handlingTest是WrapperRoute中缺少的最后一个日志。

package test;

import org.apache.camel.CamelContext;
import org.apache.camel.builder.RouteBuilder;
import org.junit.Test;

import at.mic.edis.test.TemplateCamelTest;

public class ExcepionHandlingTest extends TemplateCamelTest{

    @Test
    public void noErrorTest() throws Exception {
        template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:NO-ERROR");
//      2014-11-20 10:35:23,335 [main] INFO  route1 - WRAPPER-Start
//      2014-11-20 10:35:23,350 [main] INFO  route2 - NO-ERROR-ROUTE: run without exception
//      2014-11-20 10:35:23,353 [main] INFO  route1 - WRAPPER: Finally
//      2014-11-20 10:35:23,353 [main] INFO  route1 - WRAPPER: End of wrapper route
    }

    @Test
    public void unhandledTest() throws Exception {
        template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:UNHANDLED");
//      2014-11-20 10:36:34,932 [main] INFO  route1 - WRAPPER-Start
//      2014-11-20 10:36:34,948 [main] INFO  route3 - UNHANDLED: throw exception
//      2014-11-20 10:36:34,952 [main] INFO  route1 - WRAPPER: Catch exception
//      2014-11-20 10:36:34,953 [main] INFO  route1 - WRAPPER: Finally
//      2014-11-20 10:36:34,953 [main] INFO  route1 - WRAPPER: End of wrapper route
    }

    @Test
    public void handledTest() throws Exception {
        template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:HANDLED");
//      2014-11-20 10:37:47,898 [main] INFO  route1 - WRAPPER-Start
//      2014-11-20 10:37:47,913 [main] INFO  route4 - HANDLED: throw exception
//      2014-11-20 10:37:47,916 [main] INFO  route4 - HANDLED: Exception handled
//      2014-11-20 10:37:47,919 [main] INFO  route1 - WRAPPER: Finally
    }

    @Test
    public void tryCatchTest() throws Exception {
        template.sendBodyAndHeader("direct:WRAPPER", "BODY", "SUBROUTE", "direct:TRY-CATCH");
//      2014-11-20 10:38:55,871 [main] INFO  route1 - WRAPPER-Start
//      2014-11-20 10:38:55,887 [main] INFO  route5 - TRY-CATCH: throw exception
//      2014-11-20 10:38:55,889 [main] INFO  route5 - TRY-CATCH: exception caught
//      2014-11-20 10:38:55,890 [main] INFO  route5 - TRY-CATCH: finish
//      2014-11-20 10:38:55,891 [main] INFO  route1 - WRAPPER: Finally
//      2014-11-20 10:38:55,892 [main] INFO  route1 - WRAPPER: End of wrapper route
    }

    @Override
    public RouteBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                WrapperRoute wrapper = new WrapperRoute();
                NoErrorRoute noError = new NoErrorRoute();
                ErrorRouteUnhandled unhandled = new ErrorRouteUnhandled();
                ErrorRouteHandled handled = new ErrorRouteHandled();
                ErrorRouteTryCatch tryCatch = new ErrorRouteTryCatch();

                CamelContext context = getContext();
                context.addRoutes(wrapper);
                context.addRoutes(noError);
                context.addRoutes(unhandled);
                context.addRoutes(handled);
                context.addRoutes(tryCatch);
            }
        };
    }
}

WrapperRoute:

package test;

import org.apache.camel.builder.RouteBuilder;

import at.mic.edis.all.scheduler.processor.WrappedRoutingSlipBean;

public class WrapperRoute extends RouteBuilder{

    @Override
    public void configure() throws Exception {
        onException(Exception.class)
            .handled(true)
            .log("WRAPPER: exception handler");

        from("direct:WRAPPER")
            .log("WRAPPER-Start")
            .doTry()
                .recipientList().method(WrappedEndpoint.class.getName())                
                .end()
            .doCatch(Exception.class)
                .log("WRAPPER: Catch exception")
            .doFinally()
                .log("WRAPPER: Finally")
            .end()
            .log("WRAPPER: End of wrapper route");
    }
}

WrapperEndpoint:

package test;

import org.apache.camel.Exchange;
import org.apache.camel.Handler;

public class WrappedEndpoint {

    @Handler
    public Object process(Exchange exchange) throws Exception {
        //Reads the direct endpoint for the subroute from the header
        String endpoint = (String) exchange.getIn().getHeader("SUBROUTE");
        return endpoint;
    }
}

NoErrorRoute:

package test;

import org.apache.camel.builder.RouteBuilder;

public class NoErrorRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("direct:NO-ERROR")
            .log("NO-ERROR-ROUTE: run without exception");
    }
}

ErrorRouteUnhandled:

package test;

import org.apache.camel.builder.RouteBuilder;

public class ErrorRouteUnhandled extends RouteBuilder{

    @Override
    public void configure() throws Exception {
        from("direct:UNHANDLED")
            .log("UNHANDLED: throw exception")
            .throwException(new Exception("Exception"));
    }
}

ErrorRouteHandled:

package test;

import org.apache.camel.builder.RouteBuilder;

public class ErrorRouteHandled extends RouteBuilder{

    @Override
    public void configure() throws Exception {
        onException(Exception.class)
            .handled(true)
            .log("HANDLED: Exception handled");

        from("direct:HANDLED")
            .log("HANDLED: throw exception")
            .throwException(new Exception("Exception"));
    }
}

ErrorRouteTryCatch:

package test;

import org.apache.camel.builder.RouteBuilder;

public class ErrorRouteTryCatch extends RouteBuilder{

    @Override
    public void configure() throws Exception {
        from("direct:TRY-CATCH")
            .log("TRY-CATCH: throw exception")
            .doTry()
                .throwException(new Exception("Exception"))
            .doCatch(Exception.class)
                .log("TRY-CATCH: exception caught")
            .end()
            .log("TRY-CATCH: finish");
    }
}

修改

可以将属性 Exchange.ERRORHANDLER_HANDLED (= CamelErrorHandlerHandled )设置为false。这与未定义错误处理或在onException-block中设置 .handled(false)时属性的外观相同。

我从WrapperRoute修改了doFinally() - 块,现在一切正常:

...
.doFinally()
    .process(new Processor() {
        @Override
        public void process(Exchange exchange) throws Exception {
            // Print all properties
            for (Entry<String, Object>  entry: exchange.getProperties().entrySet()){
                System.out.println(entry.getKey() + " | " + entry.getValue());
            }
            if (exchange.getProperty(Exchange.ERRORHANDLER_HANDLED)!=null){
                System.out.println("Set error handler property to false");
                exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, false);
            }
        }
    })
    .log("WRAPPER: Finally")
.end()
...

1 个答案:

答案 0 :(得分:0)

handled中将true设置为false(=没有返回客户端失败)到ErrorRouteHandled,再次显示最后一个日志条目:

onException(Exception.class)
    .handled(false) // changed from true to false
    .log("HANDLED: Exception handled");

如果设置为true,则只会处理doFinally()部分中的一个步骤。

实际上,我不知道,如果这是一个错误或它是否按设计工作。

相关问题