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.
Related
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')
I have to call another teams one System API, with different query parameters based on different conditions. .
I am adding different conditions ( for now 15 , count may increase in future ) in Choice Router based on which I am calling the same SAPI with different query parameters.
But Choice Router is becoming very cumbersome and my flow is looking ugly.
Please suggest any other good way to handle this scenario.
One approach I can think of is to abstract the System API into its own flow which expects a flowVar JSON variable (sapiParameters) which has all the expected parameters. Like:
{
param1: "hello",
param2: "world",
...
}
Then you can move the conditional logic into transformers that create this flowVar variable sapiParameters.
These transformers could be dataweave transformers, but can also become Java classes or groovy scripts if the logic becomes too complex.
Try using match..case operator for removing multiple if..else logic. Based on your conditions, you can pass different query parameters passed to your calling API.
https://docs.mulesoft.com/mule-runtime/4.3/dataweave-pattern-matching
Another approach, I can think of DataWeave using
if,else If,else or using pattern Matching using match operator
<ee:transform doc:name="Choice alternative" doc:id="230-3-kke9" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="choiceFlow" ><![CDATA[%dw 2.0
output application/java
---
if(<condition1>)
Mule::lookup('flow1', {test:'hello '})
else if (<conditional2>)
Mule::lookup('flow2', {test:'hello '})
else
Mule::lookup('flow3', {test:'hello '})]]></ee:set-variable>
</ee:variables>
</ee:transform>
Internal workings of the DataWeave engine might cause a lookup function to be invoked in parallel with other lookup functions, or not to be invoked at all.
MuleSoft recommends that you invoke flows with the Flow Ref (flow-ref) component
Please Note: You can add more else if in above code.
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
In Mule4, I need to convert json sample data in to dynamic XML format, I have tried with dataweave(2.0) field mapping, getting null values. Does anyone can help me on this?
If the question is just asking out to build up XML output from JSON input, that is a pretty open-ended question. What do you want to evaluate dynamically? You could, for example, use part of the payload to set values in the DataWeave expression.
There is a more difficult version of this question: how to dynamically evaluate DataWeave code constructed into an input string, where this string could be read from various script files, or even constructed in-line from some input data (payload, attributes, or variables).
Here is another example covered in our MuleSoft DataWeave training course at http://training.mulesoft.com.
You can use a Dynamic Evaluate component to dynamically evaluate a constructed DataWeave expression string. Here is an example that replaces the uName parameter with a dynamic value.
Also, the expression is configured to read in different script files based on some condition:
output application/json
---
do {
var choice = attributes.queryParams.script default "NO_SCRIPT"
---
if(choice == "NO_SCRIPT")
"output application/json --- {result: 'NO SCRIPT ENTERED'}"
else if(choice == "script1") vars.script1
else if (choice == "script2") vars.script2
else read(choice)
}
Here are two example scripts that substitutes values for uName and produce different types of output (XML vs. JSON).
This is script1:
output application/xml
---
root: { message: "order "
++ attributes.queryParams.orderid
++ " has been received from "
++ uName, items: payload.items}
This is script2:
output application/json
---
root: { message: "Order2 "
++ attributes.queryParams.orderid
++ " has been received from "
++ uName, items: payload.items}
Notice that this example is dangerous. It lets the web client inject any DataWeave code into the Mule flow, so this example should never be copied into production code, but it does demonstrate the ability to run any DataWeave code passed into a Mule application.
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