Reputation: 1397
After a rest call, I am trying to set me camel route to return the data and write it into a cvs file. Problem is that I can get it to do only one of the two.
from("direct:select")
.setBody(constant("select * from animal")).to("jdbc:dataSource").marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
In the current version it writes into the file correctly but the rest response is just a bunch of numbers. Though if I change the order of functions like:
from("direct:select")
.setBody(constant("select * from animal"))
.to("file:///tmp?fileName=MY_TEST_FILE.csv").marshal().csv().to("jdbc:dataSource");
I get the correct rest response but in the file I get:
select * from applicant
Is there a way to do both from a single camel route?
Upvotes: 0
Views: 3118
Reputation: 478
Camel just executes the routing/transformation instructions in the order that you define them.
Your first attempt makes some sense: you run the select query, get the list of rows out of the JDBC call, convert it to CSV, then write it to file and return it as reply of your route. That last part is important to understand: the reply from your route will be whatever your exchange body contains at the end of the (synchronous) processing. Given that you're not happy with this first attempt, I will go and assume that the CSV format is not what you intend to return as reply.
Now looking at your second attempt, you say that it returns the expected reply but that is surprising to me: you're trying to convert the literal string "select * from animal" to CSV, which is throwing an exception on my end:
org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: java.lang.String to the required type: java.util.List with value select * from animal
Now if you remove the .marshal().csv()
, the route is working. It writes "select * from animal" to file as you've observed (but that's exactly what the route is instructing to do) and it returns as reply the content of the exchange body at the end of the route, meaning the List
that results from the JDBC call. I will thus make another assumption that this list is in fact what you're intending to return (you probably want to return JSON, so List
does indeed fit the bill for seamless JSON conversion).
With all this in mind, let's try to find you a route that does what you want. However, we hit a bit of a wall with your requirement to "do both from a single camel route". Let's hope that you didn't mean to exclude the usage of sub-routes linked by direct:
endpoints (I don't see any good reason why you'd want to avoid that).
Here's a first solution that does everything synchronously (JDBC call + writing to file both done by the originating thread):
from("direct:select")
.setBody(constant("select * from animal"))
.to("jdbc:dataSource")
.enrich("direct:file", new UseOriginalAggregationStrategy());
from("direct:file")
.marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
See Camel Enrich EIP for more details.
And here's one that will write to file asynchronously (i.e. in a separate thread), meaning that your REST call should be a bit faster to respond:
from("direct:select")
.setBody(constant("select * from animal"))
.to("jdbc:dataSource")
.wireTap("direct:file");
from("direct:file")
.marshal().csv()
.to("file:///tmp?fileName=MY_TEST_FILE.csv");
See Camel Wire Tap EIP for more details.
Upvotes: 1