I have the following Apache Camel Spring XML configuration which process a file (input). I try to rename the file before it is copied (move option). I'd like the name of a file to contain a string which is the result of a method call from a bean returning a string (getHash).
Apache Camel version
<dependency>
<groupId>org.apache.camel</groupId>
<version>3.0.0</version>
<type>pom</type>
</dependency>
camel-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Configures the Camel Context-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext id="camelContext-89c763e9" xmlns="http://camel.apache.org/schema/spring">
<route id="FileConsumption" shutdownRoute="Defer">
<from id="_from2" uri="file:/home/spool_in/?move=.done&moveFailed=.bad&fileName={bean:videoProcessor.getHash}.{file:name.ext}"/>
<bean
beanType="org.mediaprocessor.VideoProcessor" id="_videoProcessor" ref="videoProcessor"/>
</route>
</camelContext>
<bean id="videoProcessor" class="org.mediaprocessor.VideoProcessor" />
</beans>
I have a problem with the File component (first endpoint of the route)
<from id="_from2" uri="file:/home/matthieu/spool_in/?move=.done&moveFailed=.bad&fileName=${bean:videoProcessor.getHash}.{file:name.ext}"/>
Bean VideoProcessor.java
@Bean
public static String getHash(File file) throws NoSuchAlgorithmException, IOException {
//Use MD5 algorithm
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
//Get the checksum
String checksum = getFileChecksum(md5Digest, file);
return checksum;
}
Apache Camel doesn't seem to recognize the videoProcessor bean and raise the following exception :
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route FileConsumption at: >>> Bean[] <<< in route: Route(FileConsumption)[From[file:/home/spool_in/?mo... because of bean, ref or beanType must be provided
...
Caused by: java.lang.IllegalArgumentException: bean, ref or beanType must be provided
at org.apache.camel.component.bean.DefaultBeanProcessorFactory.createBeanProcessor(DefaultBeanProcessorFactory.java:67)
at org.apache.camel.reifier.BeanReifier.createProcessor(BeanReifier.java:47)
at org.apache.camel.reifier.ProcessorReifier.makeProcessorImpl(ProcessorReifier.java:571)
at org.apache.camel.reifier.ProcessorReifier.makeProcessor(ProcessorReifier.java:537)
at org.apache.camel.reifier.ProcessorReifier.addRoutes(ProcessorReifier.java:250)
at org.apache.camel.reifier.RouteReifier.doCreateRoute(RouteReifier.java:384)
... 37 more
According to documentation :
And finally we can also use a bean expression to invoke a POJO class that generates some String output (or convertible to String) to be used:
fileName="uniquefile-${bean:myguidgenerator.generateid}.txt"
https://camel.apache.org/manual/latest/file-language.html
Any ideas on what I have missing ? Thanks!
Update : Added "$" sign (typo) in "${bean:videoProcessor.getHash}" according to Julian answer : problem is not solved (same exception)
I am not familiar with the Camel XML as I find Camel DSL much easier to read and use. However in the documentation from camel you provided it was ${bean:myguidgenerator.generateid}
whereas you did not use the "$" sign in your route: fileName={bean:videoProcessor.getHash}
You will also need to add a "$" sign in from of the file extension. ${file:name.ext}
I also replicated your project and after making those "$" changes the application started on my side. However I believe you have more issues with your implementation and even if you get it started it will not do what you expect.
here is what I think your issues are:
getHash
in the fileName
will set act as a filter for the file name you want to consume. From what you are saying this is not what you want. uri="file:/home/matthieu/spool_in/?move=.done/${bean:videoProcessor.getHash}.${file:name.ext}
This is my version of the simplified VideoProcessor:
@Component
@Slf4j
public class VideoProcessor {
public void process(Exchange exchange) {
log.info("Processing {} video ", ((GenericFile) exchange.getIn().getBody()).getFileName());
}
public String getHash(File file) {
return FilenameUtils.removeExtension(file.getName()) + "_copy";
}
}
And here are the log entries:
2020-01-03 11:19:50.444 INFO 27988 --- [/temp/spool_in/] c.v.t.g.webservice.camel.VideoProcessor : Processing Video_1.mpg video
2020-01-03 11:20:41.284 INFO 27988 --- [/temp/spool_in/] c.v.t.g.webservice.camel.VideoProcessor : Processing Video_2.mpg video
2020-01-03 11:20:53.342 INFO 27988 --- [/temp/spool_in/] c.v.t.g.webservice.camel.VideoProcessor : Processing Video_3.mpg video
as well as the moved files:
As @julian already pointed out, you cannot use the filename
option to rename a file . This option is used to filter the files to be consumed.
So, if you want to rename the files before processing them, you can, for example, create a "preprocessing" route, that just renames the files and hands them over to the real processing route.
<route id="FileRenaming" shutdownRoute="Defer">
<from id="spool_in" uri="file:/home/spool_in/?move=.done&moveFailed=.bad"/>
<setHeader name="CamelFileName">
<simple>${bean:videoProcessor.getHash}.${file:name.ext}</simple>
</setHeader>
<to uri="file:/home/process/"/>
</route>
<route id="FileProcessing" shutdownRoute="Defer">
<from id="process" uri="file:/home/process/" />
...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.