<set-variable variableName="template" value="#[payload.templatePath]" doc:name="Template Path"/>
<custom-transformer class="com.comviva.mfs.eig.transformers.generic.MapUtil" doc:name="Map">
<spring:property name="sessionBean" ref="SessionBean"/>
<spring:property name="fixedTemplatePath" value="#[flowVars['template']]"/>
OR In both cases I want the value of the map to be replaced dynamically while sending the data as the key templatePath contains dynamic value and I want that to get picked from the payload that is of Map type
<custom-transformer class="com.comviva.mfs.eig.transformers.generic.MapUtil" doc:name="Map">
<spring:property name="sessionBean" ref="SessionBean"/>
<spring:property name="fixedTemplatePath" value="#[payload.templatePath]"/>
Spring properties are not interpreted by the MEL. As it is provided as setter injection which is invoked during instantiation the value of payload or a flow/session var will not be available.
You can change the transformer code to read the value from the payload within the transformation code itself as payload will be available from 'Object src' param.
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"
The message enricher documentation uses a term "variable" for example
<flow name="orderProcessingFlow">
<inbound-endpoint ref="orderEndpoint"/>
<enricher target="#[variable:state]">
<outbound-endpoint ref="stateLookup"/>
</enricher>
<outbound-endpoint ref="orderStep2"/>
</flow>
I did not find any documentation on that keyword, I can figure out it basically adds a flow variable, but is there anything more to it ? (without keyword variable you get a exception)
Also none of the examples in the documentation refer to enriching "message headers" -- My assumption is that message headers implies outbound properties is that correct ?
If the same flow were to add a outbound property how would it look (this works based on my tests)
<flow name="orderProcessingFlow">
<inbound-endpoint ref="orderEndpoint"/>
<enricher target="#[message.outboundProperties.var]">
<outbound-endpoint ref="stateLookup"/>
</enricher>
<outbound-endpoint ref="orderStep2"/>
</flow>
#[variable:state] is the old expression syntax, it's deprecated and replaced by MEL since 3.3. I think the MEL equivalent is #[flowVars.state]
Similarly, message "headers" is obsolete lingo. You have message properties with different scopes (inbound, outbound, flow/invocation and session).
And yes the only properties you can set in a flow are outbound properties (inbound ones are set by endpoints).
Having a requirement to test a object store whether it contains a key or not in a choice router
<objectstore:config name="storeDownload" doc:name="ObjectStore" persistent="false" partition="test"/>
<choice>
<when expression="#[app.registry.storeDownload.contains('#[flowVars.startKey]').equals('false')]">
Getting an error
1. Expression Evaluator "registry" with expression "ON" returned null but a value was required. (org.mule.api.expression.ExpressionRuntimeException)
org.mule.expression.RegistryExpressionEvaluator:101 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/expression/ExpressionRuntimeException.html)
2. Failed to invoke store. Message payload is of type: byte[] (org.mule.api.MessagingException)
The main issue is that you are embedding MEL into MEL which can't work. Also the boolean-as-string comparison is dodgy.
Replace this:
#[app.registry.storeDownload.contains('#[flowVars.startKey]').equals('false')]
with that:
#[!(app.registry.storeDownload.contains(flowVars.startKey))]
My use case was a bit different to Nazar's I needed to monitor a long running process which can take up to four hours.
In the first flow I generate a key value with a time stamp in it as the payload and then use it to set the ProcessState to the static value 'Started' in an ObjectStore as shown below. After which I fire a Quartz Outbound Endpoint with a four hour delay.
<objectstore:store config-ref="MonitoredProcess" value-ref="Started" key="#[payload]" doc:name="ObjectStore"/>
<quartz:outbound-endpoint jobName="ProcessMonitor" responseTimeout="10000" doc:name="Quartz"
repeatInterval="0" repeatCount="0" startDelay="${process.monitor.event.start.delay}">
<quartz:scheduled-dispatch-job>
<quartz:job-endpoint address="vm://processMonitorQueue"/>
</quartz:scheduled-dispatch-job>
</quartz:outbound-endpoint>
And I got the same exception.
After scratching my head and lots of searches the name of the variable 'value-ref' in combination with David's answer above finally revealed my problem namely the MEL is always invoked for this ref field.
As soon as I changed the field to an expression #['Started'] that MEL could evaluate my problem went away.
<objectstore:store config-ref="MonitoredProcess" value-ref="#['Started']" key="#[payload]" doc:name="ObjectStore"/>
For completeness I've included the code that retrieves the ProcessState from the ObjectStore. Note the defaultValue-ref also needs to use MEL
<vm:inbound-endpoint exchange-pattern="one-way" path="processMonitorQueue" doc:name="VM" />
<objectstore:retrieve config-ref="MonitoredProcess" defaultValue-ref="#['DoesNotExist']" key="#[payload]" targetProperty="processState" doc:name="ObjectStore"/>
i have a Mule flow that gathers calculations information from an external service to enrich a list of Invoices. So, I end up (after the enricher scope) with my calc info in a flow variable, and my original invoices in the payload.
Can I use the data mapper to inject my calculation values into the existing invoice objects?
Currently I'm using a Groovy script - but prefer config over scripting.
You can use the datamapper transformer within an enricher scope to enrich parts of the payload.
The enricher can enrich the payload if you set the 'target' to a named field on a POJO for example, or if your payload is a Map, the enricher will add a new entry to the Map.
<enricher>
<datamapper... />
<enrich target="#[payload.field1]" source="#[payload.datamapperoutputfield1]" />
<enrich target="#[payload.field2]" source="#[payload.datamapperoutputfield1]" />
</enricher>
I want to enrich my message (POJO) properties from original payload stored in flow variable
<set-variable variableName="SupplierRequest" value="#[payload]" doc:name="SupReq"/>
<flow-ref name="GetSupplierRequestDetail" doc:name="GetReqData"/>
<set-variable variableName="SupplierRequestData" value="#[payload]" doc:name="SupReqData"/>
In above code, I need couple of SupplierRequestData POJO properties to be set with properties from SupplierRequest POJO.
Do I need to write custom transformer or any other solution?
Ideally you should use the enritcher. But given that you already have the original payload in a flow variable you could just use an expression component as an expression transformer would imply a transformation from A to B while this is modification of A with B:
<expression-component><![CDATA[message.payload.propertyName = flowVars.myOrigPayload.myProp]]></expression-component>