Search code examples
wso2mediatorwso2-esb

As in the iterate to change the message and send it fully (wso2esb)


I receive a message from AAA nested children. I want every child BBB replace the value of CCC. Then send the modified message on AAA

<AAA>
    <BBB>
        <CCC>test1</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test2</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test3</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test4</CCC>
        <DDD>testing</DDD>
    </BBB>
    <BBB>
        <CCC>test5</CCC>
        <DDD>testing</DDD>
    </BBB>
</AAA>

I do it:

<iterate continueParent="true" expression="/AAA/BBB">
    <target>
        <sequence>
            <property name="newValue" value="chang testing" scope="default" type="STRING"/>
            <enrich>
                <source clone="false" type="custom" xpath="get-property('newValue')"/>
                <target action="replace" type="custom" xpath="//DDD"/>
            </enrich>
         </sequence>
    </target>
</iterate>

But changing the message is not stored on


Solution

  • I wrote my mediator and use it for this purpose

    import org.apache.axiom.om.OMElement;
    import org.apache.axiom.om.OMNode;
    import org.apache.axiom.om.impl.dom.NamespaceImpl;
    import org.apache.axiom.soap.SOAPEnvelope;
    import org.apache.axis2.AxisFault;
    import org.apache.synapse.Mediator;
    import org.apache.synapse.MessageContext;
    import org.apache.synapse.mediators.AbstractMediator;
    import org.apache.synapse.mediators.eip.EIPUtils;
    import org.apache.synapse.util.MessageHelper;
    import org.apache.synapse.util.xpath.SynapseXPath;
    import org.jaxen.JaxenException;
    
    import java.util.List;
    
    
    public class SplitMediator extends AbstractMediator {
    
        private String sequenceRef = null;
        private String xpathString = null;
        private String attachPathString = null;
        private String uri = null;
        private String prefix = null;
    
        public boolean mediate(MessageContext synCtx) {
            if (sequenceRef == null || xpathString == null || attachPathString == null) {
                handleException("Error creating a mediate due to sequenceRef or xpathString  attachPathString is null", synCtx);
                return false;
            }
    
            try {
                SOAPEnvelope envelope = synCtx.getEnvelope();
                Mediator sequenceMediator = synCtx.getSequence(sequenceRef);
    
                SynapseXPath expression = new SynapseXPath(xpathString);
                if (uri != null && prefix != null)
                    expression.addNamespace(new NamespaceImpl(uri, prefix));
                SynapseXPath attachPath = new SynapseXPath(attachPathString);
                if (uri != null && prefix != null)
                    attachPath.addNamespace(new NamespaceImpl(uri, prefix));
    
                List<OMNode> splitElements = EIPUtils.getDetachedMatchingElements(envelope, synCtx, expression);
                MessageContext templateMessageContext = MessageHelper.cloneMessageContext(synCtx);
                OMElement omElement = getOMElementByXPath(attachPath, envelope, synCtx);
    
                for (OMNode o : splitElements) {
                     MessageContext changeCtx = getNewMessageContextToSequence(templateMessageContext, o, attachPath);
                    sequenceMediator.mediate(changeCtx);
                    List elementList = EIPUtils.getMatchingElements(changeCtx.getEnvelope(), expression);
                    OMNode changeElement = (OMNode) elementList.get(0);
                    omElement.addChild(changeElement);
                }
            } catch (JaxenException e) {
                handleException("Error evaluating split XPath expression : " + xpathString, e, synCtx);
            } catch (AxisFault af) {
                handleException("Error creating an iterated copy of the message", af, synCtx);
            }
            return true;
        }
    
        private MessageContext getNewMessageContextToSequence(MessageContext templateMessageContext, OMNode o, SynapseXPath attachPath) throws AxisFault, JaxenException {
            MessageContext synCtx = MessageHelper.cloneMessageContext(templateMessageContext);
            SOAPEnvelope envelope = synCtx.getEnvelope();
            OMElement omElement = getOMElementByXPath(attachPath, envelope, synCtx);
            omElement.addChild(o);
            return synCtx;
        }
    
        private OMElement getOMElementByXPath(SynapseXPath attachPath, SOAPEnvelope envelope, MessageContext synCtx) {
            Object attachElem = attachPath.evaluate(envelope, synCtx);
            if (attachElem != null &&
                    attachElem instanceof List && !((List) attachElem).isEmpty()) {
                attachElem = ((List) attachElem).get(0);
            }
            // for the moment attaching element should be an OMElement
            if (attachElem != null && attachElem instanceof OMElement) {
                return ((OMElement) attachElem);
            } else {
                handleException("Error in attaching the splitted elements :: " +
                        "Unable to get the attach path specified by the expression " +
                        attachPath, synCtx);
            }
            return null;
        }
    
    
        ///////////////////////////////////////////////////////////////////////////////////////
        //                        Getters and Setters                                        //
        ///////////////////////////////////////////////////////////////////////////////////////
    
    
        public String getXpathString() {
            return xpathString;
        }
    
        public void setXpathString(String xpathString) {
            this.xpathString = xpathString;
        }
    
        public String getAttachPathString() {
            return attachPathString;
        }
    
        public void setAttachPathString(String attachPathString) {
            this.attachPathString = attachPathString;
        }
    
        public String getUri() {
            return uri;
        }
    
        public void setUri(String uri) {
            this.uri = uri;
        }
    
        public String getPrefix() {
            return prefix;
        }
    
        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }
    
        public String getSequenceRef() {
            return sequenceRef;
        }
    
        public void setSequenceRef(String sequenceRef) {
            this.sequenceRef = sequenceRef;
        }
    }