PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/Resources/Companion/AdminRole/WebRole.cs

https://bitbucket.org/zgramana/azure-accelerators-project
C# | 298 lines | 229 code | 36 blank | 33 comment | 12 complexity | 8ded07d53d8d24a9e9061285129c8db8 MD5 | raw file
Possible License(s): LGPL-2.0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.WindowsAzure;
  5. using Microsoft.WindowsAzure.Accelerator;
  6. using Microsoft.WindowsAzure.Diagnostics;
  7. using Microsoft.WindowsAzure.ServiceRuntime;
  8. using WindowsAzureCompanion.VMManagerService;
  9. using System.ServiceModel;
  10. using System.Diagnostics;
  11. using Microsoft.WindowsAzure.StorageClient;
  12. using System.Threading;
  13. using System.ServiceModel.Security;
  14. using System.ServiceModel.Description;
  15. using System.Collections.Specialized;
  16. using System.IO;
  17. using System.Text;
  18. using System.Runtime.Serialization.Formatters.Soap;
  19. using System.Security.Cryptography.X509Certificates;
  20. using System.Net;
  21. using System.Net.Security;
  22. namespace Microsoft.WindowsAzure.Companion
  23. {
  24. public class WebRole : RoleEntryPoint
  25. {
  26. private DiagnosticMonitor diagnosticMonitor = null;
  27. private CloudStorageAccount storageAccount = null;
  28. private ServiceHost wcfVMManagerServiceHost = null;
  29. private IVMManager vmManager = null;
  30. public override bool OnStart()
  31. {
  32. // Create HTTPS storage endpoint
  33. storageAccount = WindowsAzureVMManager.GetStorageAccount(true);
  34. // Start Windows Azure Diagnostics
  35. StartDiagnosticMonitor();
  36. //i|
  37. //i| Start applications gracefully.
  38. //i|
  39. ServiceManager.Start();
  40. try
  41. {
  42. // Start VM Manager WCF service
  43. vmManager = StartVMManagerService();
  44. // Wait for 10 sec
  45. Thread.Sleep(10000);
  46. // Mount XDrive
  47. if (vmManager.MountXDrive())
  48. {
  49. // Setup Runtime Servers
  50. SetupRuntimeServers();
  51. }
  52. else
  53. {
  54. Trace.TraceError("Could not start the service as Windows Azure Drive was not monuted.");
  55. }
  56. }
  57. catch (Exception ex)
  58. {
  59. Trace.TraceError(ex.Message);
  60. Trace.TraceError(ex.StackTrace);
  61. }
  62. RoleEnvironment.Changing += RoleEnvironmentChanging;
  63. return base.OnStart();
  64. }
  65. // Start Windows Azure Diagnostics Monitor
  66. private void StartDiagnosticMonitor()
  67. {
  68. // Enable Diagnostics trace listener (needed for WCF service)
  69. Trace.Listeners.Add(new DiagnosticMonitorTraceListener());
  70. // Get Diagnostics and Performance Counter Capture Frequency (in minutes)
  71. TimeSpan timeSpan = TimeSpan.FromMinutes(
  72. Double.Parse(RoleEnvironment.GetConfigurationSettingValue("DiagnosticsAndPerformanceCounterCaptureFrequencyInMinutes")));
  73. var cfg = DiagnosticMonitor.GetDefaultInitialConfiguration();
  74. cfg.Logs.ScheduledTransferPeriod = timeSpan;
  75. cfg.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
  76. // Infrastructure logs
  77. cfg.DiagnosticInfrastructureLogs.ScheduledTransferPeriod = timeSpan;
  78. cfg.DiagnosticInfrastructureLogs.ScheduledTransferLogLevelFilter = LogLevel.Error;
  79. cfg.DiagnosticInfrastructureLogs.BufferQuotaInMB = 10;
  80. // Add event collection from the Windows Event Log
  81. cfg.WindowsEventLog.DataSources.Add("System!*");
  82. cfg.WindowsEventLog.ScheduledTransferPeriod = timeSpan;
  83. cfg.WindowsEventLog.DataSources.Add("Application!*[System[Provider[@Name='HostableWebCore']]]");
  84. // Add performance counter monitoring
  85. cfg.PerformanceCounters.DataSources.Add(
  86. new PerformanceCounterConfiguration()
  87. {
  88. CounterSpecifier = @"\Processor(_Total)\% Processor Time",
  89. SampleRate = timeSpan
  90. });
  91. cfg.PerformanceCounters.DataSources.Add(
  92. new PerformanceCounterConfiguration()
  93. {
  94. CounterSpecifier = @"\Memory\Available Mbytes",
  95. SampleRate = timeSpan
  96. });
  97. cfg.PerformanceCounters.ScheduledTransferPeriod = timeSpan;
  98. // Start Diagnostics
  99. //diagnosticMonitor = DiagnosticMonitor.Start(storageAccount, cfg);
  100. }
  101. // Start WCF Service to manage VM
  102. private IVMManager StartVMManagerService()
  103. {
  104. try
  105. {
  106. // If available, get SSL certificate from service configuration
  107. string sslCertificateSHA1Thumbprint = null;
  108. try
  109. {
  110. sslCertificateSHA1Thumbprint = RoleEnvironment.GetConfigurationSettingValue("SSLCertificateSHA1Thumbprint");
  111. }
  112. catch (Exception)
  113. {
  114. // Ignore, it means SSLCertificateSHA1Thumbprint is not defined
  115. }
  116. // Get VMManager WCF service binding
  117. BasicHttpBinding binding = WindowsAzureVMManager.GetVMManagerServiceBinding(sslCertificateSHA1Thumbprint);
  118. wcfVMManagerServiceHost = new ServiceHost(typeof(WindowsAzureVMManager));
  119. wcfVMManagerServiceHost.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
  120. wcfVMManagerServiceHost.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new WindowsAzureVMManagerUsernamePasswordValidator();
  121. UseRequestHeadersForMetadataAddressBehavior requestHeaderBehavior = new UseRequestHeadersForMetadataAddressBehavior();
  122. IPEndPoint ep = WindowsAzureVMManager.GetVMManagerServiceEndpoint(sslCertificateSHA1Thumbprint);
  123. if (string.IsNullOrEmpty(sslCertificateSHA1Thumbprint))
  124. {
  125. requestHeaderBehavior.DefaultPortsByScheme.Add("http", int.Parse(ep.Port.ToString()));
  126. }
  127. else
  128. {
  129. requestHeaderBehavior.DefaultPortsByScheme.Add("https", int.Parse(ep.Port.ToString()));
  130. wcfVMManagerServiceHost.Credentials.ServiceCertificate.SetCertificate(
  131. StoreLocation.LocalMachine,
  132. StoreName.My,
  133. X509FindType.FindByThumbprint,
  134. RoleEnvironment.GetConfigurationSettingValue("SSLCertificateSHA1Thumbprint")
  135. );
  136. }
  137. wcfVMManagerServiceHost.Description.Behaviors.Add(requestHeaderBehavior);
  138. // Enable WCF service debugging
  139. ServiceDebugBehavior sdb = wcfVMManagerServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>();
  140. if (sdb == null)
  141. {
  142. sdb = new ServiceDebugBehavior();
  143. wcfVMManagerServiceHost.Description.Behaviors.Add(sdb);
  144. }
  145. sdb.IncludeExceptionDetailInFaults = true;
  146. string endpoint = WindowsAzureVMManager.GetVMManagerServiceEndpointAddress(sslCertificateSHA1Thumbprint);
  147. wcfVMManagerServiceHost.AddServiceEndpoint(typeof(IVMManager), binding, endpoint);
  148. ServiceMetadataBehavior metadataBehavior = new ServiceMetadataBehavior();
  149. if (string.IsNullOrEmpty(sslCertificateSHA1Thumbprint))
  150. {
  151. metadataBehavior.HttpGetEnabled = true;
  152. metadataBehavior.HttpGetUrl = new Uri(endpoint);
  153. }
  154. else
  155. {
  156. metadataBehavior.HttpsGetEnabled = true;
  157. metadataBehavior.HttpsGetUrl = new Uri(endpoint);
  158. }
  159. wcfVMManagerServiceHost.Description.Behaviors.Add(metadataBehavior);
  160. wcfVMManagerServiceHost.Open();
  161. Trace.TraceInformation("External WCF Service started on endpoint: {0}", endpoint);
  162. }
  163. catch (Exception ex)
  164. {
  165. Trace.TraceError(ex.Message);
  166. Trace.TraceError(ex.StackTrace);
  167. }
  168. // Return service instance
  169. return WindowsAzureVMManager.GetVMManager();
  170. }
  171. // Setup Runtime Servers
  172. private void SetupRuntimeServers()
  173. {
  174. string containerName = RoleEnvironment.GetConfigurationSettingValue("PHPApplicationsBackupContainerName");
  175. string blobName = RoleEnvironment.GetConfigurationSettingValue("InstallationStatusConfigFileBlob");
  176. // Create blob container
  177. CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
  178. CloudBlobContainer container = blobClient.GetContainerReference(containerName);
  179. if (container.CreateIfNotExist())
  180. {
  181. BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
  182. containerPermissions.PublicAccess = BlobContainerPublicAccessType.Container;
  183. container.SetPermissions(containerPermissions);
  184. }
  185. CloudBlob blob = container.GetBlobReference(blobName);
  186. if (!BlobExists(blob))
  187. {
  188. // Serialize empty NameValueCollection to blob
  189. NameValueCollection values = new NameValueCollection();
  190. SoapFormatter ser = new SoapFormatter();
  191. using (MemoryStream memoryStream = new MemoryStream())
  192. {
  193. ser.Serialize(memoryStream, values);
  194. byte[] b = memoryStream.GetBuffer();
  195. string serilizedNameValueCollection = Encoding.Default.GetString(b);
  196. blob.UploadText(serilizedNameValueCollection);
  197. }
  198. }
  199. else
  200. {
  201. // Setup Runtime Servers
  202. vmManager.SetupRuntimeServers();
  203. }
  204. }
  205. // Check if blob exists
  206. private static bool BlobExists(CloudBlob blob)
  207. {
  208. try
  209. {
  210. blob.FetchAttributes();
  211. return true;
  212. }
  213. catch (StorageClientException e)
  214. {
  215. if (e.ErrorCode == StorageErrorCode.ResourceNotFound)
  216. {
  217. return false;
  218. }
  219. else
  220. {
  221. throw;
  222. }
  223. }
  224. }
  225. public override void OnStop()
  226. {
  227. try
  228. {
  229. // Stop all cron jobs
  230. vmManager.StopAllCronJobs();
  231. // Stop all Runtimes
  232. vmManager.StopPHPWebSite();
  233. vmManager.StopMySQLServer();
  234. // Unmount all windows azure drives
  235. vmManager.UnmountXDrive();
  236. }
  237. catch (Exception ex)
  238. {
  239. Trace.TraceError("Error in OnStop: {0}", ex.Message);
  240. }
  241. if (wcfVMManagerServiceHost != null)
  242. {
  243. wcfVMManagerServiceHost.Close();
  244. }
  245. ServiceManager.Stop();
  246. diagnosticMonitor.Shutdown();
  247. base.OnStop();
  248. }
  249. private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e)
  250. {
  251. // If a user configuration setting is changing
  252. if ((from change in e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
  253. where !(change.ConfigurationSettingName.StartsWith("Microsoft.WindowsAzure.Plugins.RemoteAccess.") ||
  254. change.ConfigurationSettingName.StartsWith("Microsoft.WindowsAzure.Plugins.RemoteForwarder."))
  255. select change).Any())
  256. {
  257. // Set e.Cancel to true to restart this role instance
  258. e.Cancel = true;
  259. }
  260. }
  261. }
  262. }