Reputation: 59
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");
Above route is processing big file splitting into chunk (for batch processing) and generate output file with results. once generated the output file I need to encrypt. So I added NEW route inside a processor on onCompletion file split/process route. It works but I feel it is not a good design (since involve TWO context and need context shutdown explicitly).
Can you anyone suggest me the proper way to fire the encryption route.
Upvotes: 1
Views: 3589
Reputation: 7646
Often (or always) nested routes as you suggest may be bypassed. Perhaps this simple route will meet your requirements:
@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}");
}
}
No temporary file will be written, but the split content will be directly encrypted in memory.
EDIT:
If you want to handle one file by one, then your route will look as follows:
@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}");
}
}
If you want first want to create one big file and then to PGP encode this file, then you may use an aggregator that is sampling the content of all input files in memory. Of course this is only possible if your memory constraints allow that.
Upvotes: 0
Reputation: 59
I enhanced the initial design with your feedback. But the encryption route is getting the original file as the input, are there any mechanism to redirect the generated output file as the input for encryption.
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");
Note: 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);
}
Upvotes: 0