use file name for multiple routers in Camel - apache-camel

I want use filename in multiple rotuers
#Override
public void configure() throws Exception {
from("file:C:/inputFolder").setHeader("CamelFileName").recipientList(header("CamelFileName"),"direct:route1,direct:route1")
I'm created header parameter as CamelFileName and passing that to recipientList.

Moreover, after recipient list header values will be gone. You better set the filename to property and then it can be used in 'n' of routes.

Related

Calling a camel route using Producer Template

My use case is based on the rest controller input I need to fetch or move files from different source system to destination system.
Route :-
#Component
public class MoveFile extends RouteBuilder {
#override
public void configure() throws Exception {
from("file:tmp/${header.inPath}")
.to("file:/tmp${header.outPath}?fileName=${header.fileName}")
.setBody().constant("File - ${header.inPath}/${header.fileName} Moved Succesfully")
}
}
My rest controller will pass the jobName along the getMapping to invoke this specific route inPath , outPath and File Names
#Resource(name=RouteProperties)
private Prosperties props;
#GetMapping("/runJob/{jobToInvoke}")
public String runJob (#PathVariable final String jobToInvoke){
String inPath=props.getProperty("inPath"+jobToInvoke)
String outPath=props.getProperty("outPath"+jobToInvoke)
String fileName=props.getProperty("fileName"+jobToInvoke)
String jobStatus = ProducerTemplate.withHeader("inPath",inPath)
.
.
.to(??)
.request(String.class)
}
I need help to use Producer Template to pass the properties using to ?
I tried some search on the google, but there is an example available in youtube (link) , But in that Video it is calling uri , (Direct:sendMessage) and from in the route also has that.
How to handle in this scenario ?
Thanks in Advance
A route beginning with a direct: endpoint can be invoked programmatically from Java code. In the route, the pollEnrich component invokes a consumer endpoint to read a file and replace the exchange message body with the file contents.
from("direct:start")
.pollEnrich().simple("file:/tmp?fileName=${header.inPath}")
.toD("file:/tmp?fileName=${header.outPath}")
.setBody().simple("File - ${header.inPath} Moved Successfully");
To invoke the route from Java code:
String jobStatus = producerTemplate.withHeader("inPath", inPath)
.withHeader("outPath", outPath)
.to("direct:start")
.request(String.class);
I don't know if these dynamic file URIs in from work, but at least the Camel File documentation states
Also, the starting directory must not contain dynamic expressions with
${ } placeholders. Again use the fileName option to specify the
dynamic part of the filename.
So the docs are suggesting to change
from("file:tmp/${header.inPath}")
into
from("file:tmp?fileName=${header.inPath}")
The fileName option can be a relative path (not just a filename).
If that change works for you, your question becomes obsolete because the route URI is no more dynamic.
.withHeader("inPath",inPath)
.to("file:tmp")

How to pass parameters to a Camel route?

It is possible to pass parameters to a Camel route?, for instance, in the next code snippet:
public class MyRoute extends RouteBuilder {
public void configure() throws Exception {
from("direct:start")
.to("cxf:bean:inventoryEndpoint?dataFormat=PAYLOAD");
}
}
The value for dataFormat is in hard code, but, what if I want set it dynamically?, passing a value from the code where route is called. I know this is possible adding a constructor and passing parameters in it, like this:
public class MyRoute extends RouteBuilder {
private String type;
public MyRoute(String type){
this.type = type;
}
public void configure() throws Exception {
from("direct:start")
.to("cxf:bean:inventoryEndpoint?dataFormat=" + type);
}
}
There is another way?
Thanks so much!
As you mentioned, you can use a constructor (or setters or any other Java/Framework instruments) if the parameters are static from a Camel point of view.
The parameters are configurable in the application, but after the application is started they do no more change. So, every message processed by the Camel route uses the same value.
In contrast, when the parameters are dynamic - i.e. they can change for every processed message, you can use the dynamic endpoint toD() of Camel. These endpoint addresses can contain expressions that are computed on runtime. For example the route
from("direct:start")
.toD("${header.foo}");
sends messages to a dynamic endpoint and takes the value from the message header named foo.
Or to use your example
.toD("cxf:bean:inventoryEndpoint?dataFormat=${header.dataFormat}");
This way you can set the dataformat for every message individually through a header.
You can find more about dynamic endpoints on this Camel documentation page

Dynamic Apache Camel Output Route

Hi i want to compute a dynamic output route using apache Camel. I receive a bunch of files in a folder location, based on its contents i want to move the file to dynamic output folder. The name of the ouput folder will be constructed based on the input content of the file. How do i acheive it.
The Following piece of code read the files, processes them, but i am not sure how to set the value of ${foldername} based on the contents of the file
from("file:D:\\camel\\input\\one?recursive=true&delete=true")
.process(new LogProcessor())
.to("file:D:\\camel\\output\\${foldername}")
Please assist
You could create a custom processor to construct the foldername and insert into a header.
public class DirectoryNameProcessor implements Processor {
#Override
public void process(Exchange exchange) {
Message in = exchange.getIn();
// Get the contents of the processed file
String body = in.getBody(String.class);
//Get the original file name
String fileName = in.getHeader("CamelFileName", String.class);
// Perform your logic
in.setHeader("foldername");
}
}
Then in your route you could access the newly created foldername-header:
.to("file:D:\\camel\\output\\${header.foldername}");
The short answer is, you can use the dynamic to endpoint toD.
http://camel.apache.org/message-endpoint.html#MessageEndpoint-DynamicTo
It would look like:
from("file:D:\\camel\\input\\one?recursive=true&delete=true")
.process(new LogProcessor())
.toD("file:D:\\camel\\output\\${foldername}")

Camel-cmis - metadata setting error

A simple test of setting the document class of document stored in filenet worked in camel-cmis 2.16.2. Below is the route
from("file://C:/Target/DMS/").process(new Processor() {
#Override
public void process(Exchange e) throws Exception {
e.getIn().getHeaders().put(PropertyIds.CONTENT_STREAM_MIME_TYPE, "application/pdf; charset=UTF-8");
e.getIn().getHeaders().put(CamelCMISConstants.CMIS_FOLDER_PATH, "/Test");
e.getIn().getHeaders().put("cmis:objectTypeId", "doc_Test");
e.getIn().getHeaders().put(PropertyIds.NAME, e.getIn().getHeader(Exchange.FILE_NAME));
}
}).to("cmis://http://test:9080/fncmis/resources/Service?repositoryId=TEST_REPO&username=TEST&password=RAW(TEST)");
When i check the document class of file stored in IBM Filenet - i could see the doc class as Test (symbolic name: doc_Test). But when i add atleast one of the parameter value of that class like below
e.getOut().getHeaders().put("prp_Field1","TestValue1");
Im getting NoSuchHeaderException for parameter "cmis:name" which i have already set as you can see the above route. Is this the correct way to set metadata parameters??
Below route for storing worked. Decide on the Customized classes,fields & data types, create metadata based on that & then same field names are to be set in camel headers before sending to cmis uri (Storing).
ObjectTypeId - Customized class name
CMIS_FOLDER_PATH - filenet folder path inside repository
NAME - File name to be stored
from("file://C:/Target/DMS/").process(new Processor() {
#Override
public void process(Exchange e) throws Exception {
e.getIn().getHeaders().put(CamelCMISConstants.CMIS_FOLDER_PATH, "/TEST");
e.getIn().getHeaders().put("cmis:objectTypeId", "doc_Test");
e.getIn().getHeaders().put(PropertyIds.NAME, fileName + ".pdf");
e.getOut().getHeaders().put("prp_Field1","TestValue1");
e.getOut().getHeaders().put("prp_Field2","TestValue2");
e.getOut().getHeaders().put("prp_Field3","TestValue3");
}
}).to("cmis://http://test:9080/fncmis/resources/Service?repositoryId=TEST_REPO&username=TEST&password=RAW(TEST)");
Hope it helps someone..

How to get the actual file object from Camel FTP route exchange

In my Camel router:
from(<SourceURI>)
.process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
// I want to extract the file object from the exchange
}
.to(<targetURI>).
How can I achieve this?
I tried e.g. exchange.getIn().getHeader(Exchange.FILE_NAME, String.class) which gives me the file name.
I am searching for something Exchange.FILE which gives me the actual file object. My Ultimate goal is to extract the file in the processor as the routed exchange is an archive file.
Get the file from the body. Camel uses a 'org.apache.camel.component.file.GenericFile' to store as the file body. But you can use Camel's type converters to get the file in a type you want.
For example you can get the content in different types, such as:
String text = exchange.getIn().getBody(String.class);
byte[] bytes = exchange.getIn().getBody(byte[].class);
InputStream is = exchange.getIn().getBody(InputStream.class);
For those who have a from("file:...") the following works:
File in = exchange.getIn().getBody(File.class);

Resources