using System;
|
using System.Collections.Generic;
|
using System.Text;
|
using QimenCloud.Api.Parser;
|
using Top.Api;
|
using Top.Api.Parser;
|
using Top.Api.Util;
|
|
namespace Qimen.Api
|
{
|
public class DefaultQimenClient : IQimenClient
|
{
|
protected string serverUrl;
|
protected string appKey;
|
protected string appSecret;
|
protected string format = Constants.FORMAT_XML;
|
protected string signMethod = Constants.SIGN_METHOD_MD5;
|
protected int connectTimeout = 15000; // 默认连接超时时间为15秒
|
protected int readTimeout = 30000; // 默认响应超时时间为30秒
|
|
private bool disableParser = false; // 禁用响应结果解释
|
private bool disableTrace = false; // 禁用日志调试功能
|
private bool useGzipEncoding = true; // 是否启用响应GZIP压缩
|
|
protected WebUtils webUtils;
|
protected ITopLogger topLogger;
|
|
public DefaultQimenClient(string serverUrl, string appKey, string appSecret)
|
{
|
this.serverUrl = serverUrl;
|
this.appKey = appKey;
|
this.appSecret = appSecret;
|
this.webUtils = new WebUtils();
|
this.topLogger = Top.Api.Log.Instance;
|
}
|
|
public T Execute<T>(QimenRequest<T> request) where T : QimenResponse
|
{
|
return Execute(request, null);
|
}
|
|
public T Execute<T>(QimenRequest<T> request, string session) where T : QimenResponse
|
{
|
return DoExecute(request, session);
|
}
|
|
private T DoExecute<T>(QimenRequest<T> request, string session) where T : QimenResponse
|
{
|
long start = DateTime.Now.Ticks;
|
|
// 添加协议级请求参数
|
TopDictionary parameters = new TopDictionary();
|
if (request.GetQueryParameters() != null)
|
{
|
parameters.AddAll(request.GetQueryParameters());
|
}
|
|
parameters.Add(Constants.METHOD, request.GetApiName());
|
parameters.Add(Constants.VERSION, request.Version);
|
parameters.Add(Constants.APP_KEY, appKey);
|
parameters.Add(Constants.TIMESTAMP, request.Timestamp);
|
parameters.Add(Constants.FORMAT, format);
|
parameters.Add(Constants.SIGN_METHOD, signMethod);
|
parameters.Add(Constants.SESSION, session);
|
parameters.Add(Constants.PARTNER_ID, Constants.SDK_VERSION);
|
parameters.Add(Constants.QM_CUSTOMER_ID, request.CustomerId);
|
|
// 添加头部参数
|
if (this.useGzipEncoding)
|
{
|
request.AddHeaderParameter(Constants.ACCEPT_ENCODING, Constants.CONTENT_ENCODING_GZIP);
|
}
|
|
try
|
{
|
string reqBody = request.Body;
|
if (string.IsNullOrEmpty(reqBody))
|
{
|
XmlWriter writer = new XmlWriter(Constants.QM_ROOT_TAG_REQ, typeof(QimenRequest<T>));
|
reqBody = writer.Write(request);
|
}
|
|
// 添加签名参数
|
parameters.Add(Constants.SIGN, TopUtils.SignTopRequest(parameters, reqBody, appSecret, signMethod));
|
|
string fullUrl = WebUtils.BuildRequestUrl(serverUrl, parameters);
|
string rspBody = webUtils.DoPost(fullUrl, Encoding.UTF8.GetBytes(reqBody), Constants.QM_CONTENT_TYPE, request.GetHeaderParameters());
|
|
// 解释响应结果
|
T rsp = null;
|
if (disableParser)
|
{
|
rsp = Activator.CreateInstance<T>();
|
rsp.Body = rspBody;
|
}
|
else
|
{
|
if (Constants.FORMAT_XML.Equals(format))
|
{
|
ITopParser<T> tp = new QimenXmlParser<T>();
|
rsp = tp.Parse(rspBody);
|
}
|
}
|
|
// 追踪错误的请求
|
if (rsp != null && rsp.IsError)
|
{
|
TimeSpan latency = new TimeSpan(DateTime.Now.Ticks - start);
|
TraceApiError(appKey, request.GetApiName(), serverUrl, parameters, latency.TotalMilliseconds, rspBody);
|
}
|
return rsp;
|
}
|
catch (Exception e)
|
{
|
TimeSpan latency = new TimeSpan(DateTime.Now.Ticks - start);
|
TraceApiError(appKey, request.GetApiName(), serverUrl, parameters, latency.TotalMilliseconds, e.GetType() + ": " + e.Message);
|
throw e;
|
}
|
}
|
|
public void SetTimeout(int timeout)
|
{
|
this.webUtils.Timeout = timeout;
|
}
|
|
public void SetReadWriteTimeout(int readWriteTimeout)
|
{
|
this.webUtils.ReadWriteTimeout = readWriteTimeout;
|
}
|
|
public void SetDisableParser(bool disableParser)
|
{
|
this.disableParser = disableParser;
|
}
|
|
public void SetDisableTrace(bool disableTrace)
|
{
|
this.disableTrace = disableTrace;
|
}
|
|
public void SetUseGzipEncoding(bool useGzipEncoding)
|
{
|
this.useGzipEncoding = useGzipEncoding;
|
}
|
|
public void SetIgnoreSSLCheck(bool ignore)
|
{
|
this.webUtils.IgnoreSSLCheck = ignore;
|
}
|
|
private void TraceApiError(string appKey, string apiName, string url, Dictionary<string, string> parameters, double latency, string errorMessage)
|
{
|
if (!disableTrace)
|
{
|
this.topLogger.TraceApiError(appKey, apiName, url, parameters, latency, errorMessage);
|
}
|
}
|
}
|
}
|