Azure packaging

Executing ClickToBuild.cmd generates the package for Azure including all modules available in Orchard.Web automatically
AzureSDK in requiered for this tasks. If not present, the package won't succeed, but Orchard.Web will still be built
The Orchard.Azure solution contains the required environment for implementing Azure specific providers, and unit testing
The Orchard.Azure.CloudService solution contains the CloudService enrironment to simulate Azure platform locally

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-05-07 12:41:37 -07:00
parent ae801b66b2
commit 7248fb6fd7
21 changed files with 1179 additions and 244 deletions

View File

@@ -1,250 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.IO;
using Microsoft.WindowsAzure;
using Orchard.Storage;
namespace Orchard.Azure.Storage {
public interface IDependency { }
public class AzureBlobStorageProvider : IStorageProvider {
public const string ContainerName = "media"; // container names must be lower cased
private readonly CloudStorageAccount _storageAccount;
private string _shellName;
public CloudBlobClient BlobClient { get; private set; }
public CloudBlobContainer Container { get; private set; }
public class AzureBlobStorageProvider : AzureFileSystem, IStorageProvider {
public AzureBlobStorageProvider(string shellName)
: this(shellName, CloudStorageAccount.FromConfigurationSetting("DataConnectionString")) {
}
public AzureBlobStorageProvider(string shellName, CloudStorageAccount storageAccount) {
// Setup the connection to custom storage accountm, e.g. Development Storage
_storageAccount = storageAccount;
_shellName = shellName;
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 = BlobClient.GetContainerReference(ContainerName);
Container.CreateIfNotExist();
Container.SetPermissions(new BlobContainerPermissions { PublicAccess = BlobContainerPublicAccessType.Container });
}
private static void EnsurePathIsRelative(string path) {
if ( path.StartsWith("/") || path.StartsWith("http://"))
throw new ArgumentException("Path must be relative");
}
public IStorageFile GetFile(string path) {
EnsurePathIsRelative(path);
Container.EnsureBlobExists(path);
return new AzureBlobFileStorage(Container.GetBlockBlobReference(path));
}
public IEnumerable<IStorageFile> ListFiles(string path) {
EnsurePathIsRelative(path);
string prefix = String.Concat(Container.Name, "/", _shellName, "/", path);
if ( !prefix.EndsWith("/") )
prefix += "/";
foreach ( var blobItem in BlobClient.ListBlobsWithPrefix(prefix).OfType<CloudBlockBlob>() ) {
yield return new AzureBlobFileStorage(blobItem);
}
}
public IEnumerable<IStorageFolder> ListFolders(string path) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
if ( !Container.DirectoryExists(path) ) {
try {
CreateFolder(path);
}
catch ( Exception ex ) {
throw new ArgumentException(string.Format("The folder could not be created at path: {0}. {1}", path, ex));
}
}
return Container.GetDirectoryReference(path)
.ListBlobs()
.OfType<CloudBlobDirectory>()
.Select<CloudBlobDirectory, IStorageFolder>(d => new AzureBlobFolderStorage(d))
.ToList();
}
public void CreateFolder(string path) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
Container.EnsureDirectoryDoesNotExist(path);
Container.GetDirectoryReference(path);
}
public void DeleteFolder(string path) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
Container.EnsureDirectoryExists(path);
foreach ( var blob in Container.GetDirectoryReference(path).ListBlobs() ) {
if ( blob is CloudBlob )
( (CloudBlob)blob ).Delete();
if ( blob is CloudBlobDirectory )
DeleteFolder(blob.Uri.ToString().Substring(Container.Uri.ToString().Length + 2 + _shellName.Length));
}
}
public void RenameFolder(string path, string newPath) {
EnsurePathIsRelative(path);
EnsurePathIsRelative(newPath);
if ( !path.EndsWith("/") )
path += "/";
if ( !newPath.EndsWith("/") )
newPath += "/";
foreach ( var blob in Container.GetDirectoryReference(_shellName + "/" + path).ListBlobs() ) {
if ( blob is CloudBlob ) {
string filename = Path.GetFileName(blob.Uri.ToString());
string source = String.Concat(path, filename);
string destination = String.Concat(newPath, filename);
RenameFile(source, destination);
}
if ( blob is CloudBlobDirectory ) {
string foldername = blob.Uri.Segments.Last();
string source = String.Concat(path, foldername);
string destination = String.Concat(newPath, foldername);
RenameFolder(source, destination);
}
}
}
public void DeleteFile(string path) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
Container.EnsureBlobExists(path);
var blob = Container.GetBlockBlobReference(path);
blob.Delete();
}
public void RenameFile(string path, string newPath) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
EnsurePathIsRelative(newPath);
newPath = String.Concat(_shellName, "/", newPath);
Container.EnsureBlobExists(path);
Container.EnsureBlobDoesNotExist(newPath);
var blob = Container.GetBlockBlobReference(path);
var newBlob = Container.GetBlockBlobReference(newPath);
newBlob.CopyFromBlob(blob);
blob.Delete();
}
public IStorageFile CreateFile(string path) {
EnsurePathIsRelative(path);
path = String.Concat(_shellName, "/", path);
if ( Container.BlobExists(path) ) {
throw new ArgumentException("File " + path + " already exists");
}
var blob = Container.GetBlockBlobReference(path);
blob.OpenWrite().Dispose(); // force file creation
return new AzureBlobFileStorage(blob);
}
private class AzureBlobFileStorage : IStorageFile {
private readonly CloudBlockBlob _blob;
public AzureBlobFileStorage(CloudBlockBlob blob) {
_blob = blob;
}
public string GetPath() {
return _blob.Uri.ToString();
}
public string GetName() {
return Path.GetFileName(GetPath());
}
public long GetSize() {
return _blob.Properties.Length;
}
public DateTime GetLastUpdated() {
return _blob.Properties.LastModifiedUtc;
}
public string GetFileType() {
return Path.GetExtension(GetPath());
}
public Stream OpenRead() {
return _blob.OpenRead();
}
public Stream OpenWrite() {
return _blob.OpenWrite();
}
}
private class AzureBlobFolderStorage : IStorageFolder {
private readonly CloudBlobDirectory _blob;
public AzureBlobFolderStorage(CloudBlobDirectory blob) {
_blob = blob;
}
public string GetName() {
return _blob.Uri.ToString();
}
public long GetSize() {
return GetDirectorySize(_blob);
}
public DateTime GetLastUpdated() {
return DateTime.MinValue;
}
public IStorageFolder GetParent() {
if ( _blob.Parent != null ) {
return new AzureBlobFolderStorage(_blob.Parent);
}
throw new ArgumentException("Directory " + _blob.Uri + " does not have a parent directory");
}
private static long GetDirectorySize(CloudBlobDirectory directoryBlob) {
long size = 0;
foreach ( var blobItem in directoryBlob.ListBlobs() ) {
if ( blobItem is CloudBlob )
size += ( (CloudBlob)blobItem ).Properties.Length;
if ( blobItem is CloudBlobDirectory )
size += GetDirectorySize((CloudBlobDirectory)blobItem);
}
return size;
}
}
public AzureBlobStorageProvider(string shellName, CloudStorageAccount storageAccount) : base("media", shellName, false, storageAccount) { }
}
}