mule remove json elements from json array - mule

I had json input like below
"products": {
"p0": {
"productId": "110",
"productName": "bag"
},
"p1": {
"productId": "160",
"productName": "shoe"
},
"p2": {
"productId": "140",
productName": "watch"
}
}
From mule I want the output like the one below
[
{
"productId": "110",
"productName": "bag"
},
{
"productId": "160",
"productName": "shoe"
},
{
"productId": "140",
"productName": "watch"
}
]
Because I need to pass the above output format to other inbound.
Anyone help how to convert my input json into above output json.
Thanks in advance for all

You can achieve what you want using some MEL and json transformers:
<json:json-to-object-transformer
returnClass="java.util.HashMap" />
<set-payload value="#[($.value in payload.products.entrySet())]" />
<json:object-to-json-transformer />
If you're going to have more complex transformation, I would write a custom transformer, or script transformer using Groovys JsonBuilder and JsonSlurper or potentially Datamapper.

If you are using Mule 3.7 and above, you can do it simply and easily with the dataweave component :-
<flow name="Testlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/test" doc:name="HTTP"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
payload.products map (
$
)
]]></dw:set-payload>
</dw:transform-message>
</flow>

Related

Combining Local business with Service & Area served schema

When I insert this code in the structured data testing tool I am only getting the first schema to show up. I can switch the order of the Local business and service w/ area served but when I do that only one of them shows up in the tool. The same thing happens when I try to split the two up and get them individually.
Working with json-ld scripts:
<script type="application/ld+json">
{
"#context": "https://schema.org",
"#type": "ProfessionalService",
"name": "Sebastian River Exterminating",
"image": "http://sebastianriverexterminating.com/images/extermination-logo-sebastian-fl.png",
"#id": "",
"url": "http://sebastianriverexterminating.com/",
"telephone": "7722289969",
"address": {
"#type": "PostalAddress",
"streetAddress": "124 Salazar Lane",
"addressLocality": "Sebastian",
"addressRegion": "FL",
"postalCode": "32958",
"addressCountry": "US"
},
"geo": {
"#type": "GeoCoordinates",
"latitude": 27.7600115,
"longitude": -80.50620599999999
},
"openingHoursSpecification": {
"#type": "OpeningHoursSpecification",
"dayOfWeek": [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday"
],
"opens": "08:00",
"closes": "18:00"
},
"sameAs": "https://www.facebook.com/SebastianRiverExterminatingFL/timeline"
}
{
"#context": "http://schema.org",
"#type": "Service",
"serviceType": "Exterminator",
"additionalType": "https://en.wikipedia.org/wiki/Pest_control",
"areaServed": [
{
"#type": "City",
"name": "Sebastian",
"#id": "https://en.wikipedia.org/wiki/Sebastian,_Florida"
},
{
"#type": "City",
"name": "Roseland",
"#id": "https://en.wikipedia.org/wiki/Roseland,_Florida"
}
]}
</script>
That is not valid json or json-ld. You can only add one object to each script. e.g.
<script type="application/ld+json">
{
...
}
</script>
You can't list objects like you did.
One way around the issue is to add each into their own script tag.
Another is to use #graph to add them as an array inside an object. e.g.
<script type="application/ld+json">
{
"#graph": [
{
...
},
{
...
}
]
}
</script>
I believe you should use a sameAs not an #id in this case, since you are providing a reference for the search engine. also, I don't believe #id is a valid property of areaServed

MULE - ESB - how to set the header for the outbound message

I am trying to set the header values for the outbound message.
I can see the values in the http.headers in the debugging mode. However it is not displaying the postman's header.
And below is the snippet
As you can see I have tried to set up header using two different ways
{code}
**<set-property propertyName="http.headers.code" value="C01" doc:name="headerCode"/>**
<set-payload value="{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"main": {
"temp": 290.24,
"pressure": 1016,
"humidity": 77,
"temp_min": 288.15,
"temp_max": 292.15
},
"id": 2643743,
"name": "London",
"cod": 200
}" doc:name="Set Payload"/>
**<message-properties-transformer doc:name="Message Properties">
<add-message-property key="http.headers.id" value="ID01" />
</message-properties-transformer>**
<logger message="header-property logger" level="INFO" doc:name="Logger"/>
</flow>
{code}
Attached debugging screenshot
Debugging screenshot
postman collection screenshot
I have expected to see the values in the headers. But it is not displaying
Could anyone shed light on this please.
Thank you and regards
Nivi
When setting outbound properties in Mule (my experience being with 3.8 onwards) they will default to the HTTP header, so you do not need to include 'http.headers.' in your property element, only the name of the header you wish to add.
E.g. if your set-property element is:
<set-property propertyName="id" value="ID01" doc:name="Add ID Header" />
Then when calling the service this will add "id" as an HTTP response header.
My whole flow is:
<flow name="testFlow">
<http:listener config-ref="HTTP_Listener_Configuration"
path="/test" doc:name="HTTP" />
<set-payload
value="{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"main": {
"temp": 290.24,
"pressure": 1016,
"humidity": 77,
"temp_min": 288.15,
"temp_max": 292.15
},
"id": 2643743,
"name": "London",
"cod": 200
}"
doc:name="Set Payload" />
<set-property propertyName="id" value="ID01" doc:name="Add ID Header" />
</flow>
When I send a request to this flow I receive the HTTP header as expected:
curl -v http://localhost:8091/test
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8091 (#0)
> GET /test HTTP/1.1
> Host: localhost:8091
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200
< id: ID01 <=============
< Content-Length: 244
< Date: Tue, 10 Jul 2018 22:44:51 GMT
<
{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"main": {
"temp": 290.24,
"pressure": 1016,
"humidity": 77,
"temp_min": 288.15,
"temp_max": 292.15
},
"id": 2643743,
"name": "London",
"cod": 200
}
Hope that helps!
Johnson.

How to concatenate a flowVar to Json payload in Mule Dataweave

incoming payload:
{
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
}, {
"ID": "89k873c8",
"Code": "CTY"
}
]
}
flowVar value is an ArrayList: ([84hkj569],[6j93hl9])
desired output payload:
{
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
}, {
"ID": "89k873c8",
"Code": "CTY"
}, {
"ID": "84hkj569",
"Code": "CTY"
}, {
"ID": "6j93hl9",
"Code": "CTY"
}
]
}
I couldn't find a way to do in dataweave,
Would you please help
The following dataweave code should give you what you want:
%dw 1.0
%output application/json
---
{
Categories: payload.Categories ++ (flowVars.value map {
"ID": $,
"Code": "CTY"
})
}
Here's the configuration from a sample flow which I have used, and the output:
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
}, {
"ID": "89k873c8",
"Code": "CTY"
}
]
}]]></dw:set-payload>
</dw:transform-message>
<scripting:component doc:name="Groovy">
<scripting:script engine="Groovy"><![CDATA[
flowVars.value = new java.util.ArrayList();
flowVars.value.add("84hkj569");
flowVars.value.add("6j93hl9");
return payload;
]]></scripting:script>
</scripting:component>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
Categories: payload.Categories ++ (flowVars.value map {
"ID": $,
"Code": "CTY"
})
}]]></dw:set-payload>
</dw:transform-message>
Output:
{
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
},
{
"ID": "89k873c8",
"Code": "CTY"
},
{
"ID": "84hkj569",
"Code": "CTY"
},
{
"ID": "6j93hl9",
"Code": "CTY"
}
]
}
Brad Cooper's dataweave code to concatenate JSON payload and flowVars.value works without any issues. Here is the complete example that works with 3.8.1.
Complete Code:
<mule xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="sample-dataweaveFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/sample" doc:name="HTTP"/>
<logger message="Request Received" level="INFO" doc:name="Logger"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-variable variableName="value"><![CDATA[%dw 1.0
%output application/java
---
['84hkj569', '6j93hl9']]]></dw:set-variable>
</dw:transform-message>
<logger message="Flow Variable: #[flowVars.value]" level="INFO" doc:name="Logger"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
Categories: [
{
"ID": "5a873ca3",
"Code": "CTY"
}, {
"ID": "89k873c8",
"Code": "CTY"
}
]
}]]></dw:set-payload>
</dw:transform-message>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="Payload: #[payload]" level="INFO" doc:name="Logger"/>
<dw:transform-message doc:name="Transform Message">
<dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
{
Categories: payload.Categories ++ (flowVars.value map {
ID: $,
Code: 'CTY'
})
}]]></dw:set-payload>
</dw:transform-message>
<byte-array-to-string-transformer doc:name="Byte Array to String"/>
<logger message="Final Response: #[payload]" level="INFO" doc:name="Logger"/>
</flow>
</mule>
TEST URL:
http://localhost:8081/sample
Console Output:
INFO 2018-05-09 01:08:51,575 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Request Received
INFO 2018-05-09 01:08:51,576 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] com.mulesoft.weave.mule.utils.MuleWeaveFactory$: MimeType was not resolved '*/*' delegating to Java.
INFO 2018-05-09 01:08:51,595 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Flow Variable: [84hkj569, 6j93hl9]
INFO 2018-05-09 01:08:51,596 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] com.mulesoft.weave.mule.utils.MuleWeaveFactory$: MimeType was not resolved '*/*' delegating to Java.
INFO 2018-05-09 01:08:51,620 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Payload: {
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
},
{
"ID": "89k873c8",
"Code": "CTY"
}
]
}
INFO 2018-05-09 01:08:51,635 [[sample-dataweave].HTTP_Listener_Configuration.worker.01] org.mule.api.processor.LoggerMessageProcessor: Final Response: {
"Categories": [
{
"ID": "5a873ca3",
"Code": "CTY"
},
{
"ID": "89k873c8",
"Code": "CTY"
},
{
"ID": "84hkj569",
"Code": "CTY"
},
{
"ID": "6j93hl9",
"Code": "CTY"
}
]
}

How to store all the json objects from an iterator into one Array in wso2 ESB

I have an json output which looks like,
"details": [
{
"id": "",
"name": "",
"status": "",
},
{
"id": "",
"name": "",
"status": "",
},
{
"id": "",
"name": "",
"status": "",
},
{
"id": "",
"name": "",
"status": "",
}
From this output I can iterate values like //jsonObject/details and fetching individual item like
json-eval('$.details.id'), but I want to store all Id's and Name's into a Array in wso2 ESB, from the output I get, Can anyone help me.
Not sure if that helps, I think the following pseydo code might do it but I haven't tried it.
//create an empty var
<property name="newArray" value=""/>
//iterate over the json
<iterate xmlns:ns="http://org.apache.synapse/xsd" continueParent="true" expression="//jsonObjects/object" id="MyIterator">
....
<property name="newArray" expression="fn:concat(get-property('newArray'),//jsonObjects/object/value)" scope="operation"/>
....
</iterate>
<log>
<property name="afterIterate" expression="get-property('operation','newArray')"/>
</log>

Mulesoft DataWeave: Transform flat list

I am relatively new to DataWeave, and was wondering how/if I can transform a message like below using DataWeave instead of a Java transformer.
If I have the following JSON payload of users, with a group and subgroup:
[{
"GROUP": "GROUP_A",
"SUBGROUP": "SUBGROUP A1",
"USER": "USER 1"
}, {
"GROUP": "GROUP_B",
"SUBGROUP": "SUBGROUP B1",
"USER": "USER 1"
}, {
"GROUP": "GROUP_B",
"SUBGROUP": "SUBGROUP B1",
"USER": "USER 2"
}, {
"GROUP": "GROUP_B",
"SUBGROUP": "SUBGROUP B2",
"USER": "USER 3"
}, {
"GROUP": "GROUP_B",
"SUBGROUP": "SUBGROUP B2",
"USER": "USER 4"
}, {
"GROUP": "GROUP_B",
"SUBGROUP": "SUBGROUP B2",
"USER": "USER 5"
}]
What would a DataWeave transformation look like to tranform the payload to something structured like the following:
[
{
"GROUP": "GROUP_A",
"SUBGROUPS": [{
"NAME": "SUBGROUP A1",
"USERS": ["USER 1"]
}]
}, {
"GROUP": "GROUP_B",
"SUBGROUPS": [{
"NAME": "SUBGROUP B1",
"USERS": ["USER 1", "USER 2"]
}, {
"NAME": "SUBGROUP B2",
"USERS": ["USER 3", "USER 4", "USER 5"]
}]
}
]
Thanks for any help!
For DataWeave development, please refer to DataWeave Reference Documentation. At this case You can refer to section Group by …. To transform above message, then try this script:
%dw 1.0
%output application/json
---
payload groupBy $.GROUP pluck {
GROUP: $$,
SUBGROUPS: $ groupBy $.SUBGROUP pluck {
NAME: $$,
USERS: $.USER
}
}