using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Xml.Serialization;
|
using Top.Api.Util;
|
|
namespace Top.Api.Cluster
|
{
|
public class Weightable
|
{
|
public double Weight { get; set; }
|
}
|
public class ApiRule : Weightable
|
{
|
public string Name { get; set; }
|
}
|
public class ApiConfig
|
{
|
public string User { get; set; }
|
|
public List<ApiRule> Rules { get; set; }
|
}
|
|
public class VipRule : Weightable
|
{
|
public string Vip { get; set; }
|
}
|
|
public class EnvConfig
|
{
|
public string Domain { get; set; }
|
|
public string Protocol { get; set; }
|
|
public List<VipRule> VipRules { get; set; }
|
}
|
public class DnsConfig
|
{
|
public IDictionary<string, string> GlobalDict { get; set; }
|
|
public IDictionary<string, ApiConfig> ApiDict { get; set; }
|
|
public IDictionary<string, List<EnvConfig>> EnvDict { get; set; }
|
|
public IDictionary<string, IDictionary<string, string>> UserDict { get; set; }
|
|
public static DnsConfig parse(string json)
|
{
|
DnsConfig dnsConfig = new DnsConfig();
|
IDictionary root = TopUtils.JsonToObject(json) as IDictionary;
|
foreach (string configType in root.Keys)
|
{
|
if ("config".Equals(configType))
|
{
|
dnsConfig.GlobalDict = new Dictionary<string, string>();
|
IDictionary globalInfo = root[configType] as IDictionary;
|
foreach (string key in globalInfo.Keys)
|
{
|
dnsConfig.GlobalDict[key] = globalInfo[key] as string;
|
}
|
}
|
else if ("env".Equals(configType))
|
{
|
IDictionary envInfos = root[configType] as IDictionary;
|
dnsConfig.EnvDict = new Dictionary<string, List<EnvConfig>>();
|
foreach (string envName in envInfos.Keys)
|
{
|
IDictionary envInfo = envInfos[envName] as IDictionary;
|
List<EnvConfig> envConfigs = new List<EnvConfig>();
|
|
foreach (string domainName in envInfo.Keys)
|
{
|
IDictionary domainInfo = envInfo[domainName] as IDictionary;
|
EnvConfig envConfig = new EnvConfig();
|
envConfig.Domain = domainName as string;
|
envConfig.Protocol = domainInfo["proto"] as string;
|
IList vipInfos = domainInfo["vip"] as IList;
|
List<VipRule> vipRules = new List<VipRule>();
|
foreach (string vipInfo in vipInfos)
|
{
|
string[] vipInfoTmp = vipInfo.ToString().Split('|');
|
VipRule vipRule = new VipRule();
|
vipRule.Vip = vipInfoTmp[0];
|
vipRule.Weight = double.Parse(vipInfoTmp[1]);
|
vipRules.Add(vipRule);
|
}
|
envConfig.VipRules = vipRules;
|
envConfigs.Add(envConfig);
|
}
|
|
dnsConfig.EnvDict[envName] = envConfigs;
|
}
|
}
|
else if ("api".Equals(configType))
|
{
|
dnsConfig.ApiDict = new Dictionary<string, ApiConfig>();
|
IDictionary apiInfos = root[configType] as IDictionary;
|
foreach (string apiName in apiInfos.Keys)
|
{
|
IDictionary apiInfo = apiInfos[apiName] as IDictionary;
|
ApiConfig apiConfig = new ApiConfig();
|
apiConfig.User = apiInfo["user"] as string;
|
List<ApiRule> apiRules = new List<ApiRule>();
|
IList apiRuleInfos = apiInfo["rule"] as IList;
|
foreach (string apiRuleInfo in apiRuleInfos)
|
{
|
string[] apiRuleInfoTmp = apiRuleInfo.ToString().Split('|');
|
ApiRule apiRule = new ApiRule();
|
apiRule.Name = apiRuleInfoTmp[0];
|
apiRule.Weight = double.Parse(apiRuleInfoTmp[1]);
|
apiRules.Add(apiRule);
|
}
|
apiConfig.Rules = apiRules;
|
dnsConfig.ApiDict[apiName] = apiConfig;
|
}
|
}
|
else if ("user".Equals(configType))
|
{
|
dnsConfig.UserDict = new Dictionary<string, IDictionary<string, string>>();
|
IDictionary userInfos = root[configType] as IDictionary;
|
foreach (string routeName in userInfos.Keys)
|
{
|
IDictionary envInfos = userInfos[routeName] as IDictionary;
|
IDictionary<string, string> tags = new Dictionary<string, string>();
|
foreach (string envName in envInfos.Keys)
|
{
|
IList tagInfos = envInfos[envName] as IList;
|
foreach (string tagName in tagInfos)
|
{
|
tags.Add(tagName, envName);
|
}
|
}
|
dnsConfig.UserDict[routeName] = tags;
|
}
|
}
|
}
|
return dnsConfig;
|
}
|
|
public string GetBestVipUrl(string serverUrl, string apiName, string session)
|
{
|
if (ApiDict.ContainsKey(apiName))
|
{
|
ApiConfig apiConfig = ApiDict[apiName];
|
if (!string.IsNullOrEmpty(session) && apiConfig.User != null)
|
{
|
string flag = GetUserFlag(session);
|
if (flag != null && UserDict.ContainsKey(apiConfig.User))
|
{
|
IDictionary<string, string> userEnvs = UserDict[apiConfig.User];
|
if (userEnvs.ContainsKey(flag))
|
{
|
string userEnv = userEnvs[flag];
|
if (EnvDict.ContainsKey(userEnv))
|
{
|
List<EnvConfig> envConfigs = EnvDict[userEnv];
|
return GetEnvVipUrl(serverUrl, envConfigs);
|
}
|
}
|
}
|
}
|
return GetApiVipUrl(serverUrl, apiConfig);
|
}
|
else
|
{
|
List<EnvConfig> envConfigs = EnvDict[GlobalDict["def_env"]];
|
return GetEnvVipUrl(serverUrl, envConfigs);
|
}
|
}
|
|
private string GetApiVipUrl(string serverUrl, ApiConfig apiConfig)
|
{
|
ApiRule apiRule = ClusterManager.GetElementByWeight(apiConfig.Rules);
|
if (EnvDict.ContainsKey(apiRule.Name))
|
{
|
List<EnvConfig> envConfigs = EnvDict[apiRule.Name];
|
return GetEnvVipUrl(serverUrl, envConfigs);
|
}
|
else
|
{
|
List<EnvConfig> envConfigs = EnvDict[GlobalDict["def_env"]];
|
return GetEnvVipUrl(serverUrl, envConfigs);
|
}
|
}
|
|
private string GetEnvVipUrl(string serverUrl, List<EnvConfig> envConfigs)
|
{
|
foreach (EnvConfig envConfig in envConfigs)
|
{
|
Uri uri = new Uri(serverUrl);
|
if (uri.Host.Equals(envConfig.Domain, StringComparison.OrdinalIgnoreCase) && uri.Scheme.Equals(envConfig.Protocol, StringComparison.OrdinalIgnoreCase))
|
{
|
string vip = ClusterManager.GetElementByWeight<VipRule>(envConfig.VipRules).Vip;
|
return serverUrl.Replace(envConfig.Domain, vip);
|
}
|
}
|
return serverUrl;
|
}
|
|
private string GetUserFlag(string session)
|
{
|
if (!string.IsNullOrEmpty(session) && session.Length > 5)
|
{
|
if (session.StartsWith("6") || session.StartsWith("7"))
|
{
|
return session.Substring(session.Length - 1, 1);
|
}
|
else if (session.StartsWith("5") || session.StartsWith("8"))
|
{
|
return session.Substring(5, 1);
|
}
|
}
|
return null;
|
}
|
|
public long GetVersion()
|
{
|
if (GlobalDict.ContainsKey("GlobalDict"))
|
{
|
return long.Parse(GlobalDict["GlobalDict"]);
|
}
|
else
|
{
|
return 0;
|
}
|
}
|
|
public int GetRefreshInterval()
|
{
|
if (GlobalDict.ContainsKey("interval"))
|
{
|
return int.Parse(GlobalDict["interval"]);
|
}
|
else
|
{
|
return 30; // 默认半小时刷新一次
|
}
|
}
|
|
}
|
|
public class HttpdnsGetResponse : TopResponse
|
{
|
[XmlElement("result")]
|
public string Result { get; set; }
|
}
|
|
public class HttpdnsGetRequest : BaseTopRequest<HttpdnsGetResponse>
|
{
|
public override string GetApiName()
|
{
|
return "taobao.httpdns.get";
|
}
|
|
public override IDictionary<string, string> GetParameters()
|
{
|
TopDictionary parameters = new TopDictionary();
|
return parameters;
|
}
|
|
public override void Validate()
|
{
|
}
|
}
|
}
|