2 using System.Collections.Generic;
6 using System.Text.RegularExpressions;
7 using System.Threading.Tasks;
11 namespace FUSE.AzureConfig.Tasks
17 if (
string.IsNullOrEmpty(configDir) || !Directory.Exists(configDir))
18 throw new ArgumentException(configDir +
" does not exist");
19 var csdef = Path.Combine(configDir, FileGenerator.CsdefName);
20 if (!File.Exists(csdef))
21 throw new ArgumentException(csdef +
" does not exist");
23 var settingsByRole = ProcessCsdef(csdef);
24 var envs = ProcessCscfgs(configDir);
25 return MergeEnvs(envs, settingsByRole);
28 private IDictionary<string, ISet<string>> ProcessCsdef(
string csdef)
30 var settingsByRole =
new Dictionary<string, ISet<string>>();
31 var doc = XDocument.Load(csdef);
32 var rootNS = FileGenerator.GetRootNamespace(doc);
33 var roles = from e in doc.Descendants()
34 where e.Name == rootNS +
"WebRole" || e.Name == rootNS +
"WorkerRole"
36 foreach (var roleElt in roles)
38 var roleName = roleElt.Attribute(
"name").Value;
39 var curSettings =
new HashSet<string>();
40 settingsByRole[roleName] = curSettings;
41 var settingElts = roleElt.Element(rootNS +
"ConfigurationSettings").Elements(rootNS +
"Setting");
42 foreach (var setting
in settingElts)
44 var settingName = setting.Attribute(
"name").Value;
45 curSettings.Add(settingName);
48 return settingsByRole;
51 private static readonly Regex _CscfgNamePat =
new Regex(
@"ServiceConfiguration\.(?<env>[^.]+)\.cscfg");
57 this.InstancesByRole =
new Dictionary<string, int>();
58 this.SettingsByRole =
new Dictionary<string, Dictionary<string, string>>();
61 public string Name {
get; set; }
63 public Dictionary<string, int> InstancesByRole {
get; set; }
65 public Dictionary<string, Dictionary<string, string>> SettingsByRole {
get; set; }
68 private List<EnvData> ProcessCscfgs(
string cscfgsDir)
70 var envs =
new List<EnvData>();
71 var files = Directory.GetFiles(cscfgsDir,
"*.cscfg");
72 foreach (var file
in files)
74 var envName = _CscfgNamePat.Match(file).Groups[
"env"].Value;
75 envName = string.IsNullOrEmpty(envName) ? FileGenerator.DefaultEnvName : envName;
76 var env =
new EnvData() { Name = envName };
78 var doc = XDocument.Load(file);
79 var rootNS = FileGenerator.GetRootNamespace(doc);
80 var roles = from e in doc.Descendants()
81 where e.Name == rootNS +
"Role"
83 foreach (var roleElt in roles)
85 var roleName = roleElt.Attribute(
"name").Value;
86 env.SettingsByRole[roleName] =
new Dictionary<string, string>();
87 env.InstancesByRole[roleName] = int.Parse(roleElt.Element(rootNS +
"Instances").Attribute(
"count").Value);
88 var settingElts = roleElt.Element(rootNS +
"ConfigurationSettings").Elements(rootNS +
"Setting");
89 foreach (var setting
in settingElts)
91 var settingName = setting.Attribute(
"name").Value;
92 var settingVal = setting.Attribute(
"value").Value;
93 env.SettingsByRole[roleName][settingName] = settingVal;
100 private AzureConfigSpec MergeEnvs(List<EnvData> envs, IDictionary<
string, ISet<string>> settingsByRole)
102 var spec =
new AzureConfigSpec();
103 var parent = string.Empty;
104 Dictionary<string, Dictionary<string, string>> prev = null;
105 foreach (var env
in envs.OrderBy(x => x.Name))
107 var envSpec =
new EnvironmentSpec() { ProfileName = env.Name };
108 spec.Environments[env.Name] = envSpec;
109 foreach (var role
in env.InstancesByRole)
111 envSpec.Roles[role.Key] =
new RoleSpec() { Instances = role.Value };
113 envSpec.Parent = parent;
115 foreach (var role
in env.SettingsByRole)
117 var settings =
new Dictionary<string, string>();
118 envSpec.ConfigSettings[role.Key] = settings;
119 foreach (var setting
in role.Value)
121 if (prev == null || !prev.ContainsKey(role.Key)
122 || !prev[role.Key].ContainsKey(setting.Key) || prev[role.Key][setting.Key] != setting.Value)
123 settings[setting.Key] = setting.Value;
128 prev = env.SettingsByRole;
JSON-based azure configuration specification.