1
votes

I use property with expression=json-eval($) to logging my current body in WSO2 ESB version 6.4.0. It works after every call, but it doesn't work after each of xqueries.

I noticed that it doesn't work after xquery where the output is </jsonObject>.

If I have output of xquery like <objectName></sampleData></objectName>, my two logs:

<log>
   <property name="logInJson" scope="default" type="STRING" expression="json-eval($)"/>
   <property name="logInXml" scope="default" type="STRING" expression="$body"/>
</log>

show the same data.

If I have output of xquery like <jsonObject></sampleData></jsonObject> the property logInXml shows correct data, but the property logInJson shows wrong data (it shows data from last response of call).

Is there any solution to logging every current body in json?

Edit - example:

This is my API:

<?xml version="1.0" encoding="UTF-8"?>
<api context="/test" name="Test" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="POST" uri-template="/test">
        <inSequence>
            <xquery key="gov:resources/normalXmlOutput.xq">
                <variable string="myData" name="payload" type="ELEMENT"/>
            </xquery>
            <log>
                <property name="BODY_XML" scope="default" type="STRING" expression="$body"/>
                <property name="BODY_JSON" scope="default" type="STRING" expression="json-eval($)"/>
            </log>
            <xquery key="gov:resources/jsonObjectOutput.xq">
                <variable string="myData" name="payload" type="ELEMENT"/>
            </xquery>
            <log>
                <property name="BODY_XML" scope="default" type="STRING" expression="$body"/>
                <property name="BODY_JSON" scope="default" type="STRING" expression="json-eval($)"/>
            </log>
        </inSequence>
        <outSequence/>
        <faultSequence/>
    </resource>
</api>

This is first xQuery named normalXmlOutput.xq:

<x xmlns="http://ws.apache.org/ns/synapse"><![CDATA[
declare namespace xf = "http://tempuri.org/";
declare function xf:normalXmlOutput($payload as xs:string)
    as element(objectName) {
        <objectName>
            <sampleData>{ $payload }</sampleData>
        </objectName>
};
declare variable $payload as xs:string external;
xf:normalXmlOutput($payload)
]]></x>

And here is xQuery named jsonObjectOutput.xq:

<x xmlns="http://ws.apache.org/ns/synapse"><![CDATA[
declare namespace xf = "http://tempuri.org/";
declare function xf:jsonObjectOutput($payload as xs:string)
    as element(jsonObject) {
        <jsonObject>
            <sampleData>{ $payload }</sampleData>
        </jsonObject>
};
declare variable $payload as xs:string external;
xf:jsonObjectOutput($payload)
]]></x>

Body of request:

{ "payloadRequest": "someValue" }

Logs:

[2021-02-09 10:48:28,438] [EI-Core]  INFO - LogMediator To: /test/test, MessageID: urn:uuid:20133e1c-f9e4-4f84-953d-4a12274281ac, Direction: request, 
BODY_XML = 
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <objectName>
      <sampleData>someValue</sampleData>
   </objectName>
</soapenv:Body>, 
BODY_JSON = 
{"objectName":{"sampleData":"someValue"}}

[2021-02-09 10:48:28,442] [EI-Core]  INFO - LogMediator To: /test/test, MessageID: urn:uuid:20133e1c-f9e4-4f84-953d-4a12274281ac, Direction: request, 
BODY_XML = 
<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <jsonObject>
      <sampleData>someValue</sampleData>
   </jsonObject>
</soapenv:Body>, 
BODY_JSON = 
{ "payloadRequest": "someValue" }

As I said, log $body in xml shows correct data in both cases, but log json-eval($) in JSON shows correct in first case, but in second case data is wrong.

2
Can you maybe post the output (wso2carbon.log) of the whole thing? That might help finding the problem. I am especially interested in the different values that get logged using the json-eval statement.ophychius
@ophychius I have added my request body and logs. Last log in JSON shows data from request instead of output from xQuery.krzysztofzuo

2 Answers

0
votes

In this case setting the "messageType" to json before logging it should do it. [1]

<property name="messageType" scope="axis2" value="application/json"/> 

Internally everything is XML unless specifically specified or returned from a source so setting it like this will make sure the json-eval works.

[1]https://docs.wso2.com/display/EI640/Generic+Properties

0
votes

Not every payload can be wraped by wso2 to proper JSON. The $body - is used to get body from soap message: read more here and wso2 internally uses XMLs.

Maybe this will help for understand how JSON works in wso2ei.