Apache camel 基于XQuery筛选器设置标头

Apache camel 基于XQuery筛选器设置标头,apache-camel,Apache Camel,我有一个路由设置为以批处理模式运行,轮询数千个XML文件。每个元素都在XML结构中加上时间戳,这个dateTime元素用于确定是否应该将XML包含在批处理的进一步处理(XQuery转换)中。由于这是一个批处理路由,它在执行后自行终止 因为路由需要自己关闭,所以我必须确保如果每条消息都被过滤掉,它也会关闭,这就是为什么我不使用过滤器,而是使用.choice()语句,并在exchange上设置一个自定义头,该头稍后在一个bean中使用,该bean对匹配项进行分组,并为XQuery准备一个源文档 然而

我有一个路由设置为以批处理模式运行,轮询数千个XML文件。每个元素都在XML结构中加上时间戳,这个dateTime元素用于确定是否应该将XML包含在批处理的进一步处理(XQuery转换)中。由于这是一个批处理路由,它在执行后自行终止

因为路由需要自己关闭,所以我必须确保如果每条消息都被过滤掉,它也会关闭,这就是为什么我不使用过滤器,而是使用
.choice()
语句,并在exchange上设置一个自定义头,该头稍后在一个bean中使用,该bean对匹配项进行分组,并为XQuery准备一个源文档

然而,我当前的方法需要另一条路径,
.choice()
的两个分支都要转发到该路径。这是必要的,因为我似乎不能强迫两条路都继续下去。所以我的问题是:如何摆脱第二条路线?一种方法是在bean中设置过滤器头,但我担心涉及的开销。我假设Camel中的XQuery过滤器的性能将大大优于POJO,POJO从字符串构建XML文档并对其运行XQuery

from(sourcePath + "?noop=true" + "&include=.*.xml")
        .choice()
            .when()
                .xquery("[XQuery Filter]")
                .setHeader("Filtered", constant(false))
                .to("direct:continue")
            .otherwise()
                .setHeader("Filtered", constant(true))
                .to("direct:continue")
.end();

from("direct:continue")
        .routeId(forwarderRouteID)
        .aggregate(aggregationExpression)
            .completionFromBatchConsumer()
            .completionTimeout(DEF_COMPLETION_TIMEOUT)
            .groupExchanges()
        .bean(new FastQueryMerger(), "group")
        .to("xquery:" + xqueryPath)
        .bean(new FileModifier(interval), "setFileName")
        .to(targetPath)
        .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    new RouteTerminator(routeID, exchange.getContext()).start();
                    new RouteTerminator(forwarderRouteID, exchange.getContext()).start();
                }
            })
.end();
你不想在这里帮忙吗? 我的意思是:

from(sourcePath + "?noop=true" + "&include=.*.xml")
    .choice()
        .when()
            .xquery("[XQuery Filter]")
            .setHeader("Filtered", constant(false)).end()
        .otherwise()
            .setHeader("Filtered", constant(true)).end()
    .aggregate(aggregationExpression)
        .completionFromBatchConsumer()
        .completionTimeout(DEF_COMPLETION_TIMEOUT)
        .groupExchanges()
    .bean(new FastQueryMerger(), "group")
    .to("xquery:" + xqueryPath)
    .bean(new FileModifier(interval), "setFileName")
    .to(targetPath)
    .process(new Processor() {
            @Override
            public void process(Exchange exchange) throws Exception {
                new RouteTerminator(routeID, exchange.getContext()).start();
                new RouteTerminator(forwarderRouteID, exchange.getContext()).start();
            }
        });
刚刚快速测试了以下一个,它成功了:

@Produce(uri = "direct:test")
protected ProducerTemplate testProducer;
@EndpointInject(uri = "mock:test-first")
protected MockEndpoint testFirst;
@EndpointInject(uri = "mock:test-therest")
protected MockEndpoint testTheRest;
@EndpointInject(uri = "mock:test-check")
protected MockEndpoint testCheck;

@Test
public void test() {
    final String first = "first";
    final String second = "second";
    testFirst.setExpectedMessageCount(1);
    testTheRest.setExpectedMessageCount(1);
    testCheck.setExpectedMessageCount(2);
    testProducer.sendBody(first);
    testProducer.sendBody(second);
    try {
        testFirst.assertIsSatisfied();
        testTheRest.assertIsSatisfied();
        testCheck.assertIsSatisfied();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

@Override
protected RouteBuilder createRouteBuilder() {
    return new RouteBuilder() {
        public void configure() {
            from("direct:test")
                .choice()
                    .when(body().isEqualTo("first")).to("mock:test-first")
                    .otherwise().to("mock:test-therest").end()
                    .to("mock:test-check");
        }
    };
}

我花了很长时间才回到这个问题上来,因为我刚刚回到项目的这一部分。您提供的第二个代码示例非常有效,正是我所需要的。整个
.choice()
语句末尾的一个简单的
.end()
语句终止所有分支。您最初的第一个代码部分有两条不正确且无法编译的
.end()
语句。我相应地修改了它。再次感谢。