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 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 VipRules { get; set; } } public class DnsConfig { public IDictionary GlobalDict { get; set; } public IDictionary ApiDict { get; set; } public IDictionary> EnvDict { get; set; } public IDictionary> 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(); 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>(); foreach (string envName in envInfos.Keys) { IDictionary envInfo = envInfos[envName] as IDictionary; List envConfigs = new List(); 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 vipRules = new List(); 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(); 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 apiRules = new List(); 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>(); IDictionary userInfos = root[configType] as IDictionary; foreach (string routeName in userInfos.Keys) { IDictionary envInfos = userInfos[routeName] as IDictionary; IDictionary tags = new Dictionary(); 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 userEnvs = UserDict[apiConfig.User]; if (userEnvs.ContainsKey(flag)) { string userEnv = userEnvs[flag]; if (EnvDict.ContainsKey(userEnv)) { List envConfigs = EnvDict[userEnv]; return GetEnvVipUrl(serverUrl, envConfigs); } } } } return GetApiVipUrl(serverUrl, apiConfig); } else { List 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 envConfigs = EnvDict[apiRule.Name]; return GetEnvVipUrl(serverUrl, envConfigs); } else { List envConfigs = EnvDict[GlobalDict["def_env"]]; return GetEnvVipUrl(serverUrl, envConfigs); } } private string GetEnvVipUrl(string serverUrl, List 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(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 { public override string GetApiName() { return "taobao.httpdns.get"; } public override IDictionary GetParameters() { TopDictionary parameters = new TopDictionary(); return parameters; } public override void Validate() { } } }