diff --git a/src/Orchard.Azure.Tests/App.config b/src/Orchard.Azure.Tests/App.config
index 61487f367..41aa17680 100644
--- a/src/Orchard.Azure.Tests/App.config
+++ b/src/Orchard.Azure.Tests/App.config
@@ -3,4 +3,7 @@
-
+
+
+
+
diff --git a/src/Orchard.Azure.Tests/AzureVirtualEnvironmentTest.cs b/src/Orchard.Azure.Tests/AzureVirtualEnvironmentTest.cs
index 6a19547b8..73ab3b121 100644
--- a/src/Orchard.Azure.Tests/AzureVirtualEnvironmentTest.cs
+++ b/src/Orchard.Azure.Tests/AzureVirtualEnvironmentTest.cs
@@ -1,6 +1,8 @@
-using System.Configuration;
+using System.ComponentModel;
+using System.Configuration;
using System.Diagnostics;
using System.IO;
+using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using NUnit.Framework;
@@ -35,7 +37,11 @@ namespace Orchard.Azure.Tests {
_dsService.Close();
}
- protected void DeleteAllBlobs(CloudBlobContainer container) {
+ protected void DeleteAllBlobs(string containerName, CloudStorageAccount account)
+ {
+ var blobClient = account.CreateCloudBlobClient();
+ var container = blobClient.GetContainerReference(containerName);
+
foreach ( var blob in container.ListBlobs() ) {
if ( blob is CloudBlob ) {
( (CloudBlob)blob ).DeleteIfExists();
diff --git a/src/Orchard.Azure.Tests/Environment/Configuration/AzureShellSettingsManagerTests.cs b/src/Orchard.Azure.Tests/Environment/Configuration/AzureShellSettingsManagerTests.cs
index 8c63d172c..f65767ca8 100644
--- a/src/Orchard.Azure.Tests/Environment/Configuration/AzureShellSettingsManagerTests.cs
+++ b/src/Orchard.Azure.Tests/Environment/Configuration/AzureShellSettingsManagerTests.cs
@@ -8,36 +8,35 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[TestFixture]
public class AzureShellSettingsManagerTests : AzureVirtualEnvironmentTest {
- protected IShellSettingsManager Loader;
+ protected CloudStorageAccount DevAccount;
+ protected IShellSettingsManager ShellSettingsManager;
protected override void OnInit() {
- CloudStorageAccount devAccount;
- CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out devAccount);
-
- Loader = new AzureShellSettingsManager(devAccount, new Moq.Mock().Object);
+ CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out DevAccount);
+ ShellSettingsManager = new AzureShellSettingsManager(DevAccount, new Moq.Mock().Object);
}
[SetUp]
public void Setup() {
// ensure default container is empty before running any test
- DeleteAllBlobs( ((AzureShellSettingsManager)Loader).Container);
+ DeleteAllBlobs(AzureShellSettingsManager.ContainerName, DevAccount);
}
[TearDown]
public void TearDown() {
// ensure default container is empty after running tests
- DeleteAllBlobs(( (AzureShellSettingsManager)Loader ).Container);
+ DeleteAllBlobs(AzureShellSettingsManager.ContainerName, DevAccount);
}
[Test]
public void SingleSettingsFileShouldComeBackAsExpected() {
- Loader.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });
+ ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
- var settings = Loader.LoadSettings().Single();
+ var settings = ShellSettingsManager.LoadSettings().Single();
Assert.That(settings, Is.Not.Null);
Assert.That(settings.Name, Is.EqualTo("Default"));
- Assert.That(settings.DataProvider, Is.EqualTo("SQLite"));
+ Assert.That(settings.DataProvider, Is.EqualTo("SQLCe"));
Assert.That(settings.DataConnectionString, Is.EqualTo("something else"));
}
@@ -45,37 +44,37 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
[Test]
public void MultipleFilesCanBeDetected() {
- Loader.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });
- Loader.SaveSettings(new ShellSettings { Name = "Another", DataProvider = "SQLite2", DataConnectionString = "something else2" });
+ ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLCe", DataConnectionString = "something else" });
+ ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Another", DataProvider = "SQLCe2", DataConnectionString = "something else2" });
- var settings = Loader.LoadSettings();
+ var settings = ShellSettingsManager.LoadSettings();
Assert.That(settings.Count(), Is.EqualTo(2));
var def = settings.Single(x => x.Name == "Default");
Assert.That(def.Name, Is.EqualTo("Default"));
- Assert.That(def.DataProvider, Is.EqualTo("SQLite"));
+ Assert.That(def.DataProvider, Is.EqualTo("SQLCe"));
Assert.That(def.DataConnectionString, Is.EqualTo("something else"));
var alt = settings.Single(x => x.Name == "Another");
Assert.That(alt.Name, Is.EqualTo("Another"));
- Assert.That(alt.DataProvider, Is.EqualTo("SQLite2"));
+ Assert.That(alt.DataProvider, Is.EqualTo("SQLCe2"));
Assert.That(alt.DataConnectionString, Is.EqualTo("something else2"));
}
[Test]
public void NewSettingsCanBeStored() {
- Loader.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });
+ ShellSettingsManager.SaveSettings(new ShellSettings { Name = "Default", DataProvider = "SQLite", DataConnectionString = "something else" });
var foo = new ShellSettings { Name = "Foo", DataProvider = "Bar", DataConnectionString = "Quux" };
- Assert.That(Loader.LoadSettings().Count(), Is.EqualTo(1));
- Loader.SaveSettings(foo);
- Assert.That(Loader.LoadSettings().Count(), Is.EqualTo(2));
+ Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(1));
+ ShellSettingsManager.SaveSettings(foo);
+ Assert.That(ShellSettingsManager.LoadSettings().Count(), Is.EqualTo(2));
- var text = ( (AzureShellSettingsManager)Loader ).Container.GetBlockBlobReference("Foo/Settings.txt").DownloadText();
- Assert.That(text, Is.StringContaining("Foo"));
- Assert.That(text, Is.StringContaining("Bar"));
- Assert.That(text, Is.StringContaining("Quux"));
+ foo = ShellSettingsManager.LoadSettings().Where(s => s.Name == "Foo").Single();
+ Assert.That(foo.Name, Is.StringContaining("Foo"));
+ Assert.That(foo.DataProvider, Is.StringContaining("Bar"));
+ Assert.That(foo.DataConnectionString, Is.StringContaining("Quux"));
}
}
}
diff --git a/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs b/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs
index f6e4fda80..256c7c505 100644
--- a/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs
+++ b/src/Orchard.Azure.Tests/FileSystems/Media/AzureBlobStorageProviderTests.cs
@@ -10,19 +10,19 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
[TestFixture]
public class AzureBlobStorageProviderTests : AzureVirtualEnvironmentTest {
+ CloudStorageAccount DevAccount;
private AzureBlobStorageProvider _azureBlobStorageProvider;
protected override void OnInit() {
- CloudStorageAccount devAccount;
- CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out devAccount);
+ CloudStorageAccount.TryParse("UseDevelopmentStorage=true", out DevAccount);
- _azureBlobStorageProvider = new AzureBlobStorageProvider(new ShellSettings { Name = "default" }, devAccount);
+ _azureBlobStorageProvider = new AzureBlobStorageProvider(new ShellSettings { Name = "default" }, DevAccount);
}
[SetUp]
public void Setup() {
// ensure default container is empty before running any test
- DeleteAllBlobs(_azureBlobStorageProvider.Container);
+ DeleteAllBlobs(_azureBlobStorageProvider.Container.Name, DevAccount);
}
[Test]
diff --git a/src/Orchard.Azure/AzureFileSystem.cs b/src/Orchard.Azure/AzureFileSystem.cs
index 7d1bd11d3..05a42e61e 100644
--- a/src/Orchard.Azure/AzureFileSystem.cs
+++ b/src/Orchard.Azure/AzureFileSystem.cs
@@ -28,8 +28,8 @@ namespace Orchard.Azure {
// Setup the connection to custom storage accountm, e.g. Development Storage
_storageAccount = storageAccount;
ContainerName = containerName;
- _root = String.IsNullOrEmpty(root) || root == "/" ? String.Empty : root + "/";
- _absoluteRoot = _storageAccount.BlobEndpoint.AbsoluteUri + containerName + "/" + root + "/";
+ _root = String.IsNullOrEmpty(root) ? "": root + "/";
+ _absoluteRoot = _storageAccount.BlobEndpoint.AbsoluteUri + "/" + containerName + "/" + root;
using ( new HttpContextWeaver() ) {
@@ -40,12 +40,11 @@ namespace Orchard.Azure {
Container.CreateIfNotExist();
- if (isPrivate) {
- Container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Off });
- }
- else {
- Container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Container });
- }
+ Container.SetPermissions(isPrivate
+ ? new BlobContainerPermissions
+ {PublicAccess = BlobContainerPublicAccessType.Off}
+ : new BlobContainerPermissions
+ {PublicAccess = BlobContainerPublicAccessType.Container});
}
}
@@ -107,7 +106,7 @@ namespace Orchard.Azure {
EnsurePathIsRelative(path);
- string prefix = String.Concat(Combine(Container.Name, _root), path);
+ string prefix = Combine(Combine(Container.Name, _root), path);
if ( !prefix.EndsWith("/") )
prefix += "/";
@@ -128,7 +127,16 @@ namespace Orchard.Azure {
EnsurePathIsRelative(path);
using ( new HttpContextWeaver() ) {
- if ( !Container.DirectoryExists(String.Concat(_root, path)) ) {
+
+ // return root folders
+ if (String.Concat(_root, path) == String.Empty) {
+ return Container.ListBlobs()
+ .OfType()
+ .Select(d => new AzureBlobFolderStorage(d, _absoluteRoot))
+ .ToList();
+ }
+
+ if (!Container.DirectoryExists(String.Concat(_root, path)) ) {
try {
CreateFolder(String.Concat(_root, path));
}
@@ -146,14 +154,12 @@ namespace Orchard.Azure {
}
}
- public void TryCreateFolder(string path)
- {
+ public void TryCreateFolder(string path) {
EnsurePathIsRelative(path);
CreateFile(Combine(path, FolderEntry));
}
- public void CreateFolder(string path)
- {
+ public void CreateFolder(string path) {
EnsurePathIsRelative(path);
using (new HttpContextWeaver()) {
Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path));
diff --git a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs
index 524c02777..d38e673e6 100644
--- a/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs
+++ b/src/Orchard.Azure/Environment/Configuration/AzureShellSettingsManager.cs
@@ -2,10 +2,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
-using JetBrains.Annotations;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;
-using Microsoft.WindowsAzure.StorageClient;
using Orchard.Environment.Configuration;
using Orchard.Localization;
@@ -13,97 +11,68 @@ namespace Orchard.Azure.Environment.Configuration {
public class AzureShellSettingsManager : IShellSettingsManager {
public const string ContainerName = "sites"; // container names must be lower cased
+ public const string SettingsFilename = "Settings.txt";
+
private readonly IShellSettingsManagerEventHandler _events;
+ private readonly AzureFileSystem _fileSystem;
- private readonly CloudStorageAccount _storageAccount;
- public CloudBlobClient BlobClient { get; private set; }
- public CloudBlobContainer Container { get; private set; }
-
- Localizer T { get; [UsedImplicitly]
- set; }
+ Localizer T { get; set; }
public AzureShellSettingsManager(IShellSettingsManagerEventHandler events)
- : this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events)
- {
- }
+ : this(CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("DataConnectionString")), events) {}
- public AzureShellSettingsManager(CloudStorageAccount storageAccount, IShellSettingsManagerEventHandler events)
- {
- // Setup the connection to custom storage accountm, e.g. Development Storage
- _storageAccount = storageAccount;
+ public AzureShellSettingsManager(CloudStorageAccount storageAccount, IShellSettingsManagerEventHandler events) {
_events = events;
-
- using ( new HttpContextWeaver() ) {
- BlobClient = _storageAccount.CreateCloudBlobClient();
-
- // Get and create the container if it does not exist
- // The container is named with DNS naming restrictions (i.e. all lower case)
- Container = new CloudBlobContainer(ContainerName, BlobClient);
- Container.CreateIfNotExist();
-
- // Tenant settings are protected by default
- Container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Off });
- }
-
+ _fileSystem = new AzureFileSystem(ContainerName, String.Empty, true, storageAccount);
}
IEnumerable IShellSettingsManager.LoadSettings() {
- return LoadSettings().ToArray();
+ var settings = LoadSettings().ToArray();
+ 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());
+ var content = ComposeSettings(settings);
+ var filePath = String.Concat(settings.Name, "/", SettingsFilename);
+ var file = _fileSystem.CreateFile(filePath);
- using ( new HttpContextWeaver() ) {
- var filePath = String.Concat(settings.Name, "/", "Settings.txt");
- var blob = Container.GetBlockBlobReference(filePath);
- blob.UploadText(ComposeSettings(settings));
+ using (var stream = file.OpenWrite()) {
+ using (var writer = new StreamWriter(stream)) {
+ writer.Write(content);
+ }
}
_events.Saved(settings);
}
IEnumerable LoadSettings() {
+ foreach (var folder in _fileSystem.ListFolders(null))
+ foreach (var file in _fileSystem.ListFiles(folder.GetPath())) {
+ if (!String.Equals(file.GetName(), SettingsFilename))
+ continue;
- using ( new HttpContextWeaver() ) {
- var settingsBlobs =
- BlobClient.ListBlobsWithPrefix(Container.Name + "/").OfType()
- .SelectMany(directory => directory.ListBlobs()).OfType()
- .Where(
- blob =>
- string.Equals(Path.GetFileName(blob.Uri.ToString()),
- "Settings.txt",
- StringComparison.OrdinalIgnoreCase));
-
- return settingsBlobs.Select(settingsBlob => ParseSettings(settingsBlob.DownloadText())).ToList();
- }
+ using (var stream = file.OpenRead())
+ using (var reader = new StreamReader(stream))
+ yield return ParseSettings(reader.ReadToEnd());
+ }
}
- static ShellSettings ParseSettings(string text)
- {
+ static ShellSettings ParseSettings(string text) {
var shellSettings = new ShellSettings();
if (String.IsNullOrEmpty(text))
return shellSettings;
- string[] settings = text.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
- foreach (var setting in settings)
- {
- string[] settingFields = setting.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries);
+ string[] settings = text.Split(new[] {"\r\n"}, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var setting in settings) {
+ string[] settingFields = setting.Split(new[] {":"}, StringSplitOptions.RemoveEmptyEntries);
int fieldsLength = settingFields.Length;
if (fieldsLength != 2)
continue;
- for (int i = 0; i < fieldsLength; i++)
- {
+ for (int i = 0; i < fieldsLength; i++) {
settingFields[i] = settingFields[i].Trim();
}
- if (settingFields[1] != "null")
- {
- switch (settingFields[0])
- {
+ if (settingFields[1] != "null") {
+ switch (settingFields[0]) {
case "Name":
shellSettings.Name = settingFields[1];
break;
@@ -140,23 +109,22 @@ namespace Orchard.Azure.Environment.Configuration {
return shellSettings;
}
- static string ComposeSettings(ShellSettings settings)
- {
+ static string ComposeSettings(ShellSettings settings) {
if (settings == null)
return "";
return string.Format("Name: {0}\r\nDataProvider: {1}\r\nDataConnectionString: {2}\r\nDataPrefix: {3}\r\nRequestUrlHost: {4}\r\nRequestUrlPrefix: {5}\r\nState: {6}\r\nEncryptionAlgorithm: {7}\r\nEncryptionKey: {8}\r\nEncryptionIV: {9}\r\n",
- settings.Name,
- settings.DataProvider,
- settings.DataConnectionString ?? "null",
- settings.DataTablePrefix ?? "null",
- settings.RequestUrlHost ?? "null",
- settings.RequestUrlPrefix ?? "null",
- settings.State != null ? settings.State.ToString() : String.Empty,
- settings.EncryptionAlgorithm ?? "null",
- settings.EncryptionKey ?? "null",
- settings.EncryptionIV ?? "null"
- );
+ settings.Name,
+ settings.DataProvider,
+ settings.DataConnectionString ?? "null",
+ settings.DataTablePrefix ?? "null",
+ settings.RequestUrlHost ?? "null",
+ settings.RequestUrlPrefix ?? "null",
+ settings.State != null ? settings.State.ToString() : String.Empty,
+ settings.EncryptionAlgorithm ?? "null",
+ settings.EncryptionKey ?? "null",
+ settings.EncryptionIV ?? "null"
+ );
}
}
}
diff --git a/src/Orchard.Azure/Orchard.Azure.5.0.ReSharper b/src/Orchard.Azure/Orchard.Azure.5.0.ReSharper
new file mode 100644
index 000000000..470d2dcf2
--- /dev/null
+++ b/src/Orchard.Azure/Orchard.Azure.5.0.ReSharper
@@ -0,0 +1,108 @@
+
+
+
+
+ SOLUTION
+
+
+ False
+ False
+ False
+ END_OF_LINE
+ END_OF_LINE
+ TOGETHER
+ ALWAYS_ADD
+ ALWAYS_ADD
+ ALWAYS_ADD
+ ALWAYS_ADD
+ ALWAYS_ADD
+ ALWAYS_ADD
+ END_OF_LINE
+ END_OF_LINE
+
+ - public
+ - protected
+ - internal
+ - private
+ - new
+ - abstract
+ - virtual
+ - override
+ - sealed
+ - static
+ - readonly
+ - extern
+ - unsafe
+ - volatile
+
+ END_OF_LINE
+ END_OF_LINE
+ False
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $object$_On$event$
+ $event$Handler
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
index 462e8f2ae..62fdd5deb 100644
--- a/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
+++ b/src/Orchard.Azure/Orchard.Azure.CloudService/ServiceDefinition.csdef
@@ -1,6 +1,13 @@
+