Read Configuration Settings for the Storage Client Library and Handle Changed Settings
Updated: May 11, 2011
If you have a hosted service that uses the Windows Azure Storage Client library to access your Windows Azure Storage account it is recommended that you store your connection string in the service configuration file. Storing the connection string in the service configuration file allows a deployed service to respond to changes in the configuration without redeploying the application. Examples of when this is beneficial are:
-
Testing – If you use a test account while you have your application deployed to the staging environment and must switch it over to the live account when your move the application to the production environment.
-
Security – If you must rotate the keys for your storage account due to the key in use being compromised.
For more information on configuring the connection string, see Configuring Connection Strings.
There are two patterns that can be implemented to handle configuration change:
-
If the application can tolerate being restarted without affecting the service, you can detect the change and reject it, thus causing the role instance to recycle after any endpoints are taken out of the load balancer rotation. Typically, web sites fall into this category. This is simplest and easiest way to handle the change.
-
If your application is long running or otherwise unable to gracefully handle being restarted when a change occurs, you can update the configuration of your hosted service while it is running without taking the role instance offline by performing a hot update of the configuration.
The Windows Azure Managed Library includes the Microsoft.WindowsAzure.ServiceRuntime namespace, which provides classes for interacting with the Windows Azure environment from code running in an instance of a role. The RoleEnvironment class defines the Changing and Changed events that are raised before and after a configuration change. You can handle these events and respond to the change.
-
Open the source file that contains the entry point class for the role, for example WebRole.cs.
-
Ensure that the project references the Microsoft.WindowsAzure.ServiceRuntime.dll file and that the following using statement is added to the file:
using Microsoft.WindowsAzure.ServiceRuntime; -
Add the following code to the OnStart method of the role entrypoint point class to specify the event handler:
public override bool OnStart() { RoleEnvironment.Changing += (object ignored, RoleEnvironmentChangingEventArgs e) => { var settingChanges = e.Changes.OfType<RoleEnvironmentConfigurationSettingChange>(); foreach (var settingChange in settingChanges) { // Recycle the role when MyStorageConnectionString setting changes. // You must replace "MyStorageConnectionString" with the name of your storage // connection string as configured in your .csdef file. // If you have additional configuration settings that you want to reject // you should configure them here. if (settingChange.ConfigurationSettingName.Equals ("MyStorageConnectionString", StringComparison.InvariantCultureIgnoreCase)) { e.Cancel = true; } } }; return base.OnStart(); }
-
Save the file.
Before you can detect configuration changes for a hot update, you must specify where to retrieve the configuration information from. Rather than defaulting to a specific configuration file, the CloudStorageAccount requires you set a delegate using configSetter to retrieve correct configuration file.
-
Open the source file that contains the entry point class for the role, for example WebRole.cs.
-
Ensure that the project references the Microsoft.WindowsAzure.ServiceRuntime.dll file and that the following using statement is added to the file:
using Microsoft.WindowsAzure.ServiceRuntime; -
If you are using a full IIS web role or a worker role, add the following code to the OnStart method to specify the event handler:
public class WebRole : RoleEntryPoint { public override bool OnStart() { #region Setup CloudStorageAccount Configuration Setting Publisher // This code sets up a handler to update CloudStorageAccount instances when the // corresponding configuration settings change in the service configuration file. CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => { // Provide the configSetter with the initial value. configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)); RoleEnvironment.Changed += (ignored, arg) => { if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>() .Any((change) => (change.ConfigurationSettingName == configName))) { // The corresponding configuration setting has changed, propagate the value. if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))) { // In this case, the change to the storage account credentials in the // service configuration is significant enough that the role needs to be // recycled in order to use the latest settings. (for example, the // endpoint has changed) RoleEnvironment.RequestRecycle(); } } }; }); #endregion return base.OnStart(); } }
-
If you are using a full IIS web role, add the following event handler method to the Global.asax source file:
void Application_Start(object sender, EventArgs e) { // Code that runs on application startup #region Setup CloudStorageAccount Configuration Setting Publisher // This code sets up a handler to update CloudStorageAccount instances when their // corresponding configuration settings change in the service configuration file. CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => { // Provide the configSetter with the initial value configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)); RoleEnvironment.Changed += (ignored, arg) => { if (arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>() .Any((change) => (change.ConfigurationSettingName == configName))) { // The corresponding configuration setting has changed, propagate the value. if (!configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))) { // In this case, the change to the storage account credentials in the // service configuration is significant enough that the role needs to be // recycled in order to use the latest settings. (for example, the // endpoint has changed) RoleEnvironment.RequestRecycle(); } } }; }); #endregion }
-
Save the file.
See Also