how to make skipNullOn dynamic in dataweave script? - mule

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

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>

How to write CSV over and over within For-each loop in Mule 3?

Im trying to write CSV within For-each loop in Mule 3.
Reading CSV file
Passing parameter to the API to get response
if no response, will write into another csv file. To maintain parameter value i set record variable before API calling and no matches, would write into CSV.
But CSV file not generating within For-each loop.
<foreach collection="#[payload.names]" doc:name="For Each">
<foreach collection="#[payload.names]" doc:name="For Each">
<batch:set-record-variable variableName="userName" value="#[payload.Name]" doc:name="Record Variable"/>
<http:request config-ref="HTTP_Request_Configuration" path="/users" method="GET" doc:name="Users">
<http:request-builder>
<http:query-param paramName="name" value="#[payload.Name]"/>
</http:request-builder>
</http:request>
<choice doc:name="Choice">
<when expression="#[payload.results.size()>0]">
<dw:transform-message doc:name="Transform Message" >
<dw:input-payload mimeType="application/java"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/csv
---
[payload]]]></dw:set-payload>
</dw:transform-message>
<set-payload value="#[recordVars.userName]" doc:name="Set Payload"/>
<file:outbound-endpoint responseTimeout="10000" doc:name="File" outputPattern="users.csv" path="C://output"/>
</otherwise>
</choice>
</foreach>
</foreach>

Mule Cache Scope How to invalidate mule cache for no payload of DB output

We would like to use DB query inside mule cache scope.
Wants to store the output of DB query in cache to save DB query trip.
If the DB query doesn't give any output or payload is empty, we dont want to save in mule cache.
How to invalidate the cache of the empty payload entries ?
thank you.
The answer to this is in mule forum, https://forums.mulesoft.com/questions/84675/mule-cache-scope-how-to-invalidate-mule-cache-for.html
<ee:cache cachingStrategy-ref="Caching_Strategy" filterExpression="#
[payload
!= 'testData']" doc:name="Cache">
<db:select config-ref="DBConfig" fetchSize="100"
doc:name="Database">
<db:dynamic-query><![CDATA[select * from STUDENT where
student_id = 'TEST']]></db:dynamic-query>
</db:select>
<choice doc:name="Choice">
<when expression="#[message.payload.size() == 0]">
<logger message="Payload is empty" level="INFO"
doc:name="Logger"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
payload]]></dw:set-payload>
</dw:transform-message>
</when>
<otherwise>
<object-to-string-transformer doc:name="Object to String"/>
</otherwise>
</choice>
<logger message="After Choice" level="INFO" doc:name="Logger"/>
</ee:cache>

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 retrieve statusCode from ApiKit mapping in Mule

We want to process all of the exceptions we catch with the same process in our exception strategy. It is the one generated by apikit. We first send a lot with a custom component and then we generate json response. In the response with DataWeave we want to set the same statusCode. However, the statusCode do not seem to be a variable that is retrievable. Am I correct, or there is a good way to retrieve it?
<apikit:mapping-exception-strategy xmlns:apikit="http://www.mulesoft.org/schema/mule/apikit" name="svc0031_hotel-apiKitGlobalExceptionMapping">
<apikit:mapping statusCode="504">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
<apikit:mapping statusCode="404">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
</apikit:mapping-exception-strategy>
<sub-flow name="svc0031_manageErrors">
<set-payload value="#[groovy:message.exceptionPayload.rootException.message]" doc:name="Set BIP Payload"/>
<custom-transformer class="se.zystems.baseline.BaselineLogging" doc:name="Log BIP Outgoing">
<spring:property name="Level" value="ERROR"/>
<spring:property name="ObjectId" value="CatchErrors"/>
<spring:property name="TransactionStatus" value="failed"/>
</custom-transformer>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : 400,
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
<logger level="INFO" doc:name="Logger"/>
</sub-flow>
Good,
If you create a variable with the http.status then you can use it in the mapper:
<flow name="test">
<set-variable variableName="httpStatus" value="#[message.inboundProperties['http.status']" doc:name="Variable"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : flowVars.httpStatus,
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
</flow>
I found out where the statusCode value is stored thanks to the answer by Jesús Pablo Fernández
He was almost right in his answer, however, the statusCode is stored not in message.inboundProperties['http.status'], but in message.outboundProperties['http.status']. No need to even extract a variable, one can just access it in data transformer directly like this:
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
status : outboundProperties['http.status'],
message : payload,
code : 42,
more_info :"https://anypoint.mulesoft.com/apiplatform/nordic-choice-hotels"
}]]></dw:set-payload>
</dw:transform-message>
Status codes defined in the APIKitExceptionStrategy will be those sent back in the response header as http.status given the corresponding exception to be raised.
For instance,
<apikit:mapping statusCode="504">
<apikit:exception value="org.mule.api.transformer.TransformerMessagingException"/>
<flow-ref name="svc0031_manageErrors" doc:name="Manage Error"/>
</apikit:mapping>
means that when a org.mule.api.transformer.TransformerMessagingException exception is thrown and caught by this exception block, then a 504 status code is sent back as a response header.
If you want to bypass the statusCode attribute in the APIKit exception block, you should have another exceptionStrategy block to catch your desired exception, and then you could set your status code like that
<set-property name="http.status" value="<the_desired_status, e.g. 401>" />
Hope it helps.
/Tony
Good Stanislav Ivanov,
I have a flow implemented with the APIKit, which is the code that I attach and whether there is property in the inboundProperties http.status, review it because if it should contain the value, if you do not have your flow may modify the value in a previous step.
I pointed him to directly access the outboundProperties in the mapper, I was not aware, thank you very much.