Apache Camel是否支持嵌套路由?

时间:2014-02-28 06:29:30

标签: java apache-camel

Apache Camel Route:

    from("file:/tmp/test?include=.*.csv").process(new Processor() {
        public void process(Exchange exchange) throws Exception {
            // set output file name
            exchange.setProperty("outputFile", exchange.getIn().getHeader(Exchange.FILE_NAME, String.class) + ".tmp." + exchange.getExchangeId());
        }
    }).onCompletion().split().tokenize("\n", 100).process(new RequestProcessor()).to("direct:response").end().process(new Processor() {
        public void process(Exchange exchange) throws Exception {
            final String outputFile = exchange.getProperty("outputFile", String.class);

            // add new rout to encrypt
            CamelContext context = new DefaultCamelContext();
            context.addRoutes(new RouteBuilder() {
                public void configure() {

            from("file:/tmp/test/output?fileName=" + outputFile).marshal().pgp(keyFileName, keyUserid).to("file:/tmp/test/output?fileName=" + outputFile + ".pgp");
                }
            });

            context.start();
            Thread.sleep(5000);
            context.stop();
        }
    });

    from("direct:response").to("file:/tmp/test/output?fileName=${header.outputFile}&fileExist=Append");

以上路线正在处理大文件拆分为块(用于批处理)并生成带有结果的输出文件。一旦生成了我需要加密的输出文件。所以我在onCompletion文件拆分/处理路由上的处理器内添加了新路由。它有效但我觉得它不是一个好的设计(因为涉及两个上下文并且需要明确地关闭上下文)。

你能否告诉我正确的解雇加密路线的方法。

2 个答案:

答案 0 :(得分:0)

您建议的常常(或始终)嵌套路线可能会被绕过。也许这条简单的路线可以满足您的要求:

@Override
public void configure() throws Exception {
    from("file:/tmp/test?include=.*.csv")
       .split().tokenize("\n", 100)
       .setProperty("outputFile", simple("${header.CamelFileName}.${exchangeId}.pgp"))
       .log("The splitted body will be PGP encoded & written to file ${property.outputFile}")
       .marshal().pgp("keyFileName", "keyUserid")
       .to("file:/tmp/test/output?fileName=${property.outputFile}");
    }
}

不会写入临时文件,但拆分内容将直接在内存中加密。

修改

如果您想逐个处理一个文件,那么您的路线将如下所示:

@Override
public void configure() throws Exception {
    from("file:/tmp/test?include=.*.csv")
       .setProperty("outputFile", simple("${header.CamelFileName}.${exchangeId}.pgp"))
       .log("The body will be PGP encoded & written to file ${property.outputFile}")
       .marshal().pgp("keyFileName", "keyUserid")
       .to("file:/tmp/test/output?fileName=${property.outputFile}");
    }
}    

如果您想首先创建一个大文件,然后对PGP编码此文件,那么您可以使用aggregator对内存中所有输入文件的内容进行采样。当然,这只有在你的内存限制允许的情况下才有可能。

答案 1 :(得分:0)

我根据您的反馈改进了初始设计。但加密路由是将原始文件作为输入,是否有任何机制将生成的输出文件重定向为加密输入。

    from("file:/tmp/test/input?include=.*.csv&noop=true")
        .setProperty("outputFile", simple("${header.CamelFileName}.${exchangeId}"))
        .onCompletion()
            .split().tokenize("\n", 100)
            .log("splitted body processed & written to file ${property.outputFile}.csv")
            .process(new RequestProcessor())
            .to("file:/tmp/test/temp?fileName=${property.outputFile}.csv&fileExist=Append")
        .end()
        .marshal().pgp(keyFileName, keyUserid)
        .log("PGP encrypted written to file ${property.outputFile}.pgp")
        .to("file:/tmp/test/output?fileName=${property.outputFile}.pgp");

注意: 的RequestProcessor:

public class RequestProcessor implements Processor {
public void process(Exchange exchange) throws Exception {
String body = exchange.getIn().getBody(String.class);
String[] split = body.split("\n");
StringBuilder output = new StringBuilder();

// TODO begin trx

for (String input : split) {
    if (input.startsWith("InputHeader")) {
        output.append("OutputHeader").append(input.substring(11) + ",");
    } else {
        // TODO process here
        output.append("\n").append(input).append(",DONE");
    }
}

// TODO commit trx

DefaultMessage message = new DefaultMessage();
message.setBody(output.toString());

exchange.setOut(message);

}