已配置所有参数仍遇Endpoint null解析问题,求排查原因
API调用异常排查与解决
场景
该API流程分为两步:
- 先调用认证接口获取token
- 将token放入请求头,携带业务查询参数调用第二个业务接口
问题现象
成功调用第一个认证接口并获取到token,但调用第二个业务接口时出现null resolving to address错误,最终触发客户端与EI的连接超时。
日志信息
[2022-11-09 18:08:19,327] INFO {LogMediator} - {api:MsaasproEsb} To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: , SOAPAction: , MessageID: urn:uuid:e763462f-c7dc-4f3d-a8ba-b23c5f66a241, correlation_id: 7dba4bab-4218-48ca-9871-e4c2d249a91b, Direction: request, Payload: {"Data": {"status": 200, "id": 190, "user_id": "secpapi", "email": "Faisal.furqan@secp.gov.pk", "token": "9704e4de2acde3af0686c22d409f831db3d1fd76"}} [2022-11-09 18:08:19,328] INFO {TRACE_LOGGER} - Sending message through endpoint : null resolving to address = https://msaaspro.com/api/v1/scan/pep-scan/?fullname={uri.var.name}&searchtype=fuzzy&fathername={uri.var.fatherName}&dobyear={uri.var.dobYear}&cnic={uri.var.cnic}&mobile={uri.var.mobile}&country={uri.var.country}&name_similarity=90 [2022-11-09 18:08:19,328] INFO {TRACE_LOGGER} - SOAPAction: [2022-11-09 18:08:19,328] INFO {TRACE_LOGGER} - WSA-Action: [2022-11-09 18:09:17,775] INFO {SourceHandler} - Writer null when calling informWriterError [2022-11-09 18:09:17,775] WARN {SourceHandler} - STATE_DESCRIPTION = Socket Timeout occurred after accepting the request headers and the request body, INTERNAL_STATE = REQUEST_DONE, DIRECTION = REQUEST, CAUSE_OF_ERROR = Connection between the client and the EI timeouts, HTTP_URL = /msaaspro/send, HTTP_METHOD = POST, SOCKET_TIMEOUT = 180000, CLIENT_ADDRESS = /127.0.0.1:55470, CONNECTION http-incoming-4 Correlation ID : 965986e6-2d6b-4108-aefe-3a7a648eb61a [2022-11-09 18:10:44,079] INFO {SourceHandler} - Writer null when calling informWriterError [2022-11-09 18:10:44,079] WARN {SourceHandler} - STATE_DESCRIPTION = Socket Timeout occurred after accepting the request headers and the request body, INTERNAL_STATE = REQUEST_DONE, DIRECTION = REQUEST, CAUSE_OF_ERROR = Connection between the client and the EI timeouts, HTTP_URL = /msaaspro/send, HTTP_METHOD = POST, SOCKET_TIMEOUT = 180000, CLIENT_ADDRESS = /127.0.0.1:58755, CONNECTION http-incoming-5 Correlation ID : 1fc72034-a9d1-46ad-9198-d18810065c10 [2022-11-09 18:11:19,011] INFO {SourceHandler} - Writer null when calling informWriterError [2022-11-09 18:11:19,011] WARN {SourceHandler} - STATE_DESCRIPTION = Socket Timeout occurred after accepting the request headers and the request body, INTERNAL_STATE = REQUEST_DONE, DIRECTION = REQUEST, CAUSE_OF_ERROR = Connection between the client and the EI timeouts, HTTP_URL = /msaaspro/send, HTTP_METHOD = POST, SOCKET_TIMEOUT = 180000, CLIENT_ADDRESS = /127.0.0.1:58781, CONNECTION http-incoming-6 Correlation ID : 7dba4bab-4218-48ca-9871-e4c2d249a91b
原始代码
<?xml version="1.0" encoding="UTF-8"?> <api context="/msaaspro" name="MsaasproEsb" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="POST" uri-template="/send"> <inSequence> <property description="username" name="username" scope="default" type="STRING" value="json-eval($.username)"/> <property description="password" name="password" scope="default" type="STRING" value="json-eval($.password)"/> <call> <endpoint> <http method="post" statistics="enable" uri-template="https://msaaspro.com/api/v1/auth/auth-token/"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <property description="token" name="token" scope="default" type="STRING" value="json-eval($.Data.token)"/> <property description="Authorization" name="Authorization" scope="transport" type="STRING" value="fn:concat('Token ', get-property('token'))"/> <property description="name" name="uri.var.name" scope="default" type="STRING" value="json-eval($.name)"/> <property description="fatherName" name="uri.var.fatherName" scope="default" type="STRING" value="json-eval($.fatherName)"/> <property description="dobYear" name="uri.var.dobYear" scope="default" type="STRING" value="json-eval($.dobYear)"/> <property description="uniqueKey" name="uri.var.cnic" scope="default" type="STRING" value="json-eval($.cnic)"/> <property description="country" name="uri.var.country" scope="default" type="STRING" value="json-eval($.country)"/> <property description="mobile" name="uri.var.mobile" scope="default" type="STRING" value="json-eval($.mobile)"/> <log level="full"/> <call> <endpoint> <http method="get" statistics="enable" trace="enable" uri-template="https://msaaspro.com/api/v1/scan/pep-scan/?fullname={uri.var.name}&searchtype=fuzzy&fathername={uri.var.fatherName}&dobyear={uri.var.dobYear}&cnic={uri.var.cnic}&mobile={uri.var.mobile}&country={uri.var.country}&name_similarity=90"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> </inSequence> <outSequence> <respond/> </outSequence> <faultSequence/> </resource> </api>
问题根源
<call> mediator执行后,当前消息的payload会被替换为目标接口的响应内容。在原始代码中:
- 第一个
<call>调用认证接口后,消息体变成了token的响应JSON,不再包含客户端原始请求的name、fatherName等字段 - 后续提取业务参数的
json-eval($.name)等操作,因当前消息体中无对应字段,导致属性值为null - 第二个endpoint的URI模板无法解析
null值的参数,进而引发请求异常,最终触发超时
解决方法
在第一个<call>执行前,先提取所有需要的业务参数并保存到属性中,确保参数不会被后续的响应覆盖。修改后的代码如下:
<?xml version="1.0" encoding="UTF-8"?> <api context="/msaaspro" name="MsaasproEsb" xmlns="http://ws.apache.org/ns/synapse"> <resource methods="POST" uri-template="/send"> <inSequence> <!-- 先提取所有需要的参数,此时消息体是客户端原始请求 --> <property description="username" name="username" scope="default" type="STRING" value="json-eval($.username)"/> <property description="password" name="password" scope="default" type="STRING" value="json-eval($.password)"/> <property description="name" name="uri.var.name" scope="default" type="STRING" value="json-eval($.name)"/> <property description="fatherName" name="uri.var.fatherName" scope="default" type="STRING" value="json-eval($.fatherName)"/> <property description="dobYear" name="uri.var.dobYear" scope="default" type="STRING" value="json-eval($.dobYear)"/> <property description="uniqueKey" name="uri.var.cnic" scope="default" type="STRING" value="json-eval($.cnic)"/> <property description="country" name="uri.var.country" scope="default" type="STRING" value="json-eval($.country)"/> <property description="mobile" name="uri.var.mobile" scope="default" type="STRING" value="json-eval($.mobile)"/> <!-- 调用认证接口获取token --> <call> <endpoint> <http method="post" statistics="enable" uri-template="https://msaaspro.com/api/v1/auth/auth-token/"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> <!-- 提取token并设置请求头 --> <property description="token" name="token" scope="default" type="STRING" value="json-eval($.Data.token)"/> <property description="Authorization" name="Authorization" scope="transport" type="STRING" value="fn:concat('Token ', get-property('token'))"/> <log level="full"/> <!-- 调用业务接口,此时参数已提前保存,可正常解析 --> <call> <endpoint> <http method="get" statistics="enable" trace="enable" uri-template="https://msaaspro.com/api/v1/scan/pep-scan/?fullname={uri.var.name}&searchtype=fuzzy&fathername={uri.var.fatherName}&dobyear={uri.var.dobYear}&cnic={uri.var.cnic}&mobile={uri.var.mobile}&country={uri.var.country}&name_similarity=90"> <suspendOnFailure> <initialDuration>-1</initialDuration> <progressionFactor>-1</progressionFactor> <maximumDuration>0</maximumDuration> </suspendOnFailure> <markForSuspension> <retriesBeforeSuspension>0</retriesBeforeSuspension> </markForSuspension> </http> </endpoint> </call> </inSequence> <outSequence> <respond/> </outSequence> <faultSequence/> </resource> </api>
内容的提问来源于stack exchange,提问作者Ayub Jamal
相关产品推荐
相关产品推荐

