Initializing a Map using Mule Expression Language - mule

I'm trying to initialize a map with the following in a mule expression-component:
#[message.payload = [ 'changeSet' : #[payload], 'sourceAndConnectionMap' : #[flowVars['sourceAndConnectionMap']]]]
Based on the following page, this looks okay, but does not work.
https://developer.mulesoft.com/docs/display/current/Mule+Expression+Language+Reference
Only the first key is set ('changeSet'), and for some reason the payload, which is a map, becomes an ArrayList containing a map... I can also initialize this with just the second key and valy, so I know there isn't an issue resolving the flowVar.
Is there something basic about how I am initializing this map that is incorrect?

In MEL a map should be created like:
#[{'key':'value', 'key1':'value1'}]
If you do
#[[]]
That's just a list of elements.
The other comments, if you're already inside a:
#[]
You need not to add it again. In your example you have it several times.
Please run this through the Mule debugger (put brakepoints in the logs)and you'll see the difference.
<flow name="test>
<set-payload value="#[{'key':'value', 'key1':'value1'}]" doc:name="Set Payload"/>
<logger level="INFO" doc:name="Logger"/>
<set-payload value="#[{'key':'value', 'key1':payload}]" doc:name="Copy_of_Set Payload"/>
<logger level="INFO" doc:name="Copy_of_Logger"/>
<set-payload value="#[['key','value', 'key1','value1']]" doc:name="Copy_of_Set Payload"/> <logger level="INFO" doc:name="Logger"/>
</flow>
HTH

Related

How to retrieve elements in foreach loop in Mule4?

I have defined a variable to keep application/json collection.
<set-variable value="#[payload.'IntegrationEntities'.'amendmentId']" doc:name="AmendmentIds" doc:id="03b6c46a-fc7b-43d4-b23a-502146ef0b13" variableName="amendmentids"/>
<logger level="INFO" doc:name="Logger" doc:id="6a1ad892-65f9-4dd2-9891-bdf3ad64c908" message="#[vars.amendmentids]" />
It prints as;
[
"8a9a84b76b5a5a59016b687bae35012e",
"8a9a84b76b5a5a59016b6888e90e0144"
]
Then I use ForEach loop to define few process logic for each Id,
Within foreach loop how I can get, each above id?
I used,vars.amendmentids[vars.counter]], but getting following error[1]
<foreach doc:name="For Each" doc:id="7b741315-aa28-4704-82f0-629c21d93853" collection="#[vars.amendmentids]">
<logger level="INFO" doc:name="Logger" doc:id="049c3137-2f92-4077-8e3f-b26516cc5528" message="#[vars.amendmentids[vars.counter]]"/>
</foreach>
[1]
Message : "Internal execution exception while executing the script, this is most probably a bug, file an issue with the script and the input data.
Caused by:
java.lang.RuntimeException: Unable to infer a output media type as more than one is being used: application/json,application/java please specify using: output <your mime-type> --- <expr>
at org.mule.weave.v2.el.MuleDataWeaveHelper$.inferImplicitOutput(MuleDataWeaveHelper.scala:69)
.............
" evaluating expression: "vars.amendmentids[vars.counter]".
Error type : MULE:EXPRESSION
you need to access the payload only in foreach scope:
<foreach doc:name="For Each" collection="#[vars.amendmentids]">
<logger level="INFO" doc:name="Logger" message="#[payload]"/>
</foreach>
As in foreach each element of your collection will be the payload.

How to check particular value in Arraylist in Mulesoft?

This is my ArrayList -
[
{
AccountNumber=123456,
Amount=257710.06
},
{
AccountNumber=845679,
Amount=3672351.06
}
]
Here, I want to check whether the account number 123456 is in the list or not.
I have used "Choice" component, because I want to create another list with searched account numbers. This is my code-
<choice doc:name="Choice">
<when expression="#[flowVars.investOneList.contains(123456)]">
<logger message="Account number is present" level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<logger message="Account number is not present" level="INFO" doc:name="Logger"/>
</otherwise>
</choice>
Here, my logger prints "Account number is not present". My code is not able to find the account number, although it is there in the list.
Could anyone please help me out?
Thanks!
If you want to use List.contains(...) you will need to map the variable you have like this:
%dw 1.0
%output application/java
---
flowVars.investOneList map $.AccountNumber
Which will output [123456, 845679] as the payload (you can set to something else if you want). Then you can do this in your choice router:
<choice doc:name="Choice">
<when expression="#[payload.contains(123456)]">
<logger message="Account number is present" level="INFO" doc:name="Logger"/>
</when>
<otherwise>
<logger message="Account number is not present" level="INFO" doc:name="Logger"/>
</otherwise>
</choice>
But you could do the whole thing in MEL by using the dw() function like this:
...
<when expression="dw('(flowVars.investOneList map $.AccountNumber) contains 123456')">
...
And that will prevent you from needed an intermediate calculation just to get a list of the account numbers.

Mule choice route depending on payload type ie object type?

I have route choice depending on the payload. The payload can be either list, map or string. The payload has to be identified and routed depending on the payload type.
I think that you want something like that
<choice doc:name="Choice">
<when expression="#[payload is List]">
<logger level="INFO" message="i am list" doc:name="Logger"/>
</when>
<when expression="#[payload is Map]">
<logger level="INFO" message="i am map" doc:name="Logger"/>
</when>
<when expression="#[payload is String]">
<logger level="INFO" message="i am string" doc:name="Logger"/>
</when>
<otherwise>
<logger message="class doesnt match with [list, map, string]" level="INFO" doc:name="Logger"/>
</otherwise>
</choice>
I do agree with EddĂș response, except for that I would add an otherwise path. If you don't do that and get something different than a list map or string you would get the rather cryptic error:
org.mule.api.routing.RoutePathNotFoundException: Can't process message because no route has been found matching any filter and no default route is defined. Failed to route event via endpoint: ChoiceRouter [flow-construct=testNull, started=true]. Message payload is of type: NullPayload

I want to Scatter the requests but not Gather results into single payload unlike how scatter-gather does in Mule

I have a flow like:
<flow name="Flow1">
<set-payload value="Important Message" />
<scatter-gather>
<choice doc:name="A">
<when expression="true">
//TODO
</when>
<otherwise>
//TODO
</otherwise>
</choice>
<flow-ref name="B" />
</scatter-gather>
<logger message="from flow-ref B: #[payload]" level="INFO" doc:name="response from B only"/>
</flow>
Right now the payload that comes out is an array of Payload;But I need only payload from response of B. I don't want to append java class to iterate over the payload to find B response.
I don't want the response from choice component but only from flow-ref B.
How to achieve this? Is this possible in an easy way using only mule components?
If I understand correctly, you want the payload "Important Message" to reach the flow-ref to B, and you also want the choice to occur?
Try getting rid of the scatter-gather and wrapping the choice router in an Async Scope instead.

How to capture an exception using the regex-filter filter in Mule ESB

Currently I have a flow that exposes a REST service with a string as input parameter . I am using a regex -filter to ensure the format parameter as follows :
<http:inbound-endpoint doc:name="HTTP"
connector-ref="ciuServiceHTTPConnector" ref="ciuServiceHTTPEndpoint"
exchange-pattern="request-response" />
<logger level="INFO" doc:name="Logger" message="epale1 #[payload]"/>
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
<logger message="epale2 #[payload]" level="INFO" doc:name="Logger"/>
<jersey:resources doc:name="REST" >
<component class="...resource.CiudadanoResource"/>
</jersey:resources>
I need to send the customer a message "Invalid or missing parameter" . For this I use a choice-exception-strategy and catch-exception-strategy and then call a Subflow and perform http:response-builder.
How can I throw an exception(type) when the regex-filter do not match?. It is possible to incorporate this behavior or should I change my flow?
Thanks for your help;
Wrap it in a message-filter, like this:
<message-filter throwOnUnaccepted="true">
<regex-filter pattern="^/api/person/(V|E)[0-9]{8}$"
doc:name="Regex" />
</message-filter>
See the official documentation for further details:
Check the Throw On Unaccepted box to throw an exception if a message
or event is not handled. The default when not checked is to not throw
an exception.