How to pass a dynamic delimiter to csv marshalling in camel? - apache-camel

i want to pass a dynamic delimiter to the csv marshalling like below.
<marshal>
<csv delimiter="${header.FIELD_DELIMITER}"/>
</marshal>
when i try as above i am getting this exception:
Caused by: java.lang.IllegalArgumentException: Delimiter must have a length of one!
at org.apache.camel.model.dataformat.CsvDataFormat.configureDataFormat(CsvDataFormat.java:138)
at org.apache.camel.model.DataFormatDefinition.getDataFormat(DataFormatDefinition.java:88)
at org.apache.camel.model.DataFormatDefinition.getDataFormat(DataFormatDefinition.java:80)
at org.apache.camel.model.MarshalDefinition.createProcessor(MarshalDefinition.java:158)
at org.apache.camel.model.ProcessorDefinition.createProcessor(ProcessorDefinition.java:460)
at org.apache.camel.model.ProcessorDefinition.createOutputsProcessor(ProcessorDefinition.java:429)
at org.apache.camel.model.TryDefinition.createProcessor(TryDefinition.java:73)
at org.apache.camel.model.ProcessorDefinition.makeProcessor(ProcessorDefinition.java:500)t
at org.apache.camel.model.ProcessorDefinition.addRoutes(ProcessorDefinition.java:213)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:909)
... 19 more

Instead of doing this
<marshal>
<csv delimiter="${header.FIELD_DELIMITER}"/>
</marshal>
You need to do this:
<toD uri="dataformat:csv:marshal?delimiter=${header.FIELD_DELIMITER}"/>
This is dynamic routing and you will need to use this whenever you want to create URIs on runtime based on runtime values.

You cannot do that with marshal. However you can use the dataformat endpoint and the dynamic to pattern. See more details at:
http://camel.apache.org/dataformat-component.html
http://camel.apache.org/how-to-use-a-dynamic-uri-in-to.html

Related

How to use in operator in camel simple xml dsl?

I am using Camel 2.17.0. I have a need to use in operator in the simple language in the blueprint.xml file as the following
<choice id="_choice3">
<when id="_when3">
<simple>${header.STATUS} in 'Draft,Review'</simple>
......
However, It doesn't work and throws following exception:
org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[ID-A5668784-61983-1579873128661-9-6]
at org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1706)
at org.apache.camel.builder.SimpleBuilder.createPredicate(SimpleBuilder.java:104)
at org.apache.camel.builder.SimpleBuilder.matches(SimpleBuilder.java:83)
By the way, I have been using choice/when condition for a long time. Then I tried to use || and or operator as followings:
<simple>(${header.STATUS.contains("Draft")} or ${header.STATUS.contains("Review")})</simple>
<simple>(${header.STATUS} contains 'Draft' || ${header.STATUS} contains 'Review')</simple>
<simple>(${header.STATUS} contains 'Draft' or ${header.STATUS} contains 'Review')</simple>
In all cases, it throws the same exception. Please help. Thanks in advance
you might lose those extra "()" (brackets) at the end.
Could you try something like this
<simple>${header.STATUS} contains'Draft' or ${header.STATUS} contains 'Review'</simple>
I pre-assume that you are setting the Draft (String) value in the Header.
I hope it helps. :)

Setting timeout for pollenrich using configuration property

I am using pollenrich in my code to get the message from the queue:
<pollEnrich uri="activemq:queueName" timeout="5000"/>
Now, I want to read the timeout value from config file declared in etc folder.
Something like this:
<pollEnrich uri="file:inbox?fileName=data.txt" timeout="{{readTimeout}}"/>
While doing so, I am getting the following error:
org.xml.sax.SAXParseException : cvc-datatype-valid.1.2.1: '{{readTimeout}}' is not a valid value for 'integer'
This error only comes for pollenrich and nowhere else in my code. I am able to use other properties from config file in the same camel-context.
e.g.,
<from uri="timer://TestTimer?period={{timer.interval}}&delay={{startupDelay}}/>
See the documentation at: http://camel.apache.org/using-propertyplaceholder.html at the section titled Using property placeholders for any kind of attribute in the XML DSL

Camel pollEnrich and xml 'prettyPrint'

I am attempting to use Camel's pollEnrich feature, but it is not behaving as I would like... I'm not saying it's broken, but wondering if there is a way to get the behavior I desire. That is, I have an XML (blueprint) defined route that goes something like this:
<route>
<from uri="direct:a" />
<pollEnrich uri="http:www.somewebsite.com?format=application/xml" />
<to uri="log:com.acme?level=WARN&showStreams=true" />
</route>
Now, the response normally comes back just fine (e.g., in a web browser). The problem seems to be that it is not just on one line, and for some reason Camel reads each line, sequentially into the same buffer, starting at character zero... so what we end up with is one messy line in the output from the pollEnrich. That is, the to uri="log... line prints messages like:
2015-05-26 13:55:26,379 | WARN | a.distr.topic.B] | contentEnrich |
? ? | 142 - org.apache.camel.camel-core - 2.12.0.redhat-610379 |
Exchange[ExchangePattern: InOnly, BodyType:
org.apache.camel.converter.stream.InputStreamCache, Body:
<?xml versi</ElementStatus> ]pe></Status>nd>gin>ys for this element.</Reason>>ame>
(last line vertically offset for emphasis)
I cannot seem to find a way to tell Camel that the result will be in 'prettPrint' format... Anyone know how? The documentation seems to suggest that this option does not exist--in which case, I'd consider this to be a bug... though I suppose a person could argue that a custom aggregation strategy should be used (and I'd disagree with that person, citing the simplicity of this case) :)
UPDATE#1: even using org.apache.camel.processor.aggregate.UseLatestAggregationStrategy produces the same effect. (i.e., usage as below)
<bean id="latestStrat"
class="org.apache.camel.processor.aggregate.UseLatestAggregationStrategy" />
<route>
<from uri="direct:a" />
<pollEnrich uri="http:www.somewebsite.com?format=application/xml" strategyRef="latestStrat" />
<to uri="log:com.acme?level=WARN&showStreams=true" />
</route>
...going to cross fingers and try org.apache.camel.processor.aggregate.GroupedExchangeAggregationStrategy, but am guessing there is a configuration limitation with Camel always treating EOL characters as message delimiters.
UPDATE #2 - additional information:
The REST(GET) response received (tested with wget) has blank lines and null fields--but no carriage returns (^M). I've tried both the http and http4 components--same result. There is a leading <?xml version="1.0" encoding="UTF-8"?>, but no namespace/style info. I also just noticed that tab characters have been used for the pretty-ish indents. In sum, the response looks like:
<?xml version="1.0" encoding="UTF-8"?><ElementStatus>
<Flag>false</Flag>
<CODE>XYZ</CODE>
<Locale>Western</Locale>
...
(again, where the whitespace indenting has been done with tabs--AND the blank lines have a few tabs too)
...so the "answer" is that this is an apparent limitation of (or bug within) the log component's "showStreams" logic. I implemented Processor in a <bean>, routed the Exchange output from my pollEnrich to that <bean>, and logged the contents instead, and that matches exactly the output from wget.
FYI: this is camel-paxlogging (2.12.0.redhat-610379) - not sure what underlying version of camel that corresponds to, as I don't seem to have a jboss-parent-2.12.0 pom in my maven repo--which is strange, since I have other jboss-parent poms--and the red hat documentation doesn't seem to get into version composition.
FYI#2: and on a related note, when I use GroupedExchangeAggregationStrategy it does produce a List<Exchange>, BUT it behaves effectively the same as UseLatestAggregationStrategy -- i.e., 'grouped' produces a one-item List<Exchange> that only has the pollEnrich result, where 'latest' produces a standalone Exchange object that has only the pollEnrich result. Seems like an error in either GroupedExchangeAggregationStrategy or pollEnrich ... but this will likely be the topic of my next Stack-post.

apache camel spring dsl check if body contains string

I am trying to check :
<simple>${body} contains 'verification'</simple>
Body is the json:
{"verification": {"email": "bb#wp.pl", "code": "1234"}}
But this condition doesn't work. I've tried as well:
<simple>${body} contains 'verification'</simple>
<simple>${bodyAs(String)} contains 'verification'</simple>
<simple>${body.verification} != null</simple>
Could you please suggest me something?
I guess the body is maybe not a String, then try with
<simple>${bodyAs(String)} contains 'verification'</simple>
And btw what version of Camel do you use?
Actually this case:
<simple>${bodyAs(String)} contains 'verification'</simple>
didn't work cause:
In Camel the message body can be of any types. Some types are safely readable multiple times, and therefore do not 'suffer' from becoming 'empty'.
It fixes by Stream caching

Is it possible to put myBatis (iBatis) xml mappers outside the project?

According to the user guide i am able to use file path instead of
resource:
// Using classpath relative resources
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
</mappers>
// Using url fully qualified paths
<mappers>
<mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
</mappers>
in my project I'm trying to put my mapper xml "outside" the project
and i'm doing this:
<mapper url="file://D:/Mappers/ComponentMapper1.xml" />
The output of my log4j console:
Error building SqlSession.
The error may exist in file://D:/Mappers/ComponentMapper1.xml
Cause: org.apache.ibatis.builder.BuilderException: Error parsing
SQL Mapper Configuration. Cause: java.net.UnknownHostException: D
Is it bug or it's me doing something wrong?
You just need an additional forward slash before the drive letter.
Sql Map Config looks for mapping files relatively to the classpath, so just try adding your ComponentMapper1.xml somewhere to the classpath.
set CLASSPATH=%CLASSPATH%;D:/Mappers/
...
<mapper resource="ComponentMapper1.xml" />
You must use
<mapper url="file:///usr/local/ComponentMapper1.xml" />
Where file:///usr/local/ComponentMapper1.xmlis the path to your XML File, instead of the resource if you want use mappers outside resource dir.

Resources