diff --git a/src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config b/src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config
index 4b8b809f6..008324024 100644
--- a/src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config
+++ b/src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config
@@ -7,9 +7,9 @@
-
+
-
+
diff --git a/src/Orchard.Web/Config/Host.config b/src/Orchard.Web/Config/Host.config
index abf7158a9..a4f3ea12d 100644
--- a/src/Orchard.Web/Config/Host.config
+++ b/src/Orchard.Web/Config/Host.config
@@ -6,12 +6,6 @@
-
-
-
-
\ No newline at end of file
diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj b/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj
index a62a42d22..b0f473752 100644
--- a/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj
+++ b/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj
@@ -147,7 +147,6 @@
-
diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureBlobShellSettingsManager.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureBlobShellSettingsManager.cs
index 2110f4fda..774d0ef57 100644
--- a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureBlobShellSettingsManager.cs
+++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureBlobShellSettingsManager.cs
@@ -3,26 +3,40 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.WindowsAzure;
-using Microsoft.WindowsAzure.Storage;
+using Microsoft.WindowsAzure.ServiceRuntime;
using Orchard.Azure.Services.FileSystems;
using Orchard.Environment.Configuration;
using Orchard.FileSystems.Media;
+using Orchard.Logging;
namespace Orchard.Azure.Services.Environment.Configuration {
+ ///
+ /// Provides an IShellSettingsManager implementation that uses Windows Azure Blob Storage as the
+ /// underlying storage system.
+ ///
+ ///
+ /// Additionally, this class handles role configuration change events when running in a Windows Azure Cloud
+ /// Service to ensure all Orchard tenents are notified whenever a role configuration setting is changed
+ /// through the management portal or API.
+ ///
public class AzureBlobShellSettingsManager : Component, IShellSettingsManager {
- protected const string EmptyValueString = "null";
protected readonly IShellSettingsManagerEventHandler Events;
protected readonly AzureFileSystem FileSystem;
public AzureBlobShellSettingsManager(IShellSettingsManagerEventHandler events, IMimeTypeProvider mimeTypeProvider) {
Events = events;
FileSystem = new AzureFileSystem(CloudConfigurationManager.GetSetting(Constants.ShellSettingsStorageConnectionStringSettingName), Constants.ShellSettingsContainerName, String.Empty, true, mimeTypeProvider);
+ if (RoleEnvironment.IsAvailable) {
+ RoleEnvironment.Changing += RoleEnvironment_Changing;
+ RoleEnvironment.Changed += RoleEnvironment_Changed;
+ }
}
public virtual IEnumerable LoadSettings() {
var settings = LoadSettingsInternal().ToArray();
+ PlatformShellSettings.ApplyTo(settings); // Apply platform configuration overrides.
return settings;
}
@@ -40,6 +54,28 @@ namespace Orchard.Azure.Services.Environment.Configuration {
Events.Saved(settings);
}
+ void RoleEnvironment_Changing(object sender, RoleEnvironmentChangingEventArgs e) {
+ // Indicate to the fabric controller that we can handle any changes.
+ e.Cancel = false;
+ }
+
+ private void RoleEnvironment_Changed(object sender, RoleEnvironmentChangedEventArgs e) {
+ Logger.Debug("Handling RoleEnvironmentChanged event.");
+
+ var configurationChangeQuery =
+ from c in e.Changes
+ where c is RoleEnvironmentConfigurationSettingChange
+ select c;
+
+ // If there's a configuration settings change, inform all Orchard tenants.
+ if (configurationChangeQuery.Any()) {
+ Logger.Information("Role configuration settings changed; refreshing Orchard shell settings.");
+ var settingsList = LoadSettings();
+ foreach (var settings in settingsList)
+ Events.Saved(settings);
+ }
+ }
+
private IEnumerable LoadSettingsInternal() {
foreach (var folder in FileSystem.ListFolders(null)) {
foreach (var file in FileSystem.ListFiles(folder.GetPath())) {
diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureConfigShellSettingsManager.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureConfigShellSettingsManager.cs
deleted file mode 100644
index 725bd2a89..000000000
--- a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/AzureConfigShellSettingsManager.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Microsoft.WindowsAzure;
-using Microsoft.WindowsAzure.ServiceRuntime;
-using Microsoft.WindowsAzure.Storage;
-using Orchard.Environment.Configuration;
-using Orchard.FileSystems.Media;
-using Orchard.Logging;
-
-namespace Orchard.Azure.Services.Environment.Configuration {
-
- public class AzureConfigShellSettingsManager : AzureBlobShellSettingsManager {
-
- private const string _prefix = "Orchard";
-
- public AzureConfigShellSettingsManager(IShellSettingsManagerEventHandler events, IMimeTypeProvider mimeTypeProvider)
- : base(events, mimeTypeProvider) {
- if (RoleEnvironment.IsAvailable) {
- RoleEnvironment.Changing += RoleEnvironment_Changing;
- RoleEnvironment.Changed += RoleEnvironment_Changed;
- }
- }
-
- public override IEnumerable LoadSettings() {
- var settingsList = base.LoadSettings();
-
- foreach (var settings in settingsList) {
- foreach (var key in settings.Keys.ToArray()) {
- var cloudConfigurationKey = String.Format("{0}.{1}.{2}", _prefix, settings.Name, key);
- var cloudConfigurationValue = ParseValue(CloudConfigurationManager.GetSetting(cloudConfigurationKey));
- if (cloudConfigurationValue != null)
- settings[key] = cloudConfigurationValue;
- }
- }
-
- return settingsList;
- }
-
- void RoleEnvironment_Changing(object sender, RoleEnvironmentChangingEventArgs e) {
- // Indicate to the fabric controller that we can handle any changes.
- e.Cancel = false;
- }
-
- private void RoleEnvironment_Changed(object sender, RoleEnvironmentChangedEventArgs e) {
- Logger.Debug("Handling RoleEnvironmentChanged event.");
-
- var configurationChangeQuery =
- from c in e.Changes
- where c is RoleEnvironmentConfigurationSettingChange
- select c;
-
- // If there's a configuration settings change, inform all Orchard tenants.
- if (configurationChangeQuery.Any()) {
- Logger.Information("Role configuration settings changed; refreshing Orchard shell settings.");
- var settingsList = LoadSettings();
- foreach (var settings in settingsList)
- Events.Saved(settings);
- }
- }
-
- private string ParseValue(string value) {
- if (value == EmptyValueString || String.IsNullOrWhiteSpace(value))
- return null;
- return value;
- }
- }
-}
diff --git a/src/Orchard/Environment/Configuration/PlatformShellSettings.cs b/src/Orchard/Environment/Configuration/PlatformShellSettings.cs
new file mode 100644
index 000000000..00f4ec345
--- /dev/null
+++ b/src/Orchard/Environment/Configuration/PlatformShellSettings.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.WindowsAzure;
+
+namespace Orchard.Environment.Configuration {
+
+ ///
+ /// Provides logic to override individual shell settings with values read from platform configuration.
+ ///
+ ///
+ /// This class is used by IShellSettingsManager implementations to apply overrides of individual
+ /// shell settings from corresponding values in platform configuration. For each setting found
+ /// in the shell settings, this class looks for a corresponding platform setting named
+ /// Orchard.TenantName.SettingName in platform configuration. Platform configuration refers to
+ /// anywhere the class looks.
+ ///
+ public static class PlatformShellSettings {
+
+ private const string _prefix = "Orchard";
+ private const string _emptyValueString = "null";
+
+ ///
+ /// Applies platform configuration overrides to the specified ShellSettings objects.
+ ///
+ /// A list of ShellSettings objects to which platform configuration overrides will be applied.
+ public static void ApplyTo(IEnumerable shellSettingsList) {
+ foreach (var settings in shellSettingsList) {
+ foreach (var key in settings.Keys.ToArray()) {
+ var cloudConfigurationKey = String.Format("{0}.{1}.{2}", _prefix, settings.Name, key);
+ var cloudConfigurationValue = ParseValue(CloudConfigurationManager.GetSetting(cloudConfigurationKey));
+ if (cloudConfigurationValue != null)
+ settings[key] = cloudConfigurationValue;
+ }
+ }
+ }
+
+ private static string ParseValue(string value) {
+ if (value == _emptyValueString || String.IsNullOrWhiteSpace(value))
+ return null;
+ return value;
+ }
+ }
+}
diff --git a/src/Orchard/Environment/Configuration/ShellSettingsManager.cs b/src/Orchard/Environment/Configuration/ShellSettingsManager.cs
index f9ef0fe3c..d44c60e66 100644
--- a/src/Orchard/Environment/Configuration/ShellSettingsManager.cs
+++ b/src/Orchard/Environment/Configuration/ShellSettingsManager.cs
@@ -7,13 +7,17 @@ using Orchard.Localization;
namespace Orchard.Environment.Configuration {
public class ShellSettingsManager : IShellSettingsManager {
+ private const string _settingsFileName = "Settings.txt";
private readonly IAppDataFolder _appDataFolder;
private readonly IShellSettingsManagerEventHandler _events;
- public Localizer T { get; set; }
-
+ public Localizer T {
+ get;
+ set;
+ }
+
public ShellSettingsManager(
- IAppDataFolder appDataFolder,
+ IAppDataFolder appDataFolder,
IShellSettingsManagerEventHandler events) {
_appDataFolder = appDataFolder;
_events = events;
@@ -22,25 +26,27 @@ namespace Orchard.Environment.Configuration {
}
IEnumerable IShellSettingsManager.LoadSettings() {
- return LoadSettings().ToArray();
+ var settings = LoadSettingsInternal().ToArray();
+ PlatformShellSettings.ApplyTo(settings); // Apply platform configuration overrides.
+ return settings;
}
void IShellSettingsManager.SaveSettings(ShellSettings settings) {
if (settings == null)
- throw new ArgumentException(T("There are no settings to save.").ToString());
- if (string.IsNullOrEmpty(settings.Name))
- throw new ArgumentException(T("Settings \"Name\" is not set.").ToString());
+ throw new ArgumentNullException("settings");
+ if (String.IsNullOrEmpty(settings.Name))
+ throw new ArgumentException("The Name property of the supplied ShellSettings object is null or empty. The settings cannot be saved.", "settings");
- var filePath = Path.Combine(Path.Combine("Sites", settings.Name), "Settings.txt");
+ var filePath = Path.Combine(Path.Combine("Sites", settings.Name), _settingsFileName);
_appDataFolder.CreateFile(filePath, ShellSettingsSerializer.ComposeSettings(settings));
_events.Saved(settings);
}
- IEnumerable LoadSettings() {
+ private IEnumerable LoadSettingsInternal() {
var filePaths = _appDataFolder
.ListDirectories("Sites")
.SelectMany(path => _appDataFolder.ListFiles(path))
- .Where(path => string.Equals(Path.GetFileName(path), "Settings.txt", StringComparison.OrdinalIgnoreCase));
+ .Where(path => String.Equals(Path.GetFileName(path), _settingsFileName, StringComparison.OrdinalIgnoreCase));
foreach (var filePath in filePaths) {
yield return ShellSettingsSerializer.ParseSettings(_appDataFolder.ReadFile(filePath));
diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj
index fa0446aa1..25887539c 100644
--- a/src/Orchard/Orchard.Framework.csproj
+++ b/src/Orchard/Orchard.Framework.csproj
@@ -84,6 +84,10 @@
..\..\lib\log4net\log4net.dll
+
+ False
+ ..\..\lib\windowsazure\Microsoft.WindowsAzure.Configuration.dll
+
..\..\lib\newtonsoft.json\Newtonsoft.Json.dll
@@ -218,6 +222,7 @@
+