1

In my case, I'm doing a migration from Mule 3 to Mule 4.

This flow, which includes transformers like DOM to XML, XML to DOM, and an expression component, needs to be migrated.

In Mule 4, I want to reuse the xrp file.

My flow for XML payload transform uses an XPR file by the expression component in Mule 3.

<flow name="rate-dtostepFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/dtostep" allowedMethods="POST" doc:name="HTTP"/>
        <mulexml:xml-to-dom-transformer returnClass="org.dom4j.Document" doc:name="XML to DOM"/>
        <set-variable variableName="domPayload" value="#[payload]" doc:name="set domPayload "/>
        <expression-component file="xpr/responseStubCannasure.xpr" doc:name="Expression"/>
        <mulexml:dom-to-xml-transformer doc:name="DOM to XML"/>
</flow>

Input XML: https://github.com/Manikandan99/rate-dtostep/blob/master/request.xml

Output XML: https://github.com/Manikandan99/rate-dtostep/blob/master/response.xml

my MULE 3 application : https://github.com/Manikandan99/rate-dtostep/tree/master/rate-dtostep

ResponseStubcannsure xpr file:

import org.dom4j.*;
import java.util.*;
import java.util.logging.Logger;

Logger logger = Logger.getLogger("");

dtoCoverageStepsNodes = flowVars.domPayload.selectNodes("//DTOCoverage[@Status=\'Active\']/DTOSteps");
for (Node node : dtoCoverageStepsNodes){
    //logger.info("inside: detach");
    node.detach();
}

dtoCoverageNodes = flowVars.domPayload.selectNodes("//DTOCoverage[@Status=\'Active\']");
int i = 500;
for (Node node : dtoCoverageNodes){

    //node.detach();
    //logger.info("inside: assign prem");
    node.addAttribute("FullTermAmt", Integer.toString(i));

    node.addElement("DTOSteps");

    stepNode = node.selectSingleNode("DTOSteps");
    stepNode.addElement("DTOStep")
        .addAttribute("Order","1")
        .addAttribute("Name","Final Premium")
        .addAttribute("Desc","Final Premium Desc")
        .addAttribute("Operation","=")
        .addAttribute("Factor",Integer.toString(i))
        .addAttribute("Value",Integer.toString(i));

    i+=1;
}

The xpr file transform the xml payload in the following ways:

  • updated the value of the DTOStep node.
  • The attribute value of DTOStep is autoincremented from 500 each time.

Please assist me.

2
  • And as I explained previously inputs and outputs should be in the question, not just linked. Commented Jan 28, 2022 at 14:02
  • 1
    Hi Aled, In my view codey_08 transformed the input xml based on updating the value of DTOStep using that XPR file.. Commented Jan 28, 2022 at 14:08

1 Answer 1

2

You need to migrate the complete flow to Mule 4. The file responseStubCannasure.xpr is just a script in MEL (Mule 3 expression language). The extension is irrelevant, it could have been anything. MEL is very similar to Java so you could reuse the logic by encapsulating it into a Java class. You will need to add to the Java code the conversion to DOM4J from the input XML because Mule 4 doesn't support it. Probably is slightly easier to migrate the MEL script to a Groovy script because the basic syntax is very similar and both support scripts. Migrating to Java is just taking the additional steps of encapsulating the script into a method of a class and defining explicitly the types for variables.

Alternatively you could just delete the last 4 operations of the flow and replace them with a DataWeave transformation. Using a recursive function to navigate the keys and value recursively, using a condition to check if we are in the element DTOCoverage, with attribute Status == "Active" and then replace the nested element with the DTOSteps/DTOStep combination. Which is what your script does.

Example:

%dw 2.0
output application/xml
var startingValue=500
fun transformSteps(x, index)=
    x filterObject ($$ as String != "DTOSteps") ++
    {
         DTOSteps: DTOStep @(Order:1, Factor: index + startingValue, Value: index + startingValue, Name:"Final Premiun", Operation:"=", Desc: "Final Premium Desc"): null 
    }

fun transformCoverage(x, index)=
    {
        val: x match {
            case is Object -> x mapObject 
                if ($$ as String == "DTOCoverage" and $$.@Status == "Active")
                    { 
                        DTOCoverage @(( $$.@ - "FullTermAmt" ), FullTermAmt: $$$ + startingValue): 
                            transformSteps($, index)
                    }
                else 
                    (($$): transformCoverage($, index+1)) 
            else -> $
        },
        index: index
    }
---
transformCoverage(payload,1).val

This solution doesn't completely resolve the Value and Factor (why two attributes with the same value?) sequential increase. You may need to do an additional transformation, or use Groovy or Java code to renumber them.

Sign up to request clarification or add additional context in comments.

16 Comments

Aled, you're right. Could you please update the answer with encapsulating the logic in a Java class?
I added an example DataWeave script that resolves most of the problem. I'll leave the Java implementation to you. The answer is there, pointing you to the work that needs to be done.
Hi Aled, It's a close call. You did an awesome work. But In your Dataweave code, the attribute values for DTOCoverage are missing. Could you please update the code?
Aled, myself also worked on codey_08 xpr.its lit complex to transform in Dataweave code,but let encapsulating the logic in java code is easy I think so....
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.