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