|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Linq;
|
|
|
using System.Security.Cryptography;
|
|
|
using System.Text;
|
|
|
using POSV.Entity;
|
|
|
using POSV.HttpApi;
|
|
|
using POSV.LoadBalance;
|
|
|
|
|
|
namespace POSV.Utils
|
|
|
{
|
|
|
public class OpenApiUtils
|
|
|
{
|
|
|
static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
|
|
|
|
private static object _lock = new object();
|
|
|
|
|
|
private static OpenApiUtils _instance = null;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 数据表中配置的API接口
|
|
|
/// </summary>
|
|
|
private Dictionary<string,Apis> _apis;
|
|
|
|
|
|
/// <summary>
|
|
|
/// 数据表中API接口对应的URL列表
|
|
|
/// </summary>
|
|
|
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)
|
|
|
{
|
|
|
this._apis[api.ApiType] = api;
|
|
|
|
|
|
//查找ApiType匹配的全部URLS
|
|
|
var servers = urls.FindAll(x => x.ApiType == api.ApiType);
|
|
|
|
|
|
if (servers != null && servers.Count > 0)
|
|
|
{
|
|
|
var list = new List<OpenApi>();
|
|
|
foreach (var url in servers)
|
|
|
{
|
|
|
var openApi = new OpenApi();
|
|
|
|
|
|
openApi.Url = string.Format("{0}://{1}/{2}/api" , url.Protocol , url.Url , url.ContextPath);
|
|
|
|
|
|
openApi.Open = string.Format("{0}://{1}/{2}/open/api/extend" , url.Protocol , url.Url , url.ContextPath);
|
|
|
|
|
|
openApi.ApiType = (ApiType)Enum.Parse(typeof(ApiType) , url.ApiType);
|
|
|
|
|
|
openApi.AppKey = api.AppKey;
|
|
|
openApi.AppSecret = api.AppSecret;
|
|
|
openApi.Client = api.Client;
|
|
|
openApi.Locale = api.Locale;
|
|
|
openApi.Format = api.Format;
|
|
|
openApi.Version = api.Version;
|
|
|
|
|
|
openApi.Memo = url.Memo;
|
|
|
|
|
|
list.Add(openApi);
|
|
|
}
|
|
|
|
|
|
this._urls[api.ApiType] = list;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public void Refresh()
|
|
|
{
|
|
|
lock (_lock)
|
|
|
{
|
|
|
//Global.Instance.ReloadConfig(ConfigConstant.CONFIG_GROUP_SYSTEM);
|
|
|
|
|
|
Init();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
public OpenApi NextApi(ApiType api)
|
|
|
{
|
|
|
IRouting<OpenApi> routing = null;
|
|
|
if (!this._apis.ContainsKey(api.ToString())) {
|
|
|
return 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;
|
|
|
case "3"://一致性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;
|
|
|
}
|
|
|
|
|
|
/// <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);
|
|
|
|
|
|
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();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|