mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
Extended default ShellSettingsManager implementation to apply platform configuration overrrides when loading settings.
Removed the AzureConfigShellSettingsManager class.
This commit is contained in:

committed by
Sebastien Ros

parent
93c628bf85
commit
687fdadccc
@@ -7,9 +7,9 @@
|
||||
|
||||
<autofac defaultAssembly="Orchard.Framework">
|
||||
<components>
|
||||
<!-- Configure Orchard to store shell settings (Settings.txt) in platform configuration and Azure Blob Storage. -->
|
||||
<!-- Configure Orchard to store shell settings in Windows Azure Blob Storage. -->
|
||||
<component instance-scope="single-instance" type="Orchard.FileSystems.Media.ConfigurationMimeTypeProvider, Orchard.Framework" service="Orchard.FileSystems.Media.IMimeTypeProvider"></component>
|
||||
<component instance-scope="single-instance" type="Orchard.Azure.Services.Environment.Configuration.AzureConfigShellSettingsManager, Orchard.Azure" service="Orchard.Environment.Configuration.IShellSettingsManager"></component>
|
||||
<component instance-scope="single-instance" type="Orchard.Azure.Services.Environment.Configuration.AzureBlobShellSettingsManager, Orchard.Azure" service="Orchard.Environment.Configuration.IShellSettingsManager"></component>
|
||||
</components>
|
||||
</autofac>
|
||||
|
||||
|
@@ -6,12 +6,6 @@
|
||||
</configSections>
|
||||
|
||||
<autofac defaultAssembly="Orchard.Framework">
|
||||
|
||||
<!-- Uncomment below to have Orchard store shell settings (Settings.txt) in platform configuration and Azure Blob Storage (useful when running multiple instances on Azure Web sites). -->
|
||||
<!--<components>
|
||||
<component instance-scope="single-instance" type="Orchard.Azure.Services.Environment.Configuration.AzureConfigShellSettingsManager, Orchard.Azure" service="Orchard.Environment.Configuration.IShellSettingsManager"></component>
|
||||
</components>-->
|
||||
|
||||
</autofac>
|
||||
|
||||
</configuration>
|
@@ -147,7 +147,6 @@
|
||||
<Compile Include="Services\Caching\Database\AzureCacheConfiguration.cs" />
|
||||
<Compile Include="Services\Caching\Database\AzureCacheProvider.cs" />
|
||||
<Compile Include="Services\Caching\Output\AzureOutputCacheStorageProvider.cs" />
|
||||
<Compile Include="Services\Environment\Configuration\AzureConfigShellSettingsManager.cs" />
|
||||
<Compile Include="Services\Environment\Configuration\AzureBlobShellSettingsManager.cs" />
|
||||
<Compile Include="Services\FileSystems\AzureFileSystem.cs" />
|
||||
<Compile Include="Services\FileSystems\CloudBlobContainerExtensions.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 {
|
||||
|
||||
/// <summary>
|
||||
/// Provides an IShellSettingsManager implementation that uses Windows Azure Blob Storage as the
|
||||
/// underlying storage system.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
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<ShellSettings> 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<ShellSettings> LoadSettingsInternal() {
|
||||
foreach (var folder in FileSystem.ListFolders(null)) {
|
||||
foreach (var file in FileSystem.ListFiles(folder.GetPath())) {
|
||||
|
@@ -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<ShellSettings> 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.WindowsAzure;
|
||||
|
||||
namespace Orchard.Environment.Configuration {
|
||||
|
||||
/// <summary>
|
||||
/// Provides logic to override individual shell settings with values read from platform configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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 <see cref="Microsoft.WindowsAzure.CloudConfigurationManager"/> class looks.
|
||||
/// </remarks>
|
||||
public static class PlatformShellSettings {
|
||||
|
||||
private const string _prefix = "Orchard";
|
||||
private const string _emptyValueString = "null";
|
||||
|
||||
/// <summary>
|
||||
/// Applies platform configuration overrides to the specified ShellSettings objects.
|
||||
/// </summary>
|
||||
/// <param name="shellSettingsList">A list of ShellSettings objects to which platform configuration overrides will be applied.</param>
|
||||
public static void ApplyTo(IEnumerable<ShellSettings> 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;
|
||||
}
|
||||
}
|
||||
}
|
@@ -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<ShellSettings> 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<ShellSettings> LoadSettings() {
|
||||
private IEnumerable<ShellSettings> 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));
|
||||
|
@@ -84,6 +84,10 @@
|
||||
<HintPath>..\..\lib\log4net\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.WindowsAzure.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\windowsazure\Microsoft.WindowsAzure.Configuration.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -218,6 +222,7 @@
|
||||
<Compile Include="Environment\AutofacUtil\ConfigurationSettingsReaderConstants.cs" />
|
||||
<Compile Include="Environment\CollectionOrderModule.cs" />
|
||||
<Compile Include="Caching\DefaultAsyncTokenProvider.cs" />
|
||||
<Compile Include="Environment\Configuration\PlatformShellSettings.cs" />
|
||||
<Compile Include="Environment\Configuration\ShellSettingsSerializer.cs" />
|
||||
<Compile Include="Environment\Extensions\DefaultCriticalErrorProvider.cs" />
|
||||
<Compile Include="Environment\Extensions\ExtensionMonitoringCoordinator.cs" />
|
||||
|
Reference in New Issue
Block a user