PageRenderTime 70ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/Accelerator/Configuration/Settings.cs

https://bitbucket.org/zgramana/azure-accelerators-project
C# | 322 lines | 193 code | 30 blank | 99 comment | 13 complexity | 5cf1bb43b4cda55e90f2608fb3813ac1 MD5 | raw file
Possible License(s): LGPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Xml.Linq;
  7. using Microsoft.WindowsAzure.Accelerator.Configuration.Definition;
  8. using Microsoft.WindowsAzure.Accelerator.Diagnostics;
  9. using Environment = System.Environment;
  10. namespace Microsoft.WindowsAzure.Accelerator.Configuration
  11. {
  12. /// <summary>
  13. /// Manages settings from the Azure service definition (.csdef), service configuration (.cscfg),
  14. /// and service accelerator configuration (.accfg) files. (i|rdm)
  15. /// </summary>
  16. public class Settings
  17. {
  18. private const String _DefaultServiceConfigurationFile = "ServiceConfiguration.cscfg";
  19. private const String _DefaultServiceDefinitionFile = "ServiceDefinition.csdef";
  20. private const String _DefaultServiceAcceleratorFile = "ServiceAccelerator.accfg";
  21. private readonly XNamespace _cns = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration";
  22. private readonly XNamespace _dns = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition";
  23. private readonly XNamespace _ans = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceAcceleratorConfiguration";
  24. private ServiceBusConnection _serviceBusConnection;
  25. private CloudStorageAccount _cloudStorageAccount;
  26. private Path _serviceDefinitionFile;
  27. private Path _serviceConfigurationFile;
  28. private Path _serviceAcceleratorFile;
  29. private XElement _xServiceDefinition;
  30. private XElement _xServiceConfiguration;
  31. private XElement _xServiceAccelerator;
  32. private Dictionary<String, String> _configSettings;
  33. private ServiceDefinition _serviceDefinition;
  34. private ServiceConfiguration _serviceConfiguration;
  35. private ServiceAccelerator _serviceAccelerator;
  36. /// <summary>
  37. /// Initializes a new instance of the <see cref="Settings"/> class.
  38. /// </summary>
  39. public Settings() : this(_DefaultServiceDefinitionFile, _DefaultServiceConfigurationFile, _DefaultServiceAcceleratorFile) { }
  40. /// <summary>
  41. /// Initializes a new instance of the <see cref="Settings"/> class.
  42. /// </summary>
  43. /// <param name="serviceDefinitionFile">The service definition file.</param>
  44. /// <param name="serviceConfigurationFile">The service configuration file.</param>
  45. /// <param name="serviceAcceleratorFile">The service accelerator configuration file.</param>
  46. public Settings(Path serviceDefinitionFile, Path serviceConfigurationFile, Path serviceAcceleratorFile)
  47. {
  48. ServiceDefinitionFile = serviceDefinitionFile;
  49. ServiceConfigurationFile = serviceConfigurationFile;
  50. ServiceAcceleratorFile = serviceAcceleratorFile;
  51. }
  52. /// <summary>
  53. /// Gets a value indicating whether this instance is hostable web core.
  54. /// </summary>
  55. public Boolean IsHostableWebCore
  56. {
  57. get { return false; } //XServiceDefinition.Descendants("Site").FirstOrDefault() == null; }
  58. }
  59. /// <summary>
  60. /// Gets the diagnostics service bus connection.
  61. /// </summary>
  62. public ServiceBusConnection ServiceBusConnection
  63. {
  64. get { return _serviceBusConnection ?? ( _serviceBusConnection = ServiceBusConnection.Parse(GetConfigurationSetting("DiagnosticsServiceBus"))); }
  65. }
  66. /// <summary>
  67. /// Gets the default cloud drive URI.
  68. /// </summary>
  69. public String DefaultCloudDriveUri
  70. {
  71. get { return GetConfigurationSetting("AcceleratorDrivePageBlobUri") ?? DefaultSettings.CloudDriveUri; }
  72. }
  73. /// <summary>
  74. /// Gets the default local site path.
  75. /// </summary>
  76. /// <remarks>
  77. /// Matained for HWC backwards compatiblity only. Is not useful for a SDK 1.3 sites based configuration,
  78. /// which includes a native physicalDirectory attribute.
  79. /// </remarks>
  80. public String DefaultLocalSitePath
  81. {
  82. get { return GetConfigurationSetting("LocalSitePath"); }
  83. }
  84. /// <summary>
  85. /// Gets the name of the application.
  86. /// </summary>
  87. public String ApplicationName
  88. {
  89. get { return ServiceConfiguration.serviceName; }
  90. }
  91. /// <summary>
  92. /// Gets the cloud storage account.
  93. /// </summary>
  94. public CloudStorageAccount CloudStorageAccount
  95. {
  96. get { return _cloudStorageAccount ?? ( _cloudStorageAccount = CloudStorageAccount.Parse(GetConfigurationSetting("AcceleratorConnectionString"))); }
  97. }
  98. /// <summary>
  99. /// Gets the service definition class information from the .csdef file.
  100. /// </summary>
  101. public ServiceDefinition ServiceDefinition
  102. {
  103. get { return _serviceDefinition ?? (_serviceDefinition = ServiceDefinition.LoadFromFile(ServiceDefinitionFile)); }
  104. }
  105. /// <summary>
  106. /// Gets the service configuration class from the cscfg file.
  107. /// </summary>
  108. public ServiceConfiguration ServiceConfiguration
  109. {
  110. get { return _serviceConfiguration ?? (_serviceConfiguration = ServiceConfiguration.LoadFromFile(ServiceConfigurationFile)); }
  111. }
  112. /// <summary>
  113. /// Gets the service accelerator configuration class from the accfg file.
  114. /// </summary>
  115. public ServiceAccelerator ServiceAccelerator
  116. {
  117. get { return _serviceAccelerator ?? (_serviceAccelerator = ServiceAccelerator.LoadFromFile(ServiceAcceleratorFile)); }
  118. }
  119. #region | XML
  120. /// <summary>
  121. /// Gets all 'Site' service definition elements defined in all roles.
  122. /// </summary>
  123. public List<XElement> XSites
  124. {
  125. get { return XServiceDefinition.Descendants(_dns + "Site").ToList(); }
  126. }
  127. /// <summary>
  128. /// Gets the service configuration setting elements.
  129. /// </summary>
  130. public Dictionary<String, String> ConfigurationSettings
  131. {
  132. get { return _configSettings ?? (_configSettings = GetRoleSettings(String.Empty)); }
  133. // XServiceConfiguration.Descendants(_cns + "Setting").ToDictionary(e => (String)e.Attribute("name"), e => (String)e.Attribute("value"))); }
  134. }
  135. /// <summary>
  136. /// Gets the service definition XML from the csdef file.
  137. /// </summary>
  138. public XElement XServiceDefinition
  139. {
  140. get { return _xServiceDefinition ?? (_xServiceDefinition = XDocument.Load(ServiceDefinitionFile).Element(_dns + "ServiceDefinition")); }
  141. }
  142. /// <summary>
  143. /// Gets the service configuration XML from the cscfg file.
  144. /// </summary>
  145. public XElement XServiceConfiguration
  146. {
  147. get { return _xServiceConfiguration ?? (_xServiceConfiguration = XDocument.Load(ServiceConfigurationFile).Element(_cns + "ServiceConfiguration")); }
  148. }
  149. /// <summary>
  150. /// Gets the service configuration XML from the cscfg file.
  151. /// </summary>
  152. public XElement XServiceAccelerator
  153. {
  154. get { return _xServiceAccelerator ?? (_xServiceAccelerator = XDocument.Load(ServiceAcceleratorFile).Element(_ans + "ServiceAccelerator")); }
  155. }
  156. #endregion
  157. #region | FILE RESOURCES
  158. /// <summary>
  159. /// Gets or sets the service definition (.csdef) file.
  160. /// </summary>
  161. public Path ServiceDefinitionFile
  162. {
  163. get { return _serviceDefinitionFile ?? (_serviceDefinitionFile = LocateConfigurationFile(_DefaultServiceDefinitionFile)); }
  164. set
  165. {
  166. if (!String.IsNullOrEmpty(value) && File.Exists(value))
  167. {
  168. _serviceDefinitionFile = value;
  169. _serviceDefinition = null;
  170. _xServiceDefinition = null;
  171. }
  172. }
  173. }
  174. /// <summary>
  175. /// Gets or sets the service configuration (.cscfg) file.
  176. /// </summary>
  177. public Path ServiceConfigurationFile
  178. {
  179. get { return _serviceConfigurationFile ?? (_serviceConfigurationFile = LocateConfigurationFile(_DefaultServiceConfigurationFile)); }
  180. set
  181. {
  182. if (!String.IsNullOrEmpty(value) && File.Exists(value))
  183. {
  184. _serviceConfigurationFile = value;
  185. _serviceConfiguration = null;
  186. _serviceConfigurationFile = null;
  187. }
  188. }
  189. }
  190. /// <summary>
  191. /// Gets or sets the service accelerator configuration (.accfg) file.
  192. /// </summary>
  193. public Path ServiceAcceleratorFile
  194. {
  195. get { return _serviceAcceleratorFile?? (_serviceAcceleratorFile= LocateConfigurationFile(_DefaultServiceAcceleratorFile)); }
  196. set
  197. {
  198. if (!String.IsNullOrEmpty(value) && File.Exists(value))
  199. {
  200. _serviceAcceleratorFile= value;
  201. _xServiceAccelerator = null;
  202. }
  203. }
  204. }
  205. /// <summary>
  206. /// Locates a configuration file using a known filename. This method will attempt to locate the file
  207. /// in the following four locations:
  208. /// 1. current directory
  209. /// 2. parent of current directory
  210. /// 3. binary directory
  211. /// 4. parent of binary directory
  212. /// </summary>
  213. /// <param name="filename">The file name.</param>
  214. private static Path LocateConfigurationFile(String filename)
  215. {
  216. Path path;
  217. if (!File.Exists(path = Path.Combine(".", filename).GetFullPath()))
  218. if (!File.Exists(path = path.Protect(p => p.GetParentFolder().Combine(filename))))
  219. if (!File.Exists(path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filename)))
  220. if (!File.Exists(path = path.Protect(p => p.GetParentFolder().Combine(filename))))
  221. path = null;
  222. return path;
  223. }
  224. #endregion
  225. /// <summary>
  226. /// Gets the configuration setting.
  227. /// </summary>
  228. /// <param name="settingName">Name of the setting.</param>
  229. /// <returns></returns>
  230. public String GetConfigurationSetting(String settingName)
  231. {
  232. return GetRoleConfigurationSetting(settingName, String.Empty);
  233. }
  234. /// <summary>
  235. /// Gets the configuration setting.
  236. /// </summary>
  237. /// <param name="settingName">Name of the setting.</param>
  238. /// <param name="roleName">Name of the role.</param>
  239. /// <returns></returns>
  240. public String GetRoleConfigurationSetting(String settingName, String roleName)
  241. {
  242. return GetRoleSettings(roleName).OnValid(rs => rs.ContainsKey(settingName) ? rs[settingName] : null);
  243. }
  244. /// <summary>
  245. /// Gets the configuration setting elements for the specified role.
  246. /// </summary>
  247. /// <param name="roleName">Name of the role.</param>
  248. /// <returns>List of setting elements.</returns>
  249. public Dictionary<String,String> GetRoleSettings(String roleName)
  250. {
  251. XElement scope = (String.IsNullOrEmpty(roleName))
  252. ? XServiceConfiguration
  253. : //i|String query = String.Format("serviceAccelerator/application[@name=\"{0}\"]"
  254. (from r in XServiceConfiguration.Elements()
  255. where r.GetAttribute("value") == roleName
  256. select r).FirstOrDefault();
  257. return scope.Descendants(_cns + "Setting").ToDictionary(e => (String)e.Attribute("name"), e => (String)e.Attribute("value"));
  258. }
  259. /// <summary>
  260. /// Pushes the values of each of the service configuration settings into environment variables by the same name. Used to
  261. /// single-source configuration information, while leveraging batch files for deployment.
  262. /// </summary>
  263. public void SetConfigEnvironment()
  264. {
  265. Trace.TraceInformation("Setting Environment Variables");
  266. foreach (var setting in ConfigurationSettings)
  267. {
  268. try
  269. {
  270. String key = setting.Key;
  271. String value = setting.Value;
  272. Environment.SetEnvironmentVariable(key, value);
  273. Trace.TraceInformation("\t{0:20} : {1}", key, value);
  274. if (!String.IsNullOrEmpty(value) && key.ToLower().Contains("connectionstring"))
  275. {
  276. foreach (var kvp in setting.Value.SplitToDictionary<String, String>(new[] { ';' }, new[] { '=' }).Where(d => !String.IsNullOrEmpty(d.Value)))
  277. {
  278. //b| this needs to take into account role and setting name in a compound form.
  279. Environment.SetEnvironmentVariable(String.Format("{0}_{1}", key, kvp.Key), kvp.Value);
  280. Environment.SetEnvironmentVariable(kvp.Key, kvp.Value);
  281. Trace.TraceInformation("\t{0:20} : {1}", kvp.Key, kvp.Value);
  282. }
  283. }
  284. }
  285. catch (Exception ex)
  286. {
  287. Trace.TraceError(ex.ToString());
  288. }
  289. }
  290. }
  291. }
  292. }