Correcting Azure blob storage returned values

- Paths should be relative for Orchard.Media

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-10-21 12:47:40 -07:00
parent b7f6e70d29
commit 63e25ef1a8
5 changed files with 85 additions and 80 deletions

View File

@@ -48,7 +48,8 @@
<MSBuild <MSBuild
Projects="$(SrcFolder)\Orchard.Azure\Orchard.Azure.CloudService.sln" Projects="$(SrcFolder)\Orchard.Azure\Orchard.Azure.CloudService.sln"
Targets="Build" Targets="Build"
Properties="Configuration=Release;OutputPath=$(CompileFolder);PlatformTarget=x64" /> Properties="Configuration=Release;OutputPath=$(CompileFolder);PlatformTarget=x64;DefineConstants=AZURE"
/>
<MSBuild <MSBuild
Projects="$(SrcFolder)\Orchard.Azure.sln" Projects="$(SrcFolder)\Orchard.Azure.sln"

View File

@@ -50,7 +50,7 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
Assert.AreEqual(".txt", storageFile.GetFileType()); Assert.AreEqual(".txt", storageFile.GetFileType());
Assert.AreEqual("foo.txt", storageFile.GetName()); Assert.AreEqual("foo.txt", storageFile.GetName());
Assert.That(storageFile.GetPath().EndsWith("/default/foo.txt"), Is.True); Assert.AreEqual("foo.txt", storageFile.GetPath());
Assert.AreEqual(0, storageFile.GetSize()); Assert.AreEqual(0, storageFile.GetSize());
} }
@@ -71,7 +71,8 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
var files = _azureBlobStorageProvider.ListFiles(""); var files = _azureBlobStorageProvider.ListFiles("");
Assert.AreEqual(1, files.Count()); Assert.AreEqual(1, files.Count());
Assert.That(files.First().GetPath().EndsWith("foo2.txt"), Is.True); Assert.That(files.First().GetPath().Equals("foo2.txt"), Is.True);
Assert.That(files.First().GetName().Equals("foo2.txt"), Is.True);
} }
[Test] [Test]
@@ -82,7 +83,11 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("").Count()); Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("").Count());
Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder").Count()); Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder").Count());
Assert.AreEqual("folder/foo.txt", _azureBlobStorageProvider.ListFiles("folder").First().GetPath());
Assert.AreEqual("foo.txt", _azureBlobStorageProvider.ListFiles("folder").First().GetName());
Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder/folder").Count()); Assert.AreEqual(1, _azureBlobStorageProvider.ListFiles("folder/folder").Count());
Assert.AreEqual("folder/folder/foo.txt", _azureBlobStorageProvider.ListFiles("folder/folder").First().GetPath());
Assert.AreEqual("foo.txt", _azureBlobStorageProvider.ListFiles("folder/folder").First().GetName());
} }
[Test] [Test]
@@ -92,6 +97,14 @@ namespace Orchard.Azure.Tests.FileSystems.Media {
_azureBlobStorageProvider.CreateFolder("folder"); _azureBlobStorageProvider.CreateFolder("folder");
} }
[Test]
public void ListFolderShouldAcceptNullPath() {
_azureBlobStorageProvider.CreateFolder("folder");
Assert.AreEqual(1, _azureBlobStorageProvider.ListFolders(null).Count());
Assert.AreEqual("folder", _azureBlobStorageProvider.ListFolders(null).First().GetName());
Assert.AreEqual("folder", _azureBlobStorageProvider.ListFolders(null).First().GetPath());
}
[Test] [Test]
public void DeleteFolderShouldDeleteFilesAlso() { public void DeleteFolderShouldDeleteFilesAlso() {
_azureBlobStorageProvider.CreateFile("folder/foo1.txt"); _azureBlobStorageProvider.CreateFile("folder/foo1.txt");

View File

@@ -16,6 +16,7 @@ namespace Orchard.Azure {
private readonly CloudStorageAccount _storageAccount; private readonly CloudStorageAccount _storageAccount;
private readonly string _root; private readonly string _root;
private readonly string _absoluteRoot;
public CloudBlobClient BlobClient { get; private set; } public CloudBlobClient BlobClient { get; private set; }
public CloudBlobContainer Container { get; private set; } public CloudBlobContainer Container { get; private set; }
@@ -28,6 +29,7 @@ namespace Orchard.Azure {
_storageAccount = storageAccount; _storageAccount = storageAccount;
ContainerName = containerName; ContainerName = containerName;
_root = String.IsNullOrEmpty(root) || root == "/" ? String.Empty : root + "/"; _root = String.IsNullOrEmpty(root) || root == "/" ? String.Empty : root + "/";
_absoluteRoot = _storageAccount.BlobEndpoint.AbsoluteUri + containerName + "/" + root + "/";
using ( new HttpContextWeaver() ) { using ( new HttpContextWeaver() ) {
@@ -49,70 +51,65 @@ namespace Orchard.Azure {
} }
private static void EnsurePathIsRelative(string path) { private static void EnsurePathIsRelative(string path) {
if ( path.StartsWith("/") || path.StartsWith("http://")) if (path.StartsWith("/") || path.StartsWith("http://"))
throw new ArgumentException("Path must be relative"); throw new ArgumentException("Path must be relative");
} }
public IStorageFile GetFile(string path) { public IStorageFile GetFile(string path) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
using ( new HttpContextWeaver() ) using ( new HttpContextWeaver() ) {
{ Container.EnsureBlobExists(String.Concat(_root, path));
Container.EnsureBlobExists(path); return new AzureBlobFileStorage(Container.GetBlockBlobReference(path), _absoluteRoot);
return new AzureBlobFileStorage(Container.GetBlockBlobReference(path));
} }
} }
public bool FileExists(string path) { public bool FileExists(string path) {
using ( new HttpContextWeaver() ) using ( new HttpContextWeaver() ) {
{ return Container.BlobExists(String.Concat(_root, path));
path = String.Concat(_root, path);
return Container.BlobExists(path);
} }
} }
public IEnumerable<IStorageFile> ListFiles(string path) { public IEnumerable<IStorageFile> ListFiles(string path) {
path = path ?? String.Empty;
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
string prefix = String.Concat(Container.Name, "/", _root, path); string prefix = String.Concat(Container.Name, "/", _root, path);
if ( !prefix.EndsWith("/") ) if ( !prefix.EndsWith("/") )
prefix += "/"; prefix += "/";
using ( new HttpContextWeaver() )
{ using ( new HttpContextWeaver() ) {
foreach (var blobItem in BlobClient.ListBlobsWithPrefix(prefix).OfType<CloudBlockBlob>()) foreach (var blobItem in BlobClient.ListBlobsWithPrefix(prefix).OfType<CloudBlockBlob>()) {
{
// ignore directory entries // ignore directory entries
if(blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry)) if(blobItem.Uri.AbsoluteUri.EndsWith(FolderEntry))
continue; continue;
yield return new AzureBlobFileStorage(blobItem); yield return new AzureBlobFileStorage(blobItem, _absoluteRoot);
} }
} }
} }
public IEnumerable<IStorageFolder> ListFolders(string path) { public IEnumerable<IStorageFolder> ListFolders(string path) {
path = path ?? String.Empty;
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path); using ( new HttpContextWeaver() ) {
using ( new HttpContextWeaver() ) if ( !Container.DirectoryExists(String.Concat(_root, path)) ) {
{ try {
if (!Container.DirectoryExists(path)) CreateFolder(String.Concat(_root, path));
{
try
{
CreateFolder(path);
} }
catch (Exception ex) catch ( Exception ex ) {
{
throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}",
path, ex)); path, ex));
} }
} }
return Container.GetDirectoryReference(path) return Container.GetDirectoryReference(String.Concat(_root, path))
.ListBlobs() .ListBlobs()
.OfType<CloudBlobDirectory>() .OfType<CloudBlobDirectory>()
.Select<CloudBlobDirectory, IStorageFolder>(d => new AzureBlobFolderStorage(d)) .Select<CloudBlobDirectory, IStorageFolder>(d => new AzureBlobFolderStorage(d, _absoluteRoot))
.ToList(); .ToList();
} }
} }
@@ -120,10 +117,8 @@ namespace Orchard.Azure {
public void CreateFolder(string path) public void CreateFolder(string path)
{ {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path); using (new HttpContextWeaver()) {
using (new HttpContextWeaver()) Container.EnsureDirectoryDoesNotExist(String.Concat(_root, path));
{
Container.EnsureDirectoryDoesNotExist(path);
// Creating a virtually hidden file to make the directory an existing concept // Creating a virtually hidden file to make the directory an existing concept
CreateFile(path + "/" + FolderEntry); CreateFile(path + "/" + FolderEntry);
@@ -132,13 +127,10 @@ namespace Orchard.Azure {
public void DeleteFolder(string path) { public void DeleteFolder(string path) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
using ( new HttpContextWeaver() ) using ( new HttpContextWeaver() ) {
{ Container.EnsureDirectoryExists(String.Concat(_root, path));
Container.EnsureDirectoryExists(path); foreach ( var blob in Container.GetDirectoryReference(String.Concat(_root, path)).ListBlobs() ) {
foreach (var blob in Container.GetDirectoryReference(path).ListBlobs())
{
if (blob is CloudBlob) if (blob is CloudBlob)
((CloudBlob) blob).Delete(); ((CloudBlob) blob).Delete();
@@ -150,7 +142,6 @@ namespace Orchard.Azure {
public void RenameFolder(string path, string newPath) { public void RenameFolder(string path, string newPath) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
EnsurePathIsRelative(newPath); EnsurePathIsRelative(newPath);
if ( !path.EndsWith("/") ) if ( !path.EndsWith("/") )
@@ -158,20 +149,16 @@ namespace Orchard.Azure {
if ( !newPath.EndsWith("/") ) if ( !newPath.EndsWith("/") )
newPath += "/"; newPath += "/";
using ( new HttpContextWeaver() ) using ( new HttpContextWeaver() ) {
{ foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) {
foreach (var blob in Container.GetDirectoryReference(_root + path).ListBlobs()) if (blob is CloudBlob) {
{
if (blob is CloudBlob)
{
string filename = Path.GetFileName(blob.Uri.ToString()); string filename = Path.GetFileName(blob.Uri.ToString());
string source = String.Concat(path, filename); string source = String.Concat(path, filename);
string destination = String.Concat(newPath, filename); string destination = String.Concat(newPath, filename);
RenameFile(source, destination); RenameFile(source, destination);
} }
if (blob is CloudBlobDirectory) if (blob is CloudBlobDirectory) {
{
string foldername = blob.Uri.Segments.Last(); string foldername = blob.Uri.Segments.Last();
string source = String.Concat(path, foldername); string source = String.Concat(path, foldername);
string destination = String.Concat(newPath, foldername); string destination = String.Concat(newPath, foldername);
@@ -183,29 +170,24 @@ namespace Orchard.Azure {
public void DeleteFile(string path) { public void DeleteFile(string path) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
using ( new HttpContextWeaver() ) {
using ( new HttpContextWeaver() )
{
Container.EnsureBlobExists(path); Container.EnsureBlobExists(path);
var blob = Container.GetBlockBlobReference(path); var blob = Container.GetBlockBlobReference(String.Concat(_root, path));
blob.Delete(); blob.Delete();
} }
} }
public void RenameFile(string path, string newPath) { public void RenameFile(string path, string newPath) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
EnsurePathIsRelative(newPath); EnsurePathIsRelative(newPath);
newPath = String.Concat(_root, newPath);
using ( new HttpContextWeaver() )
{
Container.EnsureBlobExists(path);
Container.EnsureBlobDoesNotExist(newPath);
var blob = Container.GetBlockBlobReference(path); using ( new HttpContextWeaver() ) {
var newBlob = Container.GetBlockBlobReference(newPath); Container.EnsureBlobExists(String.Concat(_root, path));
Container.EnsureBlobDoesNotExist(String.Concat(_root, newPath));
var blob = Container.GetBlockBlobReference(String.Concat(_root, path));
var newBlob = Container.GetBlockBlobReference(String.Concat(_root, newPath));
newBlob.CopyFromBlob(blob); newBlob.CopyFromBlob(blob);
blob.Delete(); blob.Delete();
} }
@@ -213,36 +195,36 @@ namespace Orchard.Azure {
public IStorageFile CreateFile(string path) { public IStorageFile CreateFile(string path) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
if ( Container.BlobExists(path) ) { if ( Container.BlobExists(String.Concat(_root, path)) ) {
throw new ArgumentException("File " + path + " already exists"); throw new ArgumentException("File " + path + " already exists");
} }
var blob = Container.GetBlockBlobReference(path); var blob = Container.GetBlockBlobReference(String.Concat(_root, path));
blob.OpenWrite().Dispose(); // force file creation blob.OpenWrite().Dispose(); // force file creation
return new AzureBlobFileStorage(blob); return new AzureBlobFileStorage(blob, _absoluteRoot);
} }
public string GetPublicUrl(string path) { public string GetPublicUrl(string path) {
EnsurePathIsRelative(path); EnsurePathIsRelative(path);
path = String.Concat(_root, path);
using ( new HttpContextWeaver() ) using ( new HttpContextWeaver() ) {
{ Container.EnsureBlobExists(String.Concat(_root, path));
Container.EnsureBlobExists(path); return Container.GetBlockBlobReference(String.Concat(_root, path)).Uri.ToString();
return Container.GetBlockBlobReference(path).Uri.ToString();
} }
} }
private class AzureBlobFileStorage : IStorageFile { private class AzureBlobFileStorage : IStorageFile {
private readonly CloudBlockBlob _blob; private readonly CloudBlockBlob _blob;
private readonly string _rootPath;
public AzureBlobFileStorage(CloudBlockBlob blob) { public AzureBlobFileStorage(CloudBlockBlob blob, string rootPath) {
_blob = blob; _blob = blob;
_rootPath = rootPath;
} }
public string GetPath() { public string GetPath() {
return _blob.Uri.ToString(); return _blob.Uri.ToString().Substring(_rootPath.Length+1);
} }
public string GetName() { public string GetName() {
@@ -273,17 +255,19 @@ namespace Orchard.Azure {
private class AzureBlobFolderStorage : IStorageFolder { private class AzureBlobFolderStorage : IStorageFolder {
private readonly CloudBlobDirectory _blob; private readonly CloudBlobDirectory _blob;
private readonly string _rootPath;
public AzureBlobFolderStorage(CloudBlobDirectory blob) { public AzureBlobFolderStorage(CloudBlobDirectory blob, string rootPath) {
_blob = blob; _blob = blob;
_rootPath = rootPath;
} }
public string GetName() { public string GetName() {
return Path.GetDirectoryName(_blob.Uri.ToString()); return Path.GetDirectoryName(GetPath() + "/");
} }
public string GetPath() { public string GetPath() {
return _blob.Uri.ToString(); return _blob.Uri.ToString().Substring(_rootPath.Length + 1).TrimEnd('/');
} }
public long GetSize() { public long GetSize() {
@@ -296,7 +280,7 @@ namespace Orchard.Azure {
public IStorageFolder GetParent() { public IStorageFolder GetParent() {
if ( _blob.Parent != null ) { if ( _blob.Parent != null ) {
return new AzureBlobFolderStorage(_blob.Parent); return new AzureBlobFolderStorage(_blob.Parent, _rootPath);
} }
throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory"); throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory");
} }

View File

@@ -8,6 +8,11 @@ namespace Orchard.Azure.Web {
public override bool OnStart() { public override bool OnStart() {
DiagnosticMonitor.Start("DiagnosticsConnectionString"); DiagnosticMonitor.Start("DiagnosticsConnectionString");
CloudStorageAccount.SetConfigurationSettingPublisher(
(configName, configSetter) =>
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName))
);
// For information on handling configuration changes // For information on handling configuration changes
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
RoleEnvironment.Changing += RoleEnvironmentChanging; RoleEnvironment.Changing += RoleEnvironmentChanging;

View File

@@ -1,4 +1,5 @@
using System; #if !AZURE
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -248,4 +249,5 @@ namespace Orchard.FileSystems.Media {
} }
} }
} }
#endif