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