Generating random numbers in mule dataweave - mule

I have to concatenate randomly generated number with the field from request in dataweave.
NUMBR: "AA" ++ $.Load.Reference.*Reference ++ RandomNumber
How to achieve this in Mule Dataweave

Not sure what you can do in Datawevae to do this, but you can you set a Random number in a flowVariable and invoke it from your Dataweave script like so:
<set-variable variableName="random"
value="#[new java.util.Random().nextInt(100)]" doc:name="Variable" />
<dw:transform-message doc:name="Transform Message">
<dw:input-variable doc:sample="unknown.dwl" variableName="random" />
<dw:set-payload>
<![CDATA[%dw 1.0
%output application/dw
---
{
"data": ("22" as :number + flowVars.random)
} ]]>
</dw:set-payload>
</dw:transform-message>

You can also use Expression Component to assign it to Payload or variables and then concatenate
<flow name="random-numbersFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/random" allowedMethods="GET" doc:name="HTTP"/>
<expression-component doc:name="Expression"><![CDATA[payload = new java.util.Random().nextInt(100)]]></expression-component>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
data: payload
}]]></dw:set-payload>
</dw:transform-message>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</flow>

You can't do this in pure DataWeave but you could use two methods to generate the number elsewhere in the application:
You could call a global MEL function from DataWeave: https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-reference-documentation#global-mel-functions
You could call a flow that returns the value: https://docs.mulesoft.com/mule-user-guide/v/3.7/dataweave-reference-documentation#expressions-that-call-external-flows

Just set a random value generated by Java into a Flow Variable
<set-variable variableName="Random_Variable" value="#[java.util.Random().nextInt(10)]" doc:name="Random Variable"/>
Then Use that Flow Variable in your Dataweave Transform.
<dw:transform-message doc:name="Transform Message" metadata:id="8098b24c-30c1-4e9e-a3ce-9e8aaaec7bd1">
<dw:input-variable mimeType="application/java" variableName="Random_Variable"/>
<dw:set-payload><![CDATA[%dw 2.0
%output application/json
---
{
NUMBR: "AA" ++ $.Load.Reference.*Reference ++ flowVars.Random_Variable
}]]></dw:set-payload>
</dw:transform-message>

In Mule 4 Dataweave 2 function random()
Returns a pseudo-random number greater than or equal to 0.0 and less than 1.0
MULE 4 DOC:
https://docs.mulesoft.com/dataweave/2.3/dw-core-functions-random
Example:
%dw 2.0
output application/json
{ price: random() * 1000 }

Related

Add one more element to the object array inside for each loop in mule 3

I have Input as below
[{Name=ABC, ID=123},{Name=XYZ, ID=345}]
I would iterate over this collection in a for-each loop and add one more element Age to each object.
My expected output would be like
[{Name=ABC, ID=123, Age=23},{Name=XYZ, ID=345, Age=24}]
Any help would be highly appreciated. Thanks in advance.
HTH..
%dw 2.0
output application/json
var inp = [
{
"Name":"ABC",
"ID":"123"
},
{
"Name":"XYZ",
"ID":"345"
}
]
---
inp map {
($),
age: (23 + ($$)) // or your logic to derive age
}
It was not possible with DW as because payload inside for-each was modified. So I tried using Expression component. Below is my configuration XML.
<flow name="add-one-more-element-to-the-original-payload">
<poll doc:name="Poll">
<fixed-frequency-scheduler frequency="30" timeUnit="SECONDS"/>
<logger message="Pooling Started" level="INFO" doc:name="Log"/>
</poll>
<dw:transform-message doc:name="Transform Payload">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
%var collection = [{"Name":"ABC","ID":123},{"Name":"XYZ","ID":345}]
---
collection]]></dw:set-payload>
</dw:transform-message>
<set-variable variableName="outputList" value="#[new java.util.ArrayList()]"
doc:name="Set Variable"/>
<foreach doc:name="For Each" collection="#[payload]">
<dw:transform-message doc:name="CurrentPayload">
<dw:set-variable variableName="currentPayload"><![CDATA[%dw 1.0
%output application/java
---
payload]]></dw:set-variable>
</dw:transform-message>
<flow-ref name="get-age-subflow" doc:name="Get Age"/>
<expression-component doc:name="Expression"><!
[CDATA[flowVars.currentPayload.Age=payload.Age;]]></expression-component>
<expression-transformer expression="#
[flowVars.outputList.add(flowVars.currentPayload)]" doc:name="Expression"/>
</foreach>
<logger message="#[flowVars.outputList]" level="INFO" doc:name="Logger"/>
</flow>
<sub-flow name="get-age-subflow">
<dw:transform-message doc:name="Transform Age">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
Age:24
}]]></dw:set-payload>
</dw:transform-message>
</sub-flow>

Aggregation in ForEach in Mule 4

I want to aggregate the responses of each iteration of For Each. In each iteration I am getting Json data and I want to aggregate that Json data into Json Array/List. Please let me know how I can do that by using data weave in Transform or by any other way?
Below is sample Json data that I am getting in each iteration of For Each.
1st iteration:
{
"accountId": "12345",
"accountNumber": "999",
"accountTitle": "ABC"
}
2nd iteration:
{
"accountId": "98765",
"accountNumber": "888",
"accountTitle": "XYZ"
}
I want final aggregated output as below.
{
accountList: [
{
"accountId": "12345",
"accountNumber": "999",
"accountTitle": "ABC"
},
{
"accountId": "98765",
"accountNumber": "888",
"accountTitle": "XYZ"
}
]
}
You can follow something like
<!-- Define blank arraylist for aggregation -->
<dw:transform-message doc:name="Transform Message">
<dw:set-variable variableName="result"><![CDATA[%dw 1.0
%output application/java
---
[]]]></dw:set-variable>
</dw:transform-message>
<foreach doc:name="For Each">
<!-- generate response using flow logic and add following step for updating result array -->
<dw:transform-message doc:name="Transform Message">
<dw:set-variable variableName="result"><![CDATA[%dw 1.0
%output application/java
---
flowVars.result ++ [payload]]]></dw:set-variable>
</dw:transform-message>
</foreach>
<!-- Transform aggregated result to any format. I used JSON -->
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
accountList : flowVars.result]]></dw:set-payload>
</dw:transform-message>
I have used Mule 3.x syntax. For mule 4 you can use attribute instead of variable for storing records. Dataweave syntax will remain same except for changing Dataweave language version from 1.0 to 2.0.
Hope this helps.

Mule - Converting String to Date

I have a csv file which looks like this :
I am iterating the CSV file using For each after converting it to Java ArrayList using Dataweave.
Now, I need to convert one of the elements which is Date from String to Oracle Timestamp. Please help with your thoughts. The source code looks like this :
<flow name="testFlow">
<file:inbound-endpoint path="src/main/resources/input"
moveToDirectory="src/main/resources/output" connector-ref="File"
responseTimeout="10000" doc:name="File"/>
<dw:transform-message metadata:id="4e33c7ff-c33b-4c78-be34-79a154aa16df"
doc:name="Transform Message">
<dw:input-payload doc:sample="sample_data\list_csv.csv"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
payload]]></dw:set-payload>
</dw:transform-message>
<logger level="INFO" doc:name="Logger"/>
<foreach collection="#[payload]" doc:name="For Each">
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
</foreach>
</flow>
Flow design looks like this :
Basically what you need to do is to convert the date field which is a string in csv to date format. To do it just provide the format of the incoming data field and it will work for the below input example(csv is comma separated) :-
foo,bar,Name,Date
foo1,baar1,Name1,15-01-2016 12:08
foo2,baar2,Name2,15-01-2016 12:08
you can try below dw :-
%dw 1.0
%output application/java
---
payload map {
foo : $.foo,
bar : $.bar,
Name : $.Name,
Date : $.Date as :date {format: "dd-MM-yyyy hh:mm" }
}

how to make skipNullOn dynamic in dataweave script?

Based on Boolean variable I want to get output. If variable is true null parameters should not visible in output and if false null parameters should be visible. How to make skipNullOn dynamic in mule dataweave script?
#swamy Thota not sure if you can do it in dataweave.
Alternate option i can think off is, use choice and 2 dataweaves, one will skip null and other will allow null.
Please use a flow variable , the use a choice and create two different mapping one for true condition and one for false.
It will be something as below
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:encryption="http://www.mulesoft.org/schema/mule/encryption" xmlns:http="http://www.mulesoft.org/schema/mule/http"
<flow name="file2fileFlow">
<file:inbound-endpoint path="D:\Tushar\Training\DataWeave\in" moveToDirectory="D:\Tushar\Training\DataWeave\out" responseTimeout="10000" doc:name="File"/>
<set-variable variableName="test" value="#['a']" doc:name="Variable"/>
<choice tracking:enable-default-events="true" doc:name="Choice">
<when expression="#[flowVars.test] == 'a'">
<dw:transform-message doc:name="If Value True">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
}]]></dw:set-payload>
</dw:transform-message>
</when>
<otherwise>
<dw:transform-message doc:name="If Value false">
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
{
}]]></dw:set-payload>
</dw:transform-message>
</otherwise>
</choice>
<logger level="INFO" doc:name="Logger"/>
<file:outbound-endpoint outputPattern="output.txt" responseTimeout="10000" doc:name="File"/>
</flow>
</mule>
You can load dw script from file and dynamic replace in text script skipNullOn value. Then, call the MEL function #[dw(<script>, [<output type>] ]
More examles you can see there: https://support.mulesoft.com/s/article/ka4340000004GbvAAE/Dynamic-DataWeave-Script

Mule :How to set a variable with part of xml data from the response xml of a webservice

I have a response xml as below which comes from web service consumer. I want to extract the Response node, into a variable and use it in another sub-flow (Transform message input to add cdata tag to it). The request part of the response xml will be used in the same flow for some transformations using dataweave. The variable is empty when retrieved with xpath (#[xpath3('//GetTransactionResponse/GetTransactionResult/Response')]), since its a node with xml struture in it. Highly appreciate any solution with this please.
<?xml version="1.0" encoding="UTF-8"?>
<GetTransactionResponse xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<GetTransactionResult>
<Request>
<Security>
<SystemUsername>53A5949A</SystemUsername>
<SystemPassword/>
<SystemID/>
</Security>
</Request>
<Response>
<Scheme>
<Ins>
<InsReference>200</InsReference>
<InsNumber>200</InsNumber>
<InsName/>
</Ins>
</Scheme>
</Response>
</GetTransactionResult>
</GetTransactionResponse>
Thank you for your time!
The other way to get response in variable by using additional target in your dataweave. And use following script
%dw 1.0
%output application/xml
---
Response : payload.GetTransactionResponse.GetTransactionResult.Response
Your XML contains is not a valid XML as it's starting and end tags doesn't match... example :-
<InsReference>200</InsurerReference>
<InsNumber>200</InsurerNumber>
However, if you make the expression will work as follows #[xpath3('/GetTransactionResponse/GetTransactionResult/Response')]
You can transform the response to json and set variables via json expression.
<flow name="xmlparserFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/xml" allowedMethods="POST" doc:name="HTTP"/>
<dw:transform-message metadata:id="864f45d9-f193-4e82-8f9f-f689a2e13450" doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%var response=payload.GetTransactionResponse.GetTransactionResult.Response.Scheme.Ins
%output application/json
---
{
reference: response.InsReference,
number: response.InsNumber,
name: response.InsName
}]]></dw:set-payload>
</dw:transform-message>
<set-variable variableName="reference" value="#[json:reference]" doc:name="Set Variable"/>
<logger message="#[message]" level="INFO" doc:name="Logger"/>
<object-to-string-transformer doc:name="Object to String"/>
</flow>
hope this helps.
I was able to achieve finally by setting the Response and Request variables in the dataweave as below:
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
---
payload]]></dw:set-payload>
<dw:set-variable variableName="Request"><![CDATA[%dw 1.0
%output application/xml
---
{
Request: payload.GetTransactionResponse.GetTransactionResult.Request
}]]></dw:set-variable>
<dw:set-variable variableName="Response"><![CDATA[%dw 1.0
%output application/xml
---
{
Response: payload.GetTransactionResponse.GetTransactionResult.Response
}]]></dw:set-variable>
</dw:transform-message>
Appreciate all for your time.Thanks!