zrg
2024-08-16 18865d8bf24382e850e661dec6cca0e8b9dba6ae
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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);
            }
        }
    }
}