apache camel spring dsl check if body contains string - apache-camel

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

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"))

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. :)

MuleSoft 4 http request

I am new to MuleSoft
when i am giving output expression like below i am getting an data sense error, can you please help
#[output application/json --- {errorType:error.errorType, error:error.description}]
Description Resource Path Location Type Scripting language error on
expression '#[output application/json --- {errorType:error.errorType,
error:error.descrip...'. Reason: Invalid input '#', expected using,
if, ???, unless or not (line 1, column 1): . validations.xml
/validations/src/main/mule Listener Message Flow Error
It is hard to know without a snippet from the configuration XML exactly what your issue is, but one problem I see is that your dataweave does not start with a
"%dw 2.0" In mule 4 there are two languages. Mule Expression language, which is default in most components (ie #[vars.name] is MEL), and dataweave 2.0 which is default in Transform Message components. You can however, as you've attempted to do, use dataweave inside of Mule Expressions. You have it mostly right, but it must start with "%dw 2.0" at the beginning. So it should look like this.
#[%dw 2.0 output application/json --- {errorType:error.errorType, error:error.description}]
However, judging by the error message, it looks like you're attempting to use MEL in a place where it is not allowed. If you provide a snippet of the configuration XML for this component, I can be more helpful.
There is no MEL in Mule 4. It is migrated to DW2.0. Please refer link https://docs.mulesoft.com/mule-runtime/4.2/migration-mel

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

How to pass a dynamic delimiter to csv marshalling in 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

Resources