2014-02-28 211 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); 

}