WSO2ESB Iterator/Aggregator 调解器:调用 2 个服务时出错

WSO2ESB Iterator/Aggregator Mediator: Error calling 2 services

首先,对不起我的英语。

我在一项服务中工作,该服务必须并行调用一个或多个服务,然后 "merge" 响应。为此,我使用 WSO2ESB,特别是使用 Iterator Mediator 和 Aggregate Mediator 的代理服务。 Iterator mediator 读取一个 XML 结构如下:

<data>
    <search>
        <calls>
            <scriptOut>JS_TransformJavascript</scriptOut>
            <endpoint>http://cms.examble.cl/rest.html</endpoint>
            <format>json</format>
            <action>POST</action>
            <category>
                <id>5</id>
            </category>
            <type>RS</type>
            <keywords>
                <value>GREEN</value>
                <name>yourColor</name>
            </keywords>
            <keywords>
                <value>Jhon</value>
                <name>name</name>
            </keywords>
            <scriptIn>JS_TransformJavascript</scriptIn>
        </calls>
        <calls>
            <endpoint>http://ext.example.cl/soap.php</endpoint>
            <parameters>
                <value>user</value>
                <name>user</name>
            </parameters>
            <parameters>
                <value>password</value>
                <name>password</name>
            </parameters>
            <format>soap11</format>
            <type>WS</type>
            <scriptIn>XSLT_TransformIn</scriptIn>
            <scriptOut>XSLT_TransformOut</scriptOut>
            <keywords>
                <value>GREEN</value>
                <name>yourColor</name>
            </keywords>
            <keywords>
                <value>Jhon</value>
                <name>name</name>
            </keywords>
            <action>AnSoapAction</action>
            <category>
                <id>5</id>
            </category>
        </calls>
    </search>
</data>

对于每个 "calls" 元素,调解器调用 SOAP 调用的代理服务(如果 "callType" 是 "WS")或 REST 调用的代理服务("callType" 是"RS"):

<iterate expression="//calls">
    <target>
        <sequence>
            <property expression="//type" name="callType" scope="default"
                type="STRING" />
            <log level="custom">
                <property expression="$body" name="callItem" />
            </log>
            <switch source="get-property('callType')">
                <case regex="WS">
                    <send>
                        <endpoint>
                            <http method="post" trace="disable"
                                uri-template="http://esb.example.cl/services/PX_AbstractSoapCall" />
                        </endpoint>
                    </send>
                </case>
                <case regex="RS">
                    <send>
                        <endpoint>
                            <http method="post" trace="disable"
                                uri-template="http://esb.example.cl/services/PX_AbstractRestCall" />
                        </endpoint>
                    </send>
                </case>
                <default />
            </switch>
        </sequence>
    </target>
</iterate>

每个调用 (SOAP/REST) 单独工作,但如果 Iterator Mediator 调用两者,REST 调用会给我一个错误:

TID: [-1] [] [2016-01-21 17:40:51,749] ERROR {org.apache.axiom.om.impl.llom.OMSourcedElementImpl} -  Could not get parser from data source for element jsonObject {org.apache.axiom.om.impl.llom.OMSourcedElementImpl}
javax.xml.stream.XMLStreamException: java.io.IOException: Illegal character: <<>
    at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.initialize(AbstractXMLStreamReader.java:245)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.<init>(JsonXMLStreamReader.java:66)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLInputFactory.createXMLStreamReader(JsonXMLInputFactory.java:165)
    at org.apache.synapse.commons.json.JsonUtil.getReader(JsonUtil.java:274)
    at org.apache.synapse.commons.json.JsonDataSource.getReader(JsonDataSource.java:153)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getDirectReader(OMSourcedElementImpl.java:225)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.forceExpand(OMSourcedElementImpl.java:254)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getFirstOMChild(OMSourcedElementImpl.java:867)
    at org.apache.axiom.om.impl.OMNavigator._getFirstChild(OMNavigator.java:196)
    at org.apache.axiom.om.impl.OMNavigator.updateNextNode(OMNavigator.java:140)
    at org.apache.axiom.om.impl.OMNavigator.getNext(OMNavigator.java:112)
    at org.apache.axiom.om.impl.SwitchingWrapper.updateNextNode(SwitchingWrapper.java:1113)
    at org.apache.axiom.om.impl.SwitchingWrapper.updateLastNode(SwitchingWrapper.java:1104)
    at org.apache.axiom.om.impl.SwitchingWrapper.next(SwitchingWrapper.java:1041)
    at javax.xml.stream.util.StreamReaderDelegate.next(StreamReaderDelegate.java:88)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
    at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
    at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
    at org.apache.axiom.om.impl.llom.OMElementImpl.cloneOMElement(OMElementImpl.java:1065)
    at org.wso2.carbon.tracer.module.handler.TracingMessageInObservationHandler.invoke(TracingMessageInObservationHandler.java:33)
    at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
    at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
    at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:261)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:167)
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:247)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: Illegal character: <<>
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.yylex(JsonScanner.java:776)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.nextSymbol(JsonScanner.java:310)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.next(JsonStreamSourceImpl.java:136)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.peek(JsonStreamSourceImpl.java:272)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.consume(JsonXMLStreamReader.java:129)
    at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.initialize(AbstractXMLStreamReader.java:243)
    ... 29 more
TID: [-1] [] [2016-01-21 17:40:51,751] ERROR {org.apache.axis2.transport.base.threads.NativeWorkerPool} -  Uncaught exception {org.apache.axis2.transport.base.threads.NativeWorkerPool}
org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: java.lang.RuntimeException: Error obtaining parser from data source:java.io.IOException: Illegal character: <<>
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296)
    at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
    at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
    at org.apache.axiom.om.impl.llom.OMElementImpl.cloneOMElement(OMElementImpl.java:1065)
    at org.wso2.carbon.tracer.module.handler.TracingMessageInObservationHandler.invoke(TracingMessageInObservationHandler.java:33)
    at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
    at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
    at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:261)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:167)
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:247)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javax.xml.stream.XMLStreamException: java.lang.RuntimeException: Error obtaining parser from data source:java.io.IOException: Illegal character: <<>
    at org.apache.axiom.om.impl.SwitchingWrapper.updateLastNode(SwitchingWrapper.java:1106)
    at org.apache.axiom.om.impl.SwitchingWrapper.next(SwitchingWrapper.java:1041)
    at javax.xml.stream.util.StreamReaderDelegate.next(StreamReaderDelegate.java:88)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
    at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
    ... 13 more
Caused by: java.lang.RuntimeException: Error obtaining parser from data source:java.io.IOException: Illegal character: <<>
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getDirectReader(OMSourcedElementImpl.java:230)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.forceExpand(OMSourcedElementImpl.java:254)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getFirstOMChild(OMSourcedElementImpl.java:867)
    at org.apache.axiom.om.impl.OMNavigator._getFirstChild(OMNavigator.java:196)
    at org.apache.axiom.om.impl.OMNavigator.updateNextNode(OMNavigator.java:140)
    at org.apache.axiom.om.impl.OMNavigator.getNext(OMNavigator.java:112)
    at org.apache.axiom.om.impl.SwitchingWrapper.updateNextNode(SwitchingWrapper.java:1113)
    at org.apache.axiom.om.impl.SwitchingWrapper.updateLastNode(SwitchingWrapper.java:1104)
    ... 17 more
Caused by: javax.xml.stream.XMLStreamException: java.io.IOException: Illegal character: <<>
    at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.initialize(AbstractXMLStreamReader.java:245)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.<init>(JsonXMLStreamReader.java:66)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLInputFactory.createXMLStreamReader(JsonXMLInputFactory.java:165)
    at org.apache.synapse.commons.json.JsonUtil.getReader(JsonUtil.java:274)
    at org.apache.synapse.commons.json.JsonDataSource.getReader(JsonDataSource.java:153)
    at org.apache.axiom.om.impl.llom.OMSourcedElementImpl.getDirectReader(OMSourcedElementImpl.java:225)
    ... 24 more
Caused by: java.io.IOException: Illegal character: <<>
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.yylex(JsonScanner.java:776)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonScanner.nextSymbol(JsonScanner.java:310)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.next(JsonStreamSourceImpl.java:136)
    at org.apache.synapse.commons.staxon.core.json.stream.impl.JsonStreamSourceImpl.peek(JsonStreamSourceImpl.java:272)
    at org.apache.synapse.commons.staxon.core.json.JsonXMLStreamReader.consume(JsonXMLStreamReader.java:129)
    at org.apache.synapse.commons.staxon.core.base.AbstractXMLStreamReader.initialize(AbstractXMLStreamReader.java:243)
    ... 29 more

这是来自 REST 代理服务的代码:

<?xml version="1.0" encoding="UTF-8"?>
<proxy name="PX_AbstractRestCall" startOnLoad="true" trace="disable"
    transports="http https" xmlns="http://ws.apache.org/ns/synapse">
    <target>
        <inSequence>
            <property expression="//calls/action" name="method" scope="default"
                type="STRING" />
            <property expression="//calls/endpoint" name="endpoint"
                scope="default" type="STRING" />
            <property expression="//calls/format" name="format" scope="default"
                type="STRING" />
            <property expression="//calls/type" name="type" scope="default"
                type="STRING" />
            <property expression="//calls/scriptIn" name="javascriptIn"
                scope="default" type="STRING" />
            <property expression="//calls/scriptOut" name="javascriptOut"
                scope="default" type="STRING" />
            <log level="custom">
                <property expression="get-property('javascriptIn')" name="javascriptIn" />
                <property expression="get-property('javascriptOut')" name="javascriptOut" />
            </log>
            <log level="full">
                <property expression="$body" name="requestPayload" />
            </log>
            <script function="inputTransform" key="{get-property('javascriptIn')}"
                language="js" />
            <log level="custom">
                <property expression="$body" name="payloadInput" />
            </log>
            <header expression="get-property('endpoint')" name="To" scope="default" />
            <property expression="get-property('method')" name="HTTP_METHOD"
                scope="axis2" type="STRING" />
            <log level="custom">
                <property expression="get-property('format')" name="format" />
            </log>
            <switch source="get-property('format')">
                <case regex="json">
                    <property name="messageType" scope="axis2" type="STRING"
                        value="application/json" />
                </case>
                <case regex="xml">
                    <property name="messageType" scope="axis2" type="STRING"
                        value="application/xml" />
                </case>
                <default />
            </switch>
            <send>
                <endpoint name="AbtractRestEndpoint" template="EPT_AbtractRestEndpoint" />
            </send>
        </inSequence>
        <outSequence>
            <log level="custom">
                <property expression="$body" name="payloadOutput" />
            </log>
            <script function="outputTransform" key="{get-property('javascriptOut')}"
                language="js" />
            <property name="messageType" scope="axis2" type="STRING"
                value="application/xml" />
            <log level="custom">
                <property expression="$body" name="transformedPayload" />
            </log>
            <send />
        </outSequence>
        <faultSequence />
    </target>
</proxy>

我试过直接调用此服务,但使用相同的有效负载时效果很好。

谁能帮帮我!

谢谢!

我发现了问题。令我惊讶的是,这个错误非常奇怪。

使用命令 tcpdump 我发现我的两个测试的 HTTP Header 之间存在差异。

  1. 第一次测试: 迭代 1 次调用 rest 服务。

  2. 第二个测试: 迭代 2 个调用,一个用于休息服务,另一个用于肥皂服务。

第二次测试带有 VaryContent-Encoding,Content-Encoding 的值为 gzip。这些值正在压缩 JSON 请求 body 然后是服务 return 我这个响应:

Content-Length: 1386
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=utf-8

<div style="border:1px solid #990000;padding-left:20px;margin:0 0 10px 0;">

   <h4>A PHP Error was encountered</h4>
   <p>Severity: Notice</p>
   <p>Message:  Trying to get property of non-object</p>
   <p>Filename: some.php</p>
   <p>Line Number: 15</p>
   <p>Backtrace:</p>
   <p style="margin-left:10px">
      File: some.php<br />
      Line: 15<br />
      Function: _error_handler</p>
   <p style="margin-left:10px">
        File: some.php<br />
        Line: 292<br />
        Function: require_once</p>  
</div>{
"data": [
        {
            "field1": "1111",
            "field2": "1111",
            "field3": "5"
        }
    ]
}

出于这个原因,ESB 抛出异常。 我的解决方法是在我的 REST 代理服务中添加这些行:

<property name="Vary" scope="transport" action="remove"/>
<property name="Content-Encoding" scope="transport" action="remove"/>