using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; using System.Data; using System.Collections; using JwKdsV.Entity.Common; using JwKdsV.Core.HttpApi; using JwKdsV.Core.LoadBalance; namespace JwKdsV.Core.Utils { public class OpenApiUtils { static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); private static object _lock = new object(); private static OpenApiUtils _instance = null; private Dictionary _apis; private Dictionary> _urls; public static OpenApiUtils Instance { get { if (_instance == null) { lock (_lock) { _instance = new OpenApiUtils(); _instance.Init(); } } return _instance; } } private void Init() { this._apis = new Dictionary(); this._urls = new Dictionary>(); Tuple, List> result = null; using(var db = Global.Instance.OpenDataBase) { result = db.FetchMultiple(SqlConstant.ApisQueryAll + SqlConstant.UrlsQueryAll); } if(result != null) { var apis = result.Item1; var urls = result.Item2; foreach(var api in apis) { _apis[api.ApiType] = api; var serverList = urls.FindAll(x => x.ApiType == api.ApiType); if(serverList != null && serverList.Count > 0) { List list = new List(); foreach (var server in serverList) { OpenApi openApi = new OpenApi(); openApi.ApiType = (ApiType)Enum.Parse(typeof(ApiType), server.ApiType); openApi.AppKey = api.AppKey; openApi.AppSecret = api.AppSecret; openApi.Url = string.Format("{0}://{1}/{2}/api", server.Protocol, server.Url, server.ContextPath); openApi.Open = string.Format("{0}://{1}/{2}/open/api/extend", server.Protocol, server.Url, server.ContextPath); openApi.Client = api.Client; openApi.Locale = api.Locale; openApi.Version = api.Version; openApi.Format = api.Format; openApi.Memo = server.Memo; list.Add(openApi); } this._urls[api.ApiType] = list; } } } } public OpenApi NextApi(ApiType api) { IRouting routing = null; string balance = this._apis[api.ToString()].Routing + ""; switch (balance) { case "0"://随机 routing = new RandomRouting(); break; case "1"://轮询 routing = new RoundRobinRouting(this._urls.Values.Count); break; case "2"://一致性Hash routing = new ConsistentHashRouting(this._urls.Values.Count); break; default: routing = new RandomRouting(); break; } var apis = routing.select("juweiyun.cn", this._urls[api.ToString()].ToArray()); return apis; } public void Refresh() { lock (_lock) { //Global.Instance.ReloadConfig(ConfigConstant.CONFIG_GROUP_SYSTEM); Init(); } } /// /// 获取当前时间戳,兼容Java服务端 /// /// public string GetTimestamp() { TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - new DateTime(1970, 1, 1, 0, 0, 0).Ticks); return Convert.ToString((long)ts.TotalMilliseconds); } public SortedList NewParameters(OpenApi api) { SortedList parameters = new SortedList(); parameters.Add("appKey", api.AppKey); parameters.Add("format", api.Format); parameters.Add("locale", api.Locale); parameters.Add("timestamp", GetTimestamp()); parameters.Add("client", api.Client); parameters.Add("v", api.Version); //parameters.Add("tenantId", api.TenantId); //if (null != Global.Instance.Worker) //{ // parameters.Add("sessionId", Global.Instance.Worker.SessionId); //} return parameters; } /// /// 开放平台签名算法 /// /// /// public string Sign(OpenApi api, SortedList parameters) { return Sign(api, parameters, null); } /// /// 开放平台签名算法 /// /// /// public string Sign(OpenApi api, SortedList parameters, List ignoreParameters) { IList keys = parameters.Keys; var paramNames = new List(keys.Count); paramNames.AddRange(keys); if (ignoreParameters != null && ignoreParameters.Count > 0) { foreach (string ignore in ignoreParameters) { paramNames.Remove(ignore); } } StringBuilder input = new StringBuilder(); input.Append(api.AppSecret); foreach (string key in paramNames) { input.Append(key + parameters[key]); } input.Append(api.AppSecret); SHA1 sha1 = new SHA1CryptoServiceProvider();//建立一个SHA1 byte[] source = Encoding.UTF8.GetBytes(input.ToString());//将字符串转为Byte[] byte[] crypto = sha1.ComputeHash(source);//进行SHA1加密 return ByteArrayToHexString(crypto);//把加密后的字符串从Byte[]转为字符串 } /// /// 字节数组转十六进制字符串 /// /// /// public string ByteArrayToHexString(byte[] data) { StringBuilder sb = new StringBuilder(data.Length * 3); foreach (byte b in data) { sb.Append(Convert.ToString(b, 16).PadLeft(2, '0')); } return sb.ToString().ToUpper(); } } }