Camel pollEnrich and xml 'prettyPrint' - apache-camel

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.

Related

PrettyPrint feature does not work in Apache Camel

I have been trying to leverage the PrettyPrint feature to display the result of my API that is using Apache Camel. Here is the context. I have this route in my code
// Route Definition for processing Health check request
from("direct:processHealthCheckRequest")
.routeId("health")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200))
.setBody(constant(healthCheckResponse));
When I'm using Postman to test my API, the display is in pretty mode even though it is not set to true, like so
{
"status": "UP"
}
Now when I'm using the following code to set the PrettyPrint to false, I'm still getting the same result. It looks like the PrettyPrint feature is not working as it is supposed to
// Route Definition for processing Health check request
from("direct:processHealthCheckRequest")
.routeId("health")
.setHeader(Exchange.HTTP_RESPONSE_CODE, constant(200))
.setBody(constant(healthCheckResponse))
.unmarshal()
.json(JsonLibrary.Jackson, HealthCheckResponse.class, false);
I'm expecting the result to be displayed on one line like here without changing the type from JSON to string.
{"status": "UP"}
Could someone please advice on this?
I've bumped into the same issue always when manually setting the HTTP_RESPONSE_CODE header. I don't know why it technically happens - without it the HTTP response always returns proper JSON for me.
Setting CONTENT_TYPE header to application/json has solved it:
.setHeader(Exchange.CONTENT_TYPE, constant("application/json"))
The solution that finally worked was to set the following in my application.properties file.
camel.rest.data-format-property.prettyPrint=false
or not to provide that property at all.
Try this:
<removeHeaders id="removeHeaders_http*" pattern="CamelHttp*"/>
<setHeader headerName="Content-type" id="content_setHeader">
<constant>application/x-www-form-urlencoded</constant>
</setHeader>
Same with Java DSL:
.removeHeaders("CamelHttp*")
.setHeader("Content-type", constant("application/x-www-form-urlencoded"))

Exchange body substring in log message

How to log exchange body substring as message attribute of log component?
I have tried these:
<log message="SEND RESPONSE TO WEB SERVICE: Headers:[${headers}]\nBody:[${bodyAs(String).substring(0,1000)}]"/>
<log message="SEND RESPONSE TO WEB SERVICE: Headers:[${headers}]\nBody:[${body.toString().substring(0,1000)}]"/>
but none works. First variant is marked as mistake by IDE Camel plugin and does not allow application to start, and the second one throws the exception about calling toString() at null (although body is not).
ps body is really instance of String.
Read this page, particularly the section "Full Customization of the Logged Output"

Why is my Camel Netty route adding newlines to the start of my JMS messages?

I have a Camel Netty route that takes XML sent to a server port and places it in a JMS message. After the first message, every other message has a newline at the top of the message, causing my XML to fail to unmarshall when a GUI receives it.
My route look like this:
<route>
<from uri="netty4:tcp://localhost:5150?decoders=#customFrameDelimeterDecoder,#string-decoder&encoder=#string-encoder"/>
<to uri="jms:topic:my.company.topic"/>
</route>
Note: The XML is not newline terminated, hence the need for a custom frame delimeter decoder.
Try setting:
<from uri="netty4:tcp://localhost:5150?textline=true&delimiter=NULL"/>
The problem is that camel-netty4 is adding a delimiter to your message because of the codec text, so it seems that it is putting a empty string at the end of your message.
You could also try to add autoAppendDelimiter to false. According to docs:
delimiter | LINE | The delimiter to use for the textline codec. Possible values are LINE and NULL
autoAppendDelimiter | true | Whether or not to auto append missing end delimiter when sending using the textline codec.
Cheers!
EDIT:
Sorry, I was trying to answer your other question that was marked as duplicated. But maybe this answer also fits. Let me know.

Why is my Camel Netty route adding empty messages after an EOL delimiter? [duplicate]

I have a Camel Netty route that takes XML sent to a server port and places it in a JMS message. After the first message, every other message has a newline at the top of the message, causing my XML to fail to unmarshall when a GUI receives it.
My route look like this:
<route>
<from uri="netty4:tcp://localhost:5150?decoders=#customFrameDelimeterDecoder,#string-decoder&encoder=#string-encoder"/>
<to uri="jms:topic:my.company.topic"/>
</route>
Note: The XML is not newline terminated, hence the need for a custom frame delimeter decoder.
Try setting:
<from uri="netty4:tcp://localhost:5150?textline=true&delimiter=NULL"/>
The problem is that camel-netty4 is adding a delimiter to your message because of the codec text, so it seems that it is putting a empty string at the end of your message.
You could also try to add autoAppendDelimiter to false. According to docs:
delimiter | LINE | The delimiter to use for the textline codec. Possible values are LINE and NULL
autoAppendDelimiter | true | Whether or not to auto append missing end delimiter when sending using the textline codec.
Cheers!
EDIT:
Sorry, I was trying to answer your other question that was marked as duplicated. But maybe this answer also fits. Let me know.

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

Resources