You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
7.1 KiB
C#

9 months ago
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<string, Apis> _apis;
private Dictionary<string, List<OpenApi>> _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<string, Apis>();
this._urls = new Dictionary<string, List<OpenApi>>();
Tuple<List<Apis>, List<Urls>> result = null;
using(var db = Global.Instance.OpenDataBase)
{
result = db.FetchMultiple<Apis, Urls>(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<OpenApi> list = new List<OpenApi>();
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<OpenApi> routing = null;
string balance = this._apis[api.ToString()].Routing + "";
switch (balance)
{
case "0"://随机
routing = new RandomRouting<OpenApi>();
break;
case "1"://轮询
routing = new RoundRobinRouting<OpenApi>(this._urls.Values.Count);
break;
case "2"://一致性Hash
routing = new ConsistentHashRouting<OpenApi>(this._urls.Values.Count);
break;
default:
routing = new RandomRouting<OpenApi>();
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();
}
}
/// <summary>
/// 获取当前时间戳兼容Java服务端
/// </summary>
/// <returns></returns>
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<string, string> NewParameters(OpenApi api)
{
SortedList<string, string> parameters = new SortedList<string, string>();
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;
}
/// <summary>
/// 开放平台签名算法
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
public string Sign(OpenApi api, SortedList<string, string> parameters)
{
return Sign(api, parameters, null);
}
/// <summary>
/// 开放平台签名算法
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
public string Sign(OpenApi api, SortedList<string, string> parameters, List<string> ignoreParameters)
{
IList<string> keys = parameters.Keys;
var paramNames = new List<string>(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[]转为字符串
}
/// <summary>
/// 字节数组转十六进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
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();
}
}
}