Dataweave code in mule custom policy configuration - mule

I am working on creating custom policy in mule.
In configuration XML of the policy I am seeing various mule: transformers, set variable, loggers etc. while adding in before tag (<before/>) but dataweave.
I want to include dataweave code snippet in the configuration file (custom_policy.xml).
Can I have a chance to do that?

As per the example here you can use dataweave transform message component in your custom policy:
refer: https://github.com/JeyaramD/mule-custom-jwt-policy/blob/master/jwt-validation-policy/jwt-validation-policy.xml
<before>
.......
.......
<dw:transform-message doc:name="Transform Message" metadata:id="82cc8c48-d8bd-48aa-bf1d-ac1e7bc74f59">
<dw:input-payload doc:sample="sample_data/json.json"/>
<dw:input-variable variableName="jwtHeader"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
"-----BEGIN CERTIFICATE-----\n" ++ payload.keys[?($.kid == flowVars.jwtHeader.x5t)].x5c[0][0] ++ "\n-----END CERTIFICATE-----"]]></dw:set-payload>
</dw:transform-message>
...............
...............

Related

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.

Pass http header value to the web service consumer

I am trying to pass the http header value as the web service consumer,
httpHeader
I use this property as web service input,
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 namespace
---
{
ns0#GetProject: {
ns0#projectId: inboundProperties."http.query.params".projectId,
ns0#upi: inboundProperties.sm_user
}
}]]></dw:set-payload>
</dw:transform-message>
I have also tried setting the sm_user to a variable and trying to access the variable in TransformMessage as below, but the same error,
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 namespace
---
{
ns0#GetProject: {
ns0#projectId: inboundProperties."http.query.params".projectId,
ns0#upi: flowVars.setUPI
}
}]]></dw:set-payload>
</dw:transform-message>
Error:
Server was unable to read request. ---> There is an error in XML document (3, 32). ---> Input string was not in a correct format.. Message payload is of type: ElementNSImpl
Transform XML using the SM_USER header:
<?xml version='1.0' encoding='windows-1252'?>
<ns0:GetProject xmlns:ns0="namespace">
<ns0:projectId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<ns0:upi xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</ns0:GetProject>
Flow XML:
<flow name="ProjectEC">
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/xml
%namespace ns0 namespace
---
{
ns0#GetProject: {
ns0#projectId: inboundProperties."http.query.params".projectId ,
ns0#upi: inboundProperties.SM_USER
}
}]]></dw:set-payload>
</dw:transform-message>
<ws:consumer config-ref="ECDataService_Consumer" operation="GetProject" doc:name="ECWebServiceConsumer"/>
<mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
<json:xml-to-json-transformer doc:name="XML to JSON"/>
<set-variable variableName="extractJsondata" value="#[json:GetProjectResponse/GetProjectResult]" mimeType="application/json" doc:name="Variable"/>
<set-payload value="#[flowVars.extractJsondata]" doc:name="Set Payload"/>
<json:xml-to-json-transformer doc:name="XML to JSON"/>
</flow>
Can someone tell me if I am missing something.
Thanks
Few checks
Check whether your xml is the exact format which your webservice is really looking for. or
Change the encoding from encoding='windows-1252' to UTF-8. Follow the url Output Encoding issue in mule esb. or
As trial and error version directly use the xml in postman to hit webservice ( without making dataweave to do the transformation). or
Make sure you have no space <?xml version='1.0' encoding="UTF-8"?> before starting of xml greater sysmbol tag.
Check the above 4 steps anyone of this might cause issue. Step 3 will be helpful for testing.

Looping in DataWeave in MuleSoft

i have a requirement where in i need to extract the LoadReferenceNumber and assign to a variable which is initiated inside the data weave when the LoadReferenceNumberType is MB in mule, below is the xml
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<CIS>
<LoadReferenceNumberList>
<LoadReferenceNumberType>MB</LoadReferenceNumberType>
<LoadReferenceNumber>8070296</LoadReferenceNumber>
</LoadReferenceNumberList>
<LoadReferenceNumberList>
<LoadReferenceNumberType>ACT_SP_DATE</LoadReferenceNumberType>
<LoadReferenceNumber>20160404T14:12:00</LoadReferenceNumber>
</LoadReferenceNumberList>
<LoadReferenceNumberList>
<LoadReferenceNumberType>SP_DATE</LoadReferenceNumberType>
<LoadReferenceNumber>20170404T14:12:00</LoadReferenceNumber>
</LoadReferenceNumberList>
</CIS>
The example below is a dataweave component which extract the LoadReferenceNumber from LoadReferenceNumberList where LoadReferenceNumberType == 'MB':
<dw:set-variable variableName="LoadReferenceNumber"><![CDATA[%dw 1.0
%output application/java
---
value: ((payload.CIS.*LoadReferenceNumberList filter $.LoadReferenceNumberType == 'MB')[0].LoadReferenceNumber) default null]]></dw:set-variable>
</dw:transform-message>
The result is a LinkedHashMap, the example below is logger which logs the LoadReferenceNumber:
<logger message="#[flowVars.LoadReferenceNumber.value]" level="INFO"
doc:name="Logger" />
Hope this helps :)
you use that data weave
%dw 1.0
%output application/java
---
value: ((payload.CIS.*LoadReferenceNumberList filter $.LoadReferenceNumberType == 'MB')[0].LoadReferenceNumber) default null

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!

Mule: Can we remove multiple keys from a map using message property component

<message-properties-transformer doc:name="Message Properties" scope="outbound">
<delete-message-property key="#[payload.remove('5F2A')]"/>
<delete-message-property key="#[message.outboundProperties.remove('9F37')]"/>
</message-properties-transformer>
Please suggest a way in mule where I can remove multiple keys wherein the payload is of Map type
You could use a transformer or component to remove the keys that you want:
Here is an example using a transformer:
#Override
public Object transformMessage(MuleMessage message, String outputEncoding)
throws TransformerException {
message.removeProperty("5F2A", PropertyScope.OUTBOUND);
}
Alternatively, if you are using the enterprise version of the Mule runtime, multiple properties can be removed from a Map payload via DataWeave script within a Message Transformer component, as demonstrated by the following code snippet:
...
<dw:transform-message doc:name="Transform Message">
<dw:input-payload mimeType="application/java"/>
<dw:set-payload><![CDATA[%dw 1.0
%output application/java
---
payload mapObject {
($$): ($)
} - "5F2A" - "9F37"]]></dw:set-payload>
</dw:transform-message>
...