diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj b/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj index 439b09dd1..0308978ea 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj +++ b/src/Orchard.Web/Modules/Orchard.Azure/Orchard.Azure.csproj @@ -53,10 +53,6 @@ False ..\..\..\..\lib\windowsazure\Microsoft.ApplicationServer.Caching.AzureClientHelper.dll - - False - ..\..\..\..\lib\windowsazure\Microsoft.ApplicationServer.Caching.AzureCommon.dll - False ..\..\..\..\lib\windowsazure\Microsoft.ApplicationServer.Caching.Client.dll @@ -65,47 +61,18 @@ False ..\..\..\..\lib\windowsazure\Microsoft.ApplicationServer.Caching.Core.dll - - False - ..\..\..\..\lib\windowsazure\Microsoft.Data.Edm.dll - - - False - ..\..\..\..\lib\windowsazure\Microsoft.Data.OData.dll - - - False - ..\..\..\..\lib\windowsazure\Microsoft.Web.DistributedCache.dll - False ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Configuration.dll - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Diagnostics.dll - False ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Diagnostics.StorageUtility.dll - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.ServiceRuntime.dll - True - False ..\..\..\..\lib\windowsazure\Microsoft.WindowsAzure.Storage.dll - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsFabric.Common.dll - - - False - ..\..\..\..\lib\windowsazure\Microsoft.WindowsFabric.Data.Common.dll - False ..\..\..\..\lib\nhibernate\NHibernate.dll @@ -115,7 +82,6 @@ False ..\..\..\..\lib\aspnetmvc\System.Web.Mvc.dll - @@ -140,6 +106,7 @@ + diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs index 37286ceba..925ba081f 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs +++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/AzureOutputCacheStorageProvider.cs @@ -14,32 +14,37 @@ namespace Orchard.Azure.Services.Caching.Output { [OrchardFeature(Constants.OutputCacheFeatureName)] [OrchardSuppressDependency("Orchard.OutputCache.Services.DefaultCacheStorageProvider")] public class AzureOutputCacheStorageProvider : Component, IOutputCacheStorageProvider { + private readonly DataCache _cache; + private readonly string _regionAlphaNumeric; - public AzureOutputCacheStorageProvider(ShellSettings shellSettings) { + public AzureOutputCacheStorageProvider(ShellSettings shellSettings, IAzureOutputCacheHolder cacheHolder) { - try { - _cacheConfig = CacheClientConfiguration.FromPlatformConfiguration(shellSettings.Name, Constants.OutputCacheSettingNamePrefix); - _cacheConfig.Validate(); - } - catch (Exception ex) { - throw new Exception(String.Format("The {0} configuration settings are missing or invalid.", Constants.OutputCacheFeatureName), ex); - } - - _cache = _cacheConfig.CreateCache(); - _region = shellSettings.Name; + var region = shellSettings.Name; // Azure Cache supports only alphanumeric strings for regions, but Orchard supports some // non-alphanumeric characters in tenant names. Remove all non-alphanumering characters // from the region, and append the hash code of the original string to mitigate the risk // of two distinct original region strings yielding the same transformed region string. - _regionAlphaNumeric = new String(Array.FindAll(_region.ToCharArray(), Char.IsLetterOrDigit)) + _region.GetHashCode().ToString(CultureInfo.InvariantCulture); - _cache.CreateRegion(_regionAlphaNumeric); - } + _regionAlphaNumeric = new String(Array.FindAll(region.ToCharArray(), Char.IsLetterOrDigit)) + region.GetHashCode().ToString(CultureInfo.InvariantCulture); - private readonly CacheClientConfiguration _cacheConfig; - private readonly DataCache _cache; - private readonly string _region; - private readonly string _regionAlphaNumeric; + + _cache = cacheHolder.TryGetDataCache(() => { + CacheClientConfiguration cacheConfig; + + try { + cacheConfig = CacheClientConfiguration.FromPlatformConfiguration(shellSettings.Name, Constants.OutputCacheSettingNamePrefix); + cacheConfig.Validate(); + } + catch (Exception ex) { + throw new Exception(String.Format("The {0} configuration settings are missing or invalid.", Constants.OutputCacheFeatureName), ex); + } + + var cache = cacheConfig.CreateCache(); + cache.CreateRegion(_regionAlphaNumeric); + + return cache; + }); + } public void Set(string key, CacheItem cacheItem) { Logger.Debug("Set() invoked with key='{0}' in region '{1}'.", key, _regionAlphaNumeric); diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/IAzureOutputCacheHolder.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/IAzureOutputCacheHolder.cs new file mode 100644 index 000000000..12bdddbd4 --- /dev/null +++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/Caching/Output/IAzureOutputCacheHolder.cs @@ -0,0 +1,23 @@ +using System; +using Microsoft.ApplicationServer.Caching; + +namespace Orchard.Azure.Services.Caching.Output { + public interface IAzureOutputCacheHolder : ISingletonDependency { + DataCache TryGetDataCache(Func builder); + } + + public class AzureOutputCacheHolder : IAzureOutputCacheHolder { + private readonly object _synLock = new object(); + private DataCache _dataCache; + + public DataCache TryGetDataCache(Func builder) { + lock (_synLock) { + if (_dataCache != null) { + return _dataCache; + } + + return _dataCache = builder(); + } + } + } +} \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/PlatformConfiguration.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/PlatformConfiguration.cs index e3e616346..6963ed5c9 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/PlatformConfiguration.cs +++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/Environment/Configuration/PlatformConfiguration.cs @@ -13,8 +13,8 @@ namespace Orchard.Azure.Services.Environment.Configuration { /// An optional prefix to prepend the setting name with. /// The value of the setting if found with or without tenant name prefix, otherwise null. public static string GetSetting(string name, string tenant, string namePrefix = null) { - var tenantName = tenant + ":" + namePrefix + name; - var fallbackName = namePrefix + name; + var tenantName = tenant + ":" + (namePrefix ?? string.Empty) + name; + var fallbackName = (namePrefix ?? string.Empty) + name; return CloudConfigurationManager.GetSetting(tenantName) ?? CloudConfigurationManager.GetSetting(fallbackName); } } diff --git a/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs b/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs index 521f2a88b..515b38583 100644 --- a/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs +++ b/src/Orchard.Web/Modules/Orchard.Azure/Services/FileSystems/AzureFileSystem.cs @@ -109,13 +109,7 @@ namespace Orchard.Azure.Services.FileSystems { return path2; } - var ch = path1[path1.Length - 1]; - - if (ch != '/') { - return (path1.TrimEnd('/') + '/' + path2.TrimStart('/')); - } - - return (path1 + path2); + return (path1.TrimEnd('/') + '/' + path2.TrimStart('/')); } public IStorageFile GetFile(string path) {