I have 10 variables I need to set by parsing JSON payload like #[json:REQUEST_ID] etc. Can this be done thru an expression component all of the variables instead of using Set Variable one after the other. I am looking for how to parse a json payload within an expression component. Many Thanks.
You can use <message-properties-transformer> to simplify the handling of variables on the flow, for example:
<message-properties-transformer doc:name="Message Properties">
<add-message-property key="variableName" value="#[payload.from]" />
<add-message-property key="prmts" value="#[org.apache.commons.lang.StringUtils.split(payload.parameters, ';')]" />
</message-properties-transformer>
I hope I can help you.
I'd prefer an enricher to a message-properties-transformer here:
<enricher>
<enrich target="#[variable:requestId] source="#[json:REQUEST_ID]" />
<enrich target="#[variable:otherThing] source="#[json:OTHER_THING]" />
</enricher>
Related
I have multiple endpoints for different vendor's and we are differentiating it based on the userId for similar service operation and routing calls accordingly.
mule-app.properties
userIds=123,124,125
123.service.uri=http://google.com
124.service.url=http://yahoo.com
Can someone tell if there is a way to dynamically refer property using MEL and flowVariable holding userId value?
<flow name="test">
<http:listener config-ref="mylistenerconfig" path="test" doc:name="Request Listener" />
<set-variable variableName="userId" value="#[message.inboundProperties.userId]" />
<set-variable variableName="userServiceUri" value="${flowVars['userId'].service.uri}" />
<logger level="INFO" message="******* serviceUri=#[userServiceUri] ****" />
</flow>
I tried directly referring that value from message.inboundProperties.userId, referring it using a seperate variable - nothing works. Can someone suggest on how to achieve this?
Load the properties files with Spring:
<util:properties id="muleAppProps"
location="classpath*:mule-app.properties" />
Then you can dynamically refer to values in it with:
#[app.registry.muleAppProps[userId + '.service.uri']]
Assuming userId is a flow var that contains a value like "123"
<babyproducts>
<products>
<product1>
<productid>100</productid>
<productname>towel</productname>
<desc>towel</desc>
<discount>100</discount>
<validlity>10</validlity>
</product1>
<product2>
<productid>101</productid>
<productname>pillow</productname>
<desc>pillow</desc>
<discount>500</discount>
<validlity>5</validlity>
</product2>
</product>
</babyproducts>
I want to split above xml using xpath3 expression and replace the validlity value . after that i want whole set of above xml replaced values. I tried using xpath it is working fine. my requirement insists on doing using xpath3 mule expression
<splitter evaluator="xpath" expression="/babyproducts/products" doc:name="Splitter" />
<set-payload value="#[message.payload]" doc:name="Set Payload" />
<enricher source="#[flowVars.newvalidlity]" target="#[xpath('/products/validlity').text ]" doc:name="Message Enricher">
<logger level="INFO" message=" enricher done ~~~~~.." doc:name="Logger" />
</enricher>
above is my mule flow using xpath. my team wants to do using xpath3 (latest).
my expected outpu is like below with new validlity value 50 (comes from flow variable)
<babyproducts>
<products>
<product1>
<productid>100</productid>
<productname>towel</productname>
<desc>towel</desc>
<discount>100</discount>
<validlity>50</validlity>
</product1>
<product2>
<productid>101</productid>
<productname>pillow</productname>
<desc>pillow</desc>
<discount>500</discount>
<validlity>50</validlity>
</product2>
</product>
</babyproducts>
First of all your XML sample is invalid. There are unclosed tags and your xpath doesn't match the structure of the sample either.
Second of all I can only show the equivalent xpath3 expression of your xpath expression as I have already answered how to update an XML node in other questions of yours.
<splitter evaluator="xpath" expression="/babyproducts/products" doc:name="Splitter" />
Becomes:
<splitter expression="#[xpath3('/babyproducts/products/*', payload, 'NODESET')]"
doc:name="Splitter" />
And
#[xpath('/products/validlity').text]
Becomes:
#[xpath3('/products/validlity')]
No need for .text as by default returns the Stirng value. More info here: http://blogs.mulesoft.org/mule-3-6-xml-xpath-xslt-xquery3/
<splitter evaluator="xpath" expression="/healthcare/plans" doc:name="Splitter" />
<enricher source="#[flowVars.tempid]" target="#[xpath('/plans/planid').text ]" doc:name="Message Enricher">
above code working fine using xpath
but below code using xpath3 not picking up the text
<splitter expression="#[xpath3('/healthcare/plans', payload, 'NODESET')]" doc:name="Splitter" />
<enricher source="#[flowVars.tempid]" target="#[xpath3('/plans/planid').text ]" doc:name="Message Enricher">
Theres a few things wrong with your config:
By default xpath3 returns a String, so no need to call .text. More on this here: http://blogs.mulesoft.org/mule-3-6-xml-xpath-xslt-xquery3/
The source and target expressions the wrong way round. If you want to store the result of the XPath expression in a a variable then target is where the variable should be and source is the source of the value in this case the xpath expression.
Your Xpath expression is wrong. No need for /plans as the XML is already split into individual plan nodes.
Try this:
<splitter expression="#[xpath3('/healthcare/plans/*', payload, 'NODESET')]"
doc:name="Splitter" />
<enricher source="#[xpath3('planid')]" target="#[flowVars.tempid]"
doc:name="Message Enricher">
I want to perform some string operation on MEL I have following expression in MEL
<logger message="#[json:xy/PID/xy.3/AC]" level="INFO" doc:name="Logger"/>
OUTPUT IS
19901026000000
I want to extract 1st 4 digit then 6,7 digit .
How can I do this ??
Thanks
What about trying it in two steps?
<set-variable variableName="result" value="#[json:ADT_A01/PID/PID.3/CX.1]" />
<set-variable variableName="result" value="#[result.substring(0,4)]#[result.substring(5,7)]" />
As noted in the comments in #Ryan Hoegg answer, the JSON expression evaluator has been deprecated since Mule 3.3 and hence the best way to do this would be to use a json to object transformer
<json:json-to-object-transformer doc:name="JSON to Object" returnClass="java.util.HashMap"/>
and then use conventional MEL to traverse the Map
JsonPath expression are depreciated for now and you will even not get enough document on it for doing ..
So, currently you need to use either :- <json:json-to-object-transformer returnClass="java.lang.Object" doc:name="JSON to Object" />
or <json:json-to-object-transformer returnClass="java.util.HashMap" doc:name="JSON to Object" />
or even <json:json-to-object-transformer returnClass="java.util.List" doc:name="JSON to Object" /> to extract data from JSON depending on the JSON data
In trying to restore the original payload in a message, I ran into this issue that confused me regarding the scope of a mule message. Given the mule config below, I initially assumed that the payload received at the test.Name vm endpoint was going to be restored at the end of the flow (see 1. and 2. in the config):
<mule ...>
<vm:endpoint name="replacePayloadWithFoo.Name"
path="replacePayloadWithFoo.Path" />
<flow name="test">
<vm:inbound-endpoint name="test.Name" path="test.Path"
exchange-pattern="request-response" />
<!-- 1. Down below, I wanted to restore the payload at this point -->
<expression-transformer evaluator="string"
expression="bar" />
<outbound-endpoint ref="replacePayloadWithFoo.Name"
exchange-pattern="request-response" />
<!-- 2. The transformer below does not restore the payload at 1. -->
<expression-transformer evaluator="groovy"
expression="message.originalPayload" />
</flow>
<flow name="replacePayloadWithFoo">
<inbound-endpoint ref="replacePayloadWithFoo.Name"
exchange-pattern="request-response" />
<expression-transformer evaluator="string"
expression="foo" />
</flow>
</mule>
However, it seemed as though the message that entered the test flow ended at the replacePayloadWithFoo outbound endpoint. The transformer at 2. leaves "foo" as the payload.
What's the scope of the mule message?
In passing, the scripting reference documentation indicates that there is a binding for originalPayload in groovy scripts. However, if the transformer at 2. is replaced with
<expression-transformer evaluator="groovy" expression="originalPayload" />
I get an exception:
org.mule.api.expression.RequiredValueException: Expression Evaluator "groovy"
with expression "originalPayload" returned null but a value was required.
What could be the issue?
Thanks
Any outbound interaction, unless performed through an enricher, will affect the current in-flight message. This is why the call to replacePayloadWithFoo replaces the original message with the result of the outbound interaction.
This said, I can not explain the discrepancy between:
<expression-transformer evaluator="groovy" expression="message.originalPayload" />
and:
<expression-transformer evaluator="groovy" expression="originalPayload" />
because they both rely on:
event.getMessage().getPayload()