2014-02-28 165 views
0

Apache的骆驼路线:Apache Camel是否支持嵌套路由?

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文件拆分/进程路由的处理器中添加了NEW路由。它的工作原理,但我觉得这不是一个好的设计(因为涉及到TWO上下文,并且需要显式地关闭上下文)。

你可以任何人建议我解雇加密路线的正确方法。

回答

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

+0

太谢谢你了彼得。伟大的帮助... – user3332279

+0

我仍然有一个问题,与上述解决方案,它会创建基于拆分大小的多个文件。我怎样才能避免这一点,并加密成单个文件。 – user3332279

+0

@ user3332279我更新了答案 –

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

}