拆分EIP

时间:2015-12-17 16:35:01

标签: java exception-handling apache-camel

我将CSV文件输入与更大的系统集成,我想将其设置为使得CSV的各个行(由split拆分)不会正确解析将发送到医院队列,所有其他工作线将转换为对象并聚合到列表中。但是,我无法获取在split内抛出异常的消息以在其他位置路由,并且在分割结束时不会出现在聚合器中。为了简化它,我编写了一个单元测试,在分裂中抛出一个异常,并且我试图让它工作。我将字符串1\n2\n3\n拆分为三条消息,在其中一条消息上抛出异常,并在结尾处连接剩余的字符串。

public void configure() throws Exception {

    onException(Exception.class)
        .handled(true)
        .to("log:dead?level=ERROR");

    from("direct:test")
        .split(body().tokenize("\n"), new MyAggregationStrategy())
            .process(new ThrowMyException())
        .end()
        .to("mock:out");
}

@Test
public void test() throws InterruptedException {

    MockEndpoint out = getMockEndpoint("mock:out");
    out.expectedMessageCount(1);

    template.sendBody("direct:test", "1\n2\n3\n");

    assertMockEndpointsSatisfied();
}

ThrowMyException Controller:抛出异常

@Override
public void process(Exchange exchange) throws Exception {
    System.out.println("[" + exchange.getIn().getBody() + "]");
    if (exchange.getIn().getBody(String.class).trim().contentEquals("2")) {
        System.out.println("Throwing exception");
        throw new Exception();
    }
}

MyAggregationStrategy:只是连接字符串

@Override
public Exchange aggregate(Exchange oldExchange, Exchange newExchange) {
    if (oldExchange == null) {
        return newExchange;
    }
    oldExchange.getIn().setBody(
            oldExchange.getIn().getBody(String.class) + 
            newExchange.getIn().getBody(String.class));
    System.out.println(oldExchange.getIn().getBody());
    return oldExchange;
}

我期望的是onException处理程序,因为我已经表明它将处理异常(handled(true)),它将消耗控制器在获取异常时抛出的异常消息' 2',我将得到聚合器打印出的结果13。我确实得到onException处理程序打印出的行:

  

ERROR dead - Exchange [ExchangePattern:InOnly,BodyType:String,Body:2]

但聚合器然后返回' 123'而不是' 13'。

我也尝试过使用deadLetterChannel

errorHandler(deadLetterChannel("log:dead?level=ERROR")

我还尝试在continued(false)处理程序中指定onException,但没有运气。

我意识到我可以通过查看exchange.getProperty(Exchange.EXCEPTION_CAUGHT)来查找聚合器中的异常,然后不聚合它。所以我确实有一个解决方案。但是,如果有一种方法可以使用onExceptionerrorHandler在我的路线中执行此操作,我会更喜欢这样做。

1 个答案:

答案 0 :(得分:1)

stopOnException拆分器选项的

Camel Documentation表示

  

是否在发生异常时立即停止继续处理。如果禁用,则Camel继续拆分并处理子消息,无论其中一个是否失败。您可以在AggregationStrategy类中处理异常,您可以完全控制如何处理该异常。

这与Camel In Action一起表明,两个拆分器异常处理选项选项是处理聚合器中的异常,或者使用stopOnException(),这将阻止整个拆分器迭代器继续。 / p>

您可以使用exchange.getException()方法或exchange.isFailed()来测试聚合器中的异常和错误。如果您在handled(true)方法上使用onException,则必须使用exchange.getProperty(Exchange.EXCEPTION_CAUGHT)