...
But hey we have added the file producer endpoint and thus a file should also be created as the backup file. If we look in the target/subfolder
we can see that something happened.
On my humble laptop it created this folder: target\subfolder\ID-claus-acer. So the file producer create a sub folder named ID-claus-acer
what is this? Well Camel auto generates an unique filename based on the unique message id if not given instructions to use a fixed filename. In fact it creates another sub folder and name the file as: target\subfolder\ID-claus-acer\3750-1219148558921\1-0 where 1-0 is the file with the mail body. What we want is to use our own filename instead of this auto generated filename. This is archived by adding a header to the message with the filename to use. So we need to add this to our route and compute the filename based on the message content.
Setting the filename
...
For starters we show the simple solution and build from there. We start by setting a constant filename, just to verify that we are on the right path, to instruct the file producer what filename to use. The file producer uses a special header FileComponent.HEADER_FILE_NAME
to set the filename.
What we do is to send the header when we "kick-start" the routing as the header will be propagated from the direct queue to the file producer. What we need to do is to use the ProducerTemplate.sendBodyAndHeader
method that takes both a body and a header. So we change out webservice code to include the filename also:
Code Block | ||||
---|---|---|---|---|
| ||||
public OutputReportIncident reportIncident(InputReportIncident parameters) {
// create the producer template to use for sending messages
ProducerTemplate producer = context.createProducerTemplate();
// send the body and the filename defined with the special header key
Object mailBody = producer.sendBodyAndHeader("direct:start", parameters, FileComponent.HEADER_FILE_NAME, "incident.txt");
System.out.println("Body:" + mailBody);
// return an OK reply
OutputReportIncident out = new OutputReportIncident();
out.setCode("OK");
return out;
}
|
However we could also have used the route builder itself to configure the constant filename as shown below:
Code Block | ||||
---|---|---|---|---|
| ||||
public void configure() throws Exception {
from("direct:start")
.to("velocity:MailBody.vm")
// set the filename to a constant before the file producer receives the message
.setHeader(FileComponent.HEADER_FILE_NAME, constant("incident.txt"))
.to("file://target/subfolder");
}
|
But Camel can be smarter and we want to dynamic set the filename based on some of the input parameters, how can we do this?
Well the obvious solution is to compute and set the filename from the webservice implementation, but then the webservice implementation has such logic and we want this decoupled, so we could create our own POJO bean that has a method to compute the filename. We could then instruct the routing to invoke this method to get the computed filename. This is a string feature in Camel, its Bean binding. So lets show how this can be done:
Using Bean to compute the filename
First we create our plain java class that computes the filename, and it has 100% no dependencies to Camel what so ever.
Code Block | ||||
---|---|---|---|---|
| ||||
/**
* Plain java class to be used for filename generation based on the reported incident
*/
public class FilenameGenerator {
public String generateFilename(InputReportIncident input) {
// compute the filename
return "incident-" + input.getIncidentId() + ".txt";
}
}
|
The class is very simple and we could easily create unit tests for it to verify that it works as expected. So what we want now is to let Camel invoke this class and its generateFilename with the input parameters and use the output as the filename. Pheeeww is this really possible out-of-the-box in Camel? Yes it is. So lets get on with the show:
Using a script language to set the filename
We could do as in the previous parts where we send the computed filename as a message header when we "kick-start" the route. But we want to learn new stuff so we look for a different solution using some of Camels many Languages. As OGNL is a favorite language of mine (used by WebWork) so we pick this baby for a Camel ride. For starters we must add it to our pom.xml:
...