| 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); | 
|             } | 
|         } | 
|     } | 
| } |