我是WSO2 EI的新手,我在尝试从我的ESB流中定义的 API调用DSS服务时发现了一些问题。
我是这样做的:
1) 在与我的DSS服务相关的agrimarketprice-dss.dbs文件中,我进行了以下操作:
<operation name="GetCommodityDetails">
<call-query href="SelectCommodityDetails">
<with-param name="commodity_details_id" query-param="commodity_details_id"/>
</call-query>
</operation>
调用具有id=commodity_details_id的查询。它工作正常,我使用Try It工具对其进行了测试,并获得了预期的结果集。
2) 然后我定义了这个ESB流定义的 API:
<?xml version="1.0" encoding="UTF-8"?>
<api context="/commodity_details" name="commodity_details" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" uri-template="/{commodityId}">
<inSequence>
<property expression="get-property('uri.var.commodityId')" name="commodityId" scope="default" type="STRING"/>
<log level="custom"/>
<log description="commodity_details" level="custom" separator="-">
<property name="commodity_details" value="'commodity_details START'"/>
</log>
<log level="custom">
<property expression="$ctx:commodityId" name="COMMODITY ID"/>
</log>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="xml" expression="$ctx:commodityId" xmlns:ds="http://ws.wso2.org/dataservice" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
正如您在前面的 ESB 流程中看到的,我试图以这种方式调用定义到我的 DSS 服务中的前面的操作:
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="xml" expression="$ctx:commodityId" xmlns:ds="http://ws.wso2.org/dataservice" xmlns:ns="http://org.apache.synapse/xsd"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
因此,我正在创建一个有效负载,其中包含由$ctx:commodityId表示的检索到的 ID (它包含正确的值,因为我记录了它)。然后我将标题设置为必须执行的操作的名称(“urn:GetCommodityDetails”)。最后,我对包含先前 DSS 服务详细信息的agrimarketprice_Endpoint执行调用,这是内容:
<?xml version="1.0" encoding="UTF-8"?>
<endpoint name="agrimarketprice_Endpoint" xmlns="http://ws.apache.org/ns/synapse">
<address uri="http://localhost:8280/services/agrimarketprice-dss"/>
</endpoint>
这个端点是正确的,因为我将它用于另一个 API 中的另一个查询(但它具有不同的逻辑,因为在另一个查询中我从 JSON 文档中提取参数)。
问题是,当我调用我的 API 时,我在 Carbon 日志中获得了以下错误消息(我认为当它尝试执行执行我的查询的调用时):
TID: [-1234] [] [2017-10-03 11:55:16,574] INFO {org.apache.synapse.mediators.builtin.LogMediator} - {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,574] INFO {org.apache.synapse.mediators.builtin.LogMediator} - commodity_details = 'commodity_details START' {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,575] INFO {org.apache.synapse.mediators.builtin.LogMediator} - COMMODITY ID = 1 {org.apache.synapse.mediators.builtin.LogMediator}
TID: [-1234] [] [2017-10-03 11:55:16,597] INFO {org.apache.synapse.core.axis2.TimeoutHandler} - This engine will expire all callbacks after GLOBAL_TIMEOUT: 120 seconds, irrespective of the timeout action, after the specified or optional timeout {org.apache.synapse.core.axis2.TimeoutHandler}
TID: [-1234] [] [2017-10-03 11:55:16,637] ERROR {org.apache.axis2.engine.AxisEngine} - The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator. {org.apache.axis2.engine.AxisEngine}
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:102)
at org.apache.axis2.engine.Phase.invoke(Phase.java:329)
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.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:326)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:158)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
TID: [-1234] [] [2017-10-03 11:55:16,642] ERROR {org.apache.synapse.transport.passthru.ServerWorker} - Error processing GET request for : /services/agrimarketprice-dss/1 {org.apache.synapse.transport.passthru.ServerWorker}
org.apache.axis2.AxisFault: The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null. If this EPR was previously reachable, please contact the server administrator.
at org.apache.axis2.engine.DispatchPhase.checkPostConditions(DispatchPhase.java:102)
at org.apache.axis2.engine.Phase.invoke(Phase.java:329)
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.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:326)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:158)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
TID: [-1] [] [2017-10-03 11:58:16,778] INFO {org.apache.synapse.transport.passthru.SourceHandler} - Writer null when calling informWriterError {org.apache.synapse.transport.passthru.SourceHandler}
TID: [-1] [] [2017-10-03 11:58:16,780] WARN {org.apache.synapse.transport.passthru.SourceHandler} - Connection time out after request is read: http-incoming-6 Socket Timeout : 180000 Remote Address : /168.202.253.227:62418 {org.apache.synapse.transport.passthru.SourceHandler}
在我看来,这个错误应该与这个日志信息有关:
The endpoint reference (EPR) for the Operation not found is /services/agrimarketprice-dss/1 and the WSA Action = null
似乎它试图将传递的 id (1) 附加到agrimarketprice-dss(即服务名称)而忽略操作(即GetCommodityDetails并且我在标题中指定)。
那么有什么问题呢?我错过了什么?如何尝试修复此错误?
EDIT-1:我尝试了另一种方法:API 不会从 URL 路径中检索商品 ID,而是从请求中这样的 JSON 文档中检索:
{
"commodity_id": 1
}
因此,以这种方式更改 API 工作正常,查询正确执行(但我需要从 URL 中检索商品ID 并将其用作查询参数(因此它可能只是一种解决方法):
<?xml version="1.0" encoding="UTF-8"?>
<api context="/commodity_details" name="commodity_details" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" protocol="http" uri-template="/">
<inSequence>
<log level="full"/>
<log level="custom">
<property expression="json-eval($.commodity_id)" name="Commodity ID"/>
</log>
<property expression="json-eval($.commodity_id)" name="CommodityId" scope="default" type="STRING"/>
<property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
<payloadFactory media-type="xml">
<format>
<ds:GetCommodityDetails xmlns:ds="http://ws.wso2.org/dataservice">
<ds:commodity_details_id>$1</ds:commodity_details_id>
</ds:GetCommodityDetails>
</format>
<args>
<arg evaluator="json" expression="$.commodity_id"/>
</args>
</payloadFactory>
<header name="Action" scope="default" value="urn:GetCommodityDetails"/>
<call>
<endpoint key="agrimarketprice_Endpoint"/>
</call>
<send/>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence/>
</resource>
</api>
因此以这种方式正确调用 DSS 服务、执行查询和 API 将预期输出发送回客户端。
但是为什么从 POST 请求中的 JSON 文档中检索 ID 可以正常工作,但从 URL 中检索它却不起作用?