【问题标题】:Does Apache Camel support nested routes?Apache Camel 是否支持嵌套路由?
【发布时间】:2014-03-04 04:51:56
【问题描述】:

阿帕奇骆驼路线:

    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 文件拆分/处理路由的处理器内添加了新路由。它可以工作,但我觉得这不是一个好的设计(因为涉及两个上下文并且需要明确关闭上下文)。

谁能建议我触发加密路线的正确方法。

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

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

    @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 对内存中所有输入文件的内容进行采样。当然,这只有在您的内存限制允许的情况下才有可能。

    【讨论】:

    • 我仍然有一个问题,使用上述解决方案,它将根据拆分大小创建多个文件。我怎样才能避免这种情况并加密成单个文件。
    • 如果对您有帮助,您可以接受答案并点赞,这样每个人都可以看到问题已得到解答。
    【解决方案2】:

    我根据您的反馈改进了初始设计。但是加密路径是获取原始文件作为输入,有没有什么机制可以重定向生成的输出文件作为加密的输入。

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

    注意: 请求处理器:

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

    }

    【讨论】:

      猜你喜欢
      • 2016-04-30
      • 1970-01-01
      • 2020-10-23
      • 2016-09-29
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-09
      相关资源
      最近更新 更多