Conditional expression is not working in Mule 4 - mule

I have this expression when setting the value of a variable in Mule:
#[(message.inboundProperties['message-id'] != null) ? message.inboundProperties['message-id'] : java.util.UUID.randomUUID().toString().replace('-', '')]
Basically, if the message does not already have an id allocated to it then it will have one created.
I have moved onto Mule 4 and Anypoint 7 and this expression no longer works. I know the inboundProperties has changed to attributes so have made the following changes:
#[(attributes.headers.'message-id' != null) ? attributes.headers.'message-id' : java.util.UUID.randomUUID().toString().replace('-', '')]
For both expressions I get the error "No viable alternative at input '('.
How can I fix this statement to work for Mule 4?
Thanks

#[attributes.headers.'message-id' default (uuid() replace '-' with '')]
expression use Dataweave 2.0 as default in mule 4, not MEL. So you can no longer use java method invocation. Instead use the uuid() dataweave function and the replace dataweave function
You can use default instead of the if else check

Related

if else statement mule 3

I want to set a variable based on the output in Mule 3.
For example the check I want to do is if there is any payload
I want to set the var value to this ${http.path.one} else
${http.path.two}.
In Mule 4 it can be done in multiple ways but in Mule 3 seems little tricky. Anyone an Idea?
Thanks
In Mule 3 DataWeave you can use when/otherwise instead of Mule 4 if/else. To access the properties use the p() function. Depending on the exact payload and the condition you need you may need to tweak the expression for the condition.
Example:
p('http.path.two') when (payload != null) otherwise p('http.path.one')

mule3 to mule 4 expression to dataweave 2.0

I'm new to migrating the mule 3 apps to mule 4 I have done almost conversion but one expression stopped my flow and not able to achieve the logic for it if anyone has an idea regarding the expression to transform please help me
Expression:
if(flowVars.maindata.keySet().contains(payload.idCaseNumber))
{
flowVars.temporary=[];
flowVars.maindata.get(payload.idCaseNumber).add(map);
}
else
{
flowVars.temporary.add(previousdata);
vars.maindata.put(payload.idCaseNumber,temporary);
}
I have tried up to my knowledge on the above code but still I'm getting problem
flowVars.maindata.get(payload.idCaseNumber).add(map);
In Mule 3 the expression language is MEL. In Mule 4 it is DataWeave 2.0. You can't just translate directly. MEL is an imperative scripting language, similar to a subset of Java and it is easy to call Java methods. DataWeave 2.0 is a functional language. Furthermore Mule 4 operations (example: a , , etc) can only return one value, which can be assigned to the payload or to one variable.
For your snippet I'll assume that maindata is a map. You can use two set-variable to assign each variable:
<set-variable variableName="temporary" value="#[ if( namesOf(vars.maindata) contains payload.idCaseNumber ) [] else vars.temporary ++ **previousdata** ]" />
I don't know exactly what do you use for previousdata.
To update the variable maindata it is probably a good match for the update operator, in a separate or Transform operation, with the same condition than for vars.temporary.
Update:
I'll assume vars.maindata is a map, which DataWeave will consider an object, and each element is a list. As an example of doing an 'upsert' operation with a dynamic selector:
%dw 2.0
output application/java
var temporary=[5]
var maindata={ a:[1,2,3,4] }
var myKey="a"
---
maindata update {
case data at ."$(myKey)"! -> if (data != null) data ++ temporary else temporary
}
You could replace in above script the DataWeave var temporary with the expression from my example above, and the other DataWeave variables with the Mule variables (vars.name) or payload. If you change in above example myKey to have value "b" you will see that key being added.

Declaration of dynamic dataweave variable in Mule 4 like we have done with using in Mule 3

I have a requirement of creating a runtime variable in Dataweave like we have done in Mule 3 with the using keyword. Can someone let me know how can it be achieved in Mule 4
You can still use using keyword in Mule 4/Dataweave 2.
Local variables are initialized in the body of the DataWeave script and can be referenced by name only from within the scope of the expression where they are initialized.
The syntax for initializing a local variable looks like this: using ( = )
You can combine several local variable definitions as a comma separated list inside the using function. For example: using (firstName='Annie', lastName='Point')
%dw 2.0
output application/json
---
using (x = 2) 3 + x
Here is an example of defining a local variable within an object:
%dw 2.0
output application/xml
---
{
person: using (user='Greg', gender='male') {
name: user,
gender: gender
}
}
Note thise variables are only scoped to the 'person' object. Accessing them outside of person will throw an error.
Full documentation on this here: https://docs.mulesoft.com/mule-runtime/4.1/dataweave-variables

How can I do Null and empty check of arraylist using dw() function in mule?

I tried the following way,
[dw('sizeOf payload.data.accts')>0] but hthis would just check if arraylist is empty or not .So i need a help to how do I null check on "accts" arraylist using dw() function.
I want both null and empty check in dw() function of mule so that I can use it in my choice router to proceed my flow.
I would do something like this in the choice router:
In the 'When' column:
#[payload.data.accts != empty]
In the Route Message to column:
yourFlow
Please refer How to Check null condition in Data weaver : Mule.
Should be applicable to Json as well - try out
Example:(payload.Records.*RecordsEntries.*RecordEntry default [])
You can combine default with sizeOf to achieve this:
#[dw('(sizeOf (payload.data.accts default [])) == 0']
We can break this down into two expressions. The first, payload.data.accts default [] will return an empty list if payload, payload.data or payload.data.accts is null. Otherwise it will just return whatever the value of payload.data.accts is.
The second, (sizeOf <expression>) == 0 will check if the list returned from the above expression is empty or not.

How to concatenate 2 values in mule?

Can someone please let me know how to concatenate multiple values in mule?
Something like,
#[payload.getPayload()].concat(#[getSubject()])
I assume you are using Mule 3.3.x or above. If so you can use Mule Expression Language(MEL).
One example using MEL is:
#['Hello' + 'World']
Or MEL also allows you to use standard Java method invocation:
#[message.payload.concat(' Another String')]
Cheat sheet on MEL
MULE 4 Update
For Mule 4. Dataweave 2.0 is the main expression language:
Simple concat:
#['Hello' ++ ' World']
Other alternative is to use Mule Design plugin :
Drop an "Append String" operation as many times as you need.
This operation takes the message payload of the previous step and concats a specified string to it.
Not sure about performance details, but it will be surely more easy to maintain.
Append to String - MuleSoft
you can declare a string buffer using expression component
<expression-component doc:name="Expression"><![CDATA[StringBuffer sb = new
StringBuffer();
flowVars.stBuffer=sb;
]]></expression-component>
and then append use append on string buffer any where in the flow.
flowVars.stBuffer.append("string to append")
Once done use #[flowVars.stBuffer] to access the concatenated string
If you want to add two different values received through payload in the mule flow then we can use concat() method.
For example below we have received values through arraylist where i am adding two diffrent fields i.e. FirstName and the LastName -
concat(#[payload[0].'firstname']," " #[payload[0].'lastname']