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

不羁岁月 提交于 2019-12-11 16:24:48

问题


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


回答1:


If you use iterate mediator you have to aggregate the results to get the modified message. How ever this can be achieved by using xslt mediator. Sample proxy configuration would be look like follows

<proxy name="yourpproxy" transports="https http" startOnLoad="true"   trace="disable">
      <description/>
      <target>
         <inSequence>
            <xslt key="yourxsltkey"/> 
            <send/>
         </inSequence>
         <outSequence>
            <send/>
         </outSequence>
      </target>
</proxy>

where yourxsltkey is the key to your xslt definition. This can be either declare as local entry or in registry. As an sample here i have defined as a local entry.

<localEntry key="yourxsltkey">
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

       <xsl:template match="/">
        <AAA xmlns="http://ws.apache.org/ns/synapse">
          <xsl:for-each select="AAA/BBB">
            <BBB><xsl:value-of select="CCC"/></BBB>
          </xsl:for-each>
        </AAA>
       </xsl:template>
    </xsl:stylesheet>

 </localEntry>



回答2:


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;
    }
}


来源:https://stackoverflow.com/questions/17443232/as-in-the-iterate-to-change-the-message-and-send-it-fully-wso2esb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!