Mule 3 How to Declare multiple flow variables - mule

I am new to Mule and I am using Mule version 3.x. We can set values of variable using Set Variable Component. And using expression component, we can set multiple variables at a time. But expression component does not allow to Declare a flow variable. So I have to first use 3 Set Variable component and then use expression to set them at one go(if it needs to be changed).
In case of multiple variables, is there any way to declare and initialize variable in one component instead of having a separate Set Variable component to declare it?

The Message Properties Transformer
If you want to set multiple flow vars in a single component in Mule 3, and you don't need to do any transformation beforehand, the Message Properties transformer is probably the most succinct ways to do this. I like it because in addition to being able to set multiple flow vars in a single component, the XML is clear, and when you click on the component in AP Studio, the UI makes it immediately obvious that you're setting multiple variables with a single component. Just make sure to use scope="invocation" so that you're setting flow vars:
<message-properties-transformer scope="invocation" doc:name="Set flowVars">
<add-message-property key="varName1" value="1"/>
<add-message-property key="varName2" value="2"/>
<add-message-property key="varName3" value="2"/>
</message-properties-transformer>
If you need to do small transformations, you can always call DataWeave from MEL. Here's an example:
...
<add-message-property key="varName1" value="dw('payload map $.id')"/>
...
The Transform Message Component (DataWeave)
You can also do this in DataWeave with the Transform Message component as well. I do feel it has a couple disadvantages that I should point out, though. The first is the XML is more verbose and difficult to read:
<dw:transform-message doc:name="Transform Message">
<dw:set-variable variableName="varName1"><![CDATA[%dw 1.0
%output application/java
---
1]]></dw:set-variable>
<dw:set-variable variableName="varName2"><![CDATA[%dw 1.0
%output application/java
---
2]]></dw:set-variable>
<dw:set-variable variableName="varName3"><![CDATA[%dw 1.0
%output application/java
---
3]]></dw:set-variable>
</dw:transform-message>
In addition, there is no obvious way to tell from the AP Studio UI that this particular transform message component is setting multiple variables:

If you're using enterprise edition, please use dataweave to set multiple variables in one component.
Runtime 4.1
https://docs.mulesoft.com/mule-runtime/4.1/dataweave-variables
Runtime 3.8
https://docs.mulesoft.com/mule-runtime/3.8/dataweave

I would like to know why do you need to just declare variables. Anyways if in case you just need it blank while declaring, you can simply set it as below.
<expression-component doc:name="Expression">
<![CDATA[flowVars.var1 ="" ;
flowVars.var2="";]]>
</expression-component>
Hope this help.

Related

Mule : Use dynamic config-ref based on input values

I'm trying to connect to SQL Database with some configuration. But based on the input from the API we are supposed to hit different DB.
As of now, we have the code as
<choice doc:name="Check myFlag">
<when expression="#[flowVars.myFlag == 'true']">
<db:stored-procedure config-ref="Database_Configuration_1" doc:name="DB_config_1">
<db:dynamic-query><![CDATA[#[flowVars.callSPName]]]></db:dynamic-query>
</db:stored-procedure>
</when>
<otherwise>
<db:stored-procedure config-ref="Database_Configuration_2" doc:name="DB_config_2">
<db:dynamic-query><![CDATA[#[flowVars.callSPName]]]></db:dynamic-query>
</db:stored-procedure>
</otherwise>
</choice>
Instead of repeating <db:stored-procedure../> twice, is there a way where I can set a flow var with the DB config reference and use it?
Something like,
<db:stored-procedure config-ref="#[flowvars.db_config]" doc:name="DB_config_2">
<db:dynamic-query><![CDATA[#[flowVars.callSPName]]]></db:dynamic-query>
</db:stored-procedure>
In Mule 3, no. config-ref's are evaluated at application startup, not runtime.
In Mule 4 this is possible using Dynamic Configurations: https://docs.mulesoft.com/mule-sdk/1.1/static-dynamic-configs
Potential Mule 3 solutions documented here: https://help.mulesoft.com/s/article/How-to-configure-connector-with-dynamic-parameters
Put the DB call inside a sub-flow and call it from the rest of the flows with a <flow-ref>.

How to set a variable as a resource in dataweave component?

My DataWeave configuration is as below.
<dw:transform-message metadata:id="5b272b5c-4f37-4e09-8608-756169041833" doc:name="Transform Message">
<dw:set-payload resource="file:D:/Disc/sample.dwl"></dw:set-payload>
</dw:transform-message>
I am trying to externalize the transformation logic from the above.
My question is: Instead of using the file path directly in the RESOURCE attribute can I use a variable which has the file path in it? If yes, how do I achieve it? Thanks in advance.
Use properties, with properties you can replace this value and store them in an external file:
https://docs.mulesoft.com/mule-user-guide/v/3.7/configuring-properties

How to enrich the response from original payload

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>

XPATH in mule flow returns multiple values

I have a requirement where I run xPath evaluator against xml payload in mule flow. This xPath evaluator can return single or multiple values. I need to store these values in flow variable and use somewhere later in the flow. Can someone help me implementing this changes?
Appreciate your help on this.
Thanks
For extracting values from an XML document, use the XPath extractor.
<mulexml:xpath-extractor-transformer expression="/a:my/b:xpath/text()"/>
You can also use Mule Expression Language to create dynamic XPath expressions:
<expression-transformer mimeType="text/xml" evaluator="xpath" expression="//school/day[#date= #[function:datestamp:yyyy-MM-dd] ]/name
"/>
However this can get somewhat messy for complicated expressions, so I have created my own dynamic XPath transformer:
<dx:dxpath expression="/b:team[name = $teamName]/b:player[b:name = $playerName]/b:goals/text()">
<dx:variable key="playerName" value="#[header:invocation:playerName]"/>
<dx:variable key="teamName" value="#[header:invocation:teamName]"/>
<!-- unlimited number of variables -->
</dx:dxpath>
which is somewhat more easy on the eyes.
Then Wrap your flow with an ericher:
<enricher target="#[variable:myData]">
<processor-chain>
<!-- your flow here -->
</processor-chain>
</enricher>

Mule Performing a string manipulation

What is the best way to perform a string manipulation. I wish to perform a substring on a email address to extract the domain detail and populate this to a variable.
a java transformer is a possibilty, but i was hoping if i could use a message enricher with a expression to perform this operation.
pardon me but i am still a greenhorn on Mule.
here is the excerpt from my mule flow which is failing with error cannot resolve method string length.
<enricher target="#[flowVars['FromAddressDomain']]" doc:name="Message Enricher">
<expression-transformer expression="#[ payload.fromAddr.substring(payload.fromAddr.lastIndexOf('#')+ 1,payload.fromAddr.lenth())]" doc:name="Expression"></expression-transformer>
</enricher>
Simply use:
<set-variable variableName="FromAddressDomain"
value="#[org.mule.util.StringUtils.substringAfter(payload.fromAddr, '#')]" />
You can use dataweave transform on payload and use the operator splitby and spilt on # character. Please take a look at below link for more information on splitby operator
https://docs.mulesoft.com/mule-user-guide/v/3.9/dataweave-operators#split-by