2
votes

I'm implementing an API in WSO2 ESB 5.0 that is supposed to accept a POST with an XML body then forward it to another webservice with a JSON body containing the original XML body as an attribute.

Example:

I post the following body to my ESB API:

<?xml version="1.0" encoding="utf-8"?>
<workorder id="foobar">
    <foo/>
</workorder>

I expect something like the following to be posted to my webservice:

{
    "key1": "value1",
    "key2": "value2",
    "input" : "<?xml version=\"1.0\" encoding=\"utf-8\"?><workorder id=\"foobar\"><foo/></workorder>"
}

For now by inSequence looks like:

<inSequence>
         <property name="messageType" value="application/xml" scope="axis2"/>
         <log level="full"/>
         <enrich description="Store workorder">
            <source type="body" clone="true"/>
            <target type="property" property="SENT_WORKORDER"/>
         </enrich>
         <payloadFactory media-type="json" description="">
            <format>{"key1": "value1", "key2": "value2", "input": "$ctx:SENT_WORKORDER"}</format>
            <args/>
         </payloadFactory>
         <log level="full"/>
         <property name="REST_URL_POSTFIX" value="/my/service" scope="axis2" type="STRING" description="Set URL"/>
         <send>
            <endpoint key="conf:/endpoints/my_endpoint"/>
         </send>
</inSequence>

It returns this:

{
    "key1": "value1",
    "key2": "value2",
    "input" : "[<workorder id="foobar"><foo/></workorder>]"
}

I have no idea how to proceed. All I want is to retrieve the raw text that I posted (and escape double quotes so that it can be included in JSON).

1

1 Answers

2
votes

I ended up using a script mediator to handle this:

<inSequence>
        <log level="full"/>

        <script language="js"><![CDATA[
        var log = mc.getServiceLog();
        var payload = {"key1": "value1", "key2": "value2", "input": ""};
        payload["input"] = mc.getPayloadXML().toString();
        log.info("Built payload: " + JSON.stringify(payload));
        mc.setPayloadJSON(JSON.stringify(payload));
        ]]></script>

        <property name="REST_URL_POSTFIX" value="/my/service" scope="axis2" type="STRING" description="Set URL"/>
        <property description="Set Content-Type" name="messageType" scope="axis2" type="STRING" value="application/json"/>

        <send>
           <endpoint key="conf:/endpoints/my_endpoint"/>
        </send>
</inSequence>

For some reason, the JSON.stringify call as well as the final "Set Content-Type" are required.

As a bonus, I also needed to do the reverse of what I asked here: extracting an XML from a JSON payload attribute and returning it as a proper XML object. The relevant part of the sequence was:

<script language="js"><![CDATA[
var payload = mc.getPayloadJSON();
var report = payload.path.to.xml.attribute;
mc.setPayloadXML(XML(report));
]]></script>

<property description="Set Content-Type" name="messageType" scope="axis2" type="STRING" value="application/xml"/>