mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
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:
@@ -7,6 +7,7 @@ glob:*.user
|
|||||||
glob:*.patch
|
glob:*.patch
|
||||||
glob:*.hg
|
glob:*.hg
|
||||||
glob:build
|
glob:build
|
||||||
|
glob:artifacts
|
||||||
glob:*.sln.cache
|
glob:*.sln.cache
|
||||||
glob:src/Orchard.Web/Media/*
|
glob:src/Orchard.Web/Media/*
|
||||||
glob:desktop.ini
|
glob:desktop.ini
|
||||||
|
137
AzurePackage.proj
Normal file
137
AzurePackage.proj
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
|
<!-- Initialization -->
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<LibFolder>$(MSBuildProjectDirectory)\lib</LibFolder>
|
||||||
|
<SrcFolder>$(MSBuildProjectDirectory)\src</SrcFolder>
|
||||||
|
<BuildFolder>$(MSBuildProjectDirectory)\build</BuildFolder>
|
||||||
|
<ArtifactsFolder>$(MSBuildProjectDirectory)\artifacts\Azure</ArtifactsFolder>
|
||||||
|
|
||||||
|
<CompileFolder>$(BuildFolder)\Compile</CompileFolder>
|
||||||
|
<ServiceFolder>$(CompileFolder)\Orchard.Azure.CloudService.csx</ServiceFolder>
|
||||||
|
<CloudRootFolder>$(ServiceFolder)\roles\Orchard.Azure.Web\approot</CloudRootFolder>
|
||||||
|
<WebSitesFolder>$(CompileFolder)\_PublishedWebsites</WebSitesFolder>
|
||||||
|
<StageFolder>$(BuildFolder)\Stage</StageFolder>
|
||||||
|
|
||||||
|
<BuildPlatform Condition="$(ProgramW6432) != ''">x64</BuildPlatform>
|
||||||
|
<BuildPlatform Condition="$(BuildPlatform) == ''">x86</BuildPlatform>
|
||||||
|
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(LibFolder)\msbuild\MSBuild.Community.Tasks.Targets"/>
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\Cloud Service\v1.0\Microsoft.CloudService.targets" />
|
||||||
|
|
||||||
|
<!-- Coordinating Targets -->
|
||||||
|
|
||||||
|
<Target Name ="Build">
|
||||||
|
<CallTarget Targets="Clean"/>
|
||||||
|
<CallTarget Targets="Compile"/>
|
||||||
|
<CallTarget Targets="Test"/>
|
||||||
|
<CallTarget Targets="Package"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="Package">
|
||||||
|
<CallTarget Targets="Package-Stage"/>
|
||||||
|
<CallTarget Targets="Package-Zip"/>
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Building -->
|
||||||
|
|
||||||
|
<Target Name="Clean">
|
||||||
|
<MSBuild Projects="$(SrcFolder)\Orchard.sln" Targets="Clean" />
|
||||||
|
<MSBuild Projects="$(SrcFolder)\Orchard.Azure\Orchard.Azure.CloudService.sln" Targets="Clean" />
|
||||||
|
<RemoveDir Directories="$(BuildFolder)" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name ="Compile">
|
||||||
|
<MSBuild
|
||||||
|
Projects="$(SrcFolder)\Orchard.Azure\Orchard.Azure.CloudService.sln"
|
||||||
|
Targets="Build"
|
||||||
|
Properties="Configuration=Release;OutputPath=$(CompileFolder)" />
|
||||||
|
|
||||||
|
<MSBuild
|
||||||
|
Projects="$(SrcFolder)\Orchard.Azure.sln"
|
||||||
|
Targets="Build"
|
||||||
|
Properties="Configuration=Release;OutputPath=$(CompileFolder)" />
|
||||||
|
|
||||||
|
<MSBuild
|
||||||
|
Projects="$(SrcFolder)\Orchard.sln"
|
||||||
|
Targets="Build"
|
||||||
|
Properties="Configuration=Release;OutputPath=$(CompileFolder)" />
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Testing - Azure only -->
|
||||||
|
|
||||||
|
<Target Name ="Test">
|
||||||
|
<Message Text="Testing with x64 version of Sqlite"/>
|
||||||
|
|
||||||
|
<CreateItem Include="$(CompileFolder)\*Azure.Tests.*dll">
|
||||||
|
<Output TaskParameter="Include" ItemName="TestAssemblies" />
|
||||||
|
</CreateItem>
|
||||||
|
|
||||||
|
<!-- use x64 sqlite for tests depending on build platform -->
|
||||||
|
<Copy
|
||||||
|
SourceFiles="$(LibFolder)\sqlite\x64\System.Data.SQLite.dll"
|
||||||
|
DestinationFiles="$(CompileFolder)\System.Data.SQLite.dll" />
|
||||||
|
|
||||||
|
<NUnit Assemblies="@(TestAssemblies)" ToolPath="$(LibFolder)\nunit" WorkingDirectory="$(CompileFolder)" />
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name ="Spec">
|
||||||
|
<CreateItem Include="$(CompileFolder)\*.Specs.dll">
|
||||||
|
<Output TaskParameter="Include" ItemName="SpecAssemblies" />
|
||||||
|
</CreateItem>
|
||||||
|
<NUnit Assemblies="@(SpecAssemblies)" ToolPath="$(LibFolder)\nunit" />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<!-- Packaging -->
|
||||||
|
|
||||||
|
<Target Name="Package-Stage">
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Stage-Bin-Exclude Include="$(WebSitesFolder)\**\bin\**\*" />
|
||||||
|
<Stage-Orchard-Web-Exclude Include="$(WebSitesFolder)\**\Orchard.Web\**\*" />
|
||||||
|
|
||||||
|
<Stage-Themes Include="$(WebSitesFolder)\Orchard.Web\Themes\**\*" />
|
||||||
|
<Stage-Core Include="$(WebSitesFolder)\Orchard.Core\**\*" Exclude="@(Stage-Bin-Exclude)" />
|
||||||
|
<Stage-Modules Include="$(WebSitesFolder)\**\*" Exclude="@(Stage-Core);@(Stage-Bin-Exclude);@(Stage-Orchard-Web-Exclude)" />
|
||||||
|
<Stage-Modules-Bin Include="$(WebSitesFolder)\Orchard.Web\**\bin\*"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<Copy SourceFiles="@(Stage-Themes)" DestinationFolder="$(CloudRootFolder)\Themes\%(RecursiveDir)" />
|
||||||
|
<Copy SourceFiles="@(Stage-Core)" DestinationFolder="$(CloudRootFolder)\Core\%(RecursiveDir)" />
|
||||||
|
<Copy SourceFiles="@(Stage-Modules)" DestinationFolder="$(CloudRootFolder)\Modules\%(RecursiveDir)" />
|
||||||
|
<Copy SourceFiles="@(Stage-Modules-Bin)" DestinationFolder="$(CloudRootFolder)\bin\" />
|
||||||
|
|
||||||
|
<!-- use x64 sqlite for tests depending on build platform -->
|
||||||
|
<Copy
|
||||||
|
SourceFiles="$(LibFolder)\sqlite\x64\System.Data.SQLite.dll"
|
||||||
|
DestinationFiles="$(CloudRootFolder)\bin\System.Data.SQLite.dll" />
|
||||||
|
|
||||||
|
<Copy
|
||||||
|
SourceFiles="$(SrcFolder)\Orchard.Azure\Orchard.Azure.CloudService\ServiceConfiguration.cscfg"
|
||||||
|
DestinationFolder="$(StageFolder)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Exec
|
||||||
|
Command=""$(ServiceHostingSDKBinDir)cspack" "$(ServiceFolder)\ServiceDefinition.csdef" /role:Orchard.Azure.Web;"$(CloudRootFolder)";Orchard.Azure.Web.dll /out:"$(StageFolder)\Orchard.cspkg""
|
||||||
|
WorkingDirectory="$(CloudRootFolder)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
<Target Name="Package-Zip">
|
||||||
|
<ItemGroup>
|
||||||
|
<Zip-Stage Include="$(StageFolder)\ServiceConfiguration.cscfg;$(StageFolder)\Orchard.cspkg" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<MakeDir Directories="$(ArtifactsFolder)" />
|
||||||
|
<Zip Files="@(Zip-Stage)" WorkingDirectory="$(StageFolder)" ZipFileName="$(ArtifactsFolder)\AzurePackage.zip" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
@@ -1,2 +1,3 @@
|
|||||||
if "%~1"=="" build Build
|
if "%~1"=="" build Build
|
||||||
msbuild /t:%~1
|
msbuild /t:%~1 Orchard.proj
|
||||||
|
msbuild /t:%~1 AzurePackage.proj
|
||||||
|
@@ -24,6 +24,12 @@ namespace Orchard.Azure.Tests.Environment.Configuration {
|
|||||||
DeleteAllBlobs( ((AzureShellSettingsManager)Loader).Container);
|
DeleteAllBlobs( ((AzureShellSettingsManager)Loader).Container);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() {
|
||||||
|
// ensure default container is empty after running tests
|
||||||
|
DeleteAllBlobs(( (AzureShellSettingsManager)Loader ).Container);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void SingleSettingsFileShouldComeBackAsExpected() {
|
public void SingleSettingsFileShouldComeBackAsExpected() {
|
||||||
|
|
||||||
|
@@ -1,13 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Configuration;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using System.Diagnostics;
|
|
||||||
using Orchard.Azure.Storage;
|
using Orchard.Azure.Storage;
|
||||||
using Microsoft.WindowsAzure;
|
using Microsoft.WindowsAzure;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.WindowsAzure.StorageClient;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Orchard.Azure.Tests.Storage {
|
namespace Orchard.Azure.Tests.Storage {
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
|
271
src/Orchard.Azure/AzureFileSystem.cs
Normal file
271
src/Orchard.Azure/AzureFileSystem.cs
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Microsoft.WindowsAzure;
|
||||||
|
using Microsoft.WindowsAzure.StorageClient;
|
||||||
|
using System.IO;
|
||||||
|
using Orchard.Storage;
|
||||||
|
|
||||||
|
namespace Orchard.Azure {
|
||||||
|
public class AzureFileSystem {
|
||||||
|
public string ContainerName { get; protected set; }
|
||||||
|
|
||||||
|
private readonly CloudStorageAccount _storageAccount;
|
||||||
|
private readonly string _shellName;
|
||||||
|
public CloudBlobClient BlobClient { get; private set; }
|
||||||
|
public CloudBlobContainer Container { get; private set; }
|
||||||
|
|
||||||
|
public AzureFileSystem(string containerName, string shellName, bool isPrivate)
|
||||||
|
: this(containerName, shellName, isPrivate, CloudStorageAccount.FromConfigurationSetting("DataConnectionString")) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AzureFileSystem(string containerName, string shellName, bool isPrivate, CloudStorageAccount storageAccount) {
|
||||||
|
// Setup the connection to custom storage accountm, e.g. Development Storage
|
||||||
|
_storageAccount = storageAccount;
|
||||||
|
ContainerName = containerName;
|
||||||
|
_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();
|
||||||
|
|
||||||
|
if ( isPrivate ) {
|
||||||
|
Container.SetPermissions(new BlobContainerPermissions
|
||||||
|
{PublicAccess = BlobContainerPublicAccessType.Off});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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);
|
||||||
|
path = String.Concat(_shellName, "/", path);
|
||||||
|
Container.EnsureBlobExists(path);
|
||||||
|
return new AzureBlobFileStorage(Container.GetBlockBlobReference(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FileExists(string path) {
|
||||||
|
path = String.Concat(_shellName, "/", path);
|
||||||
|
return Container.BlobExists(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetPublicUrl(string path) {
|
||||||
|
EnsurePathIsRelative(path);
|
||||||
|
path = String.Concat(_shellName, "/", path);
|
||||||
|
Container.EnsureBlobExists(path);
|
||||||
|
return Container.GetBlockBlobReference(path).Uri.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
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 Path.GetDirectoryName(_blob.Uri.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetPath() {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Orchard.Environment.Configuration;
|
||||||
|
|
||||||
|
namespace Orchard.Azure.Environment.Configuration {
|
||||||
|
public class AzureAppDataFolder : IAppDataFolder {
|
||||||
|
|
||||||
|
private readonly AzureFileSystem _fs;
|
||||||
|
|
||||||
|
public AzureAppDataFolder(string shellName) {
|
||||||
|
_fs = new AzureFileSystem("appdata", shellName, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CreateFile(string path, string content) {
|
||||||
|
if(_fs.FileExists(path)) {
|
||||||
|
DeleteFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
using (var stream = _fs.CreateFile(path).OpenWrite()) {
|
||||||
|
using(var writer = new StreamWriter(stream)) {
|
||||||
|
writer.Write(content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReadFile(string path) {
|
||||||
|
using ( var stream = _fs.GetFile(path).OpenRead() ) {
|
||||||
|
using ( var reader = new StreamReader(stream) ) {
|
||||||
|
return reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteFile(string path) {
|
||||||
|
_fs.DeleteFile(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool FileExists(string path) {
|
||||||
|
return _fs.FileExists(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> ListFiles(string path) {
|
||||||
|
return _fs.ListFiles(path).Select(sf => sf.GetPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> ListDirectories(string path) {
|
||||||
|
return _fs.ListFolders(path).Select(sf => sf.GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CreateDirectory(string path) {
|
||||||
|
_fs.CreateFolder(path);
|
||||||
|
return Path.GetDirectoryName(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetBasePath(string basePath) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string MapPath(string path) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
src/Orchard.Azure/Orchard.Azure.CloudService.sln
Normal file
38
src/Orchard.Azure/Orchard.Azure.CloudService.sln
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{CC5FD16D-436D-48AD-A40C-5A424C6E3E79}") = "Orchard.Azure.CloudService", "Orchard.Azure.CloudService\Orchard.Azure.CloudService.ccproj", "{03C5327D-4E8E-45A7-ACD1-E18E7CAA3C4A}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Azure.Web", "Orchard.Azure.Web\Orchard.Azure.Web.csproj", "{0DF8F426-9F30-4918-8F64-A5B40BA12D10}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Azure", "Orchard.Azure.csproj", "{2505AA84-65A6-43D0-9C27-4F44FD576284}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Orchard.Framework", "..\Orchard\Orchard.Framework.csproj", "{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{03C5327D-4E8E-45A7-ACD1-E18E7CAA3C4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{03C5327D-4E8E-45A7-ACD1-E18E7CAA3C4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{03C5327D-4E8E-45A7-ACD1-E18E7CAA3C4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{03C5327D-4E8E-45A7-ACD1-E18E7CAA3C4A}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0DF8F426-9F30-4918-8F64-A5B40BA12D10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0DF8F426-9F30-4918-8F64-A5B40BA12D10}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0DF8F426-9F30-4918-8F64-A5B40BA12D10}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0DF8F426-9F30-4918-8F64-A5B40BA12D10}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2505AA84-65A6-43D0-9C27-4F44FD576284}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2505AA84-65A6-43D0-9C27-4F44FD576284}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2505AA84-65A6-43D0-9C27-4F44FD576284}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2505AA84-65A6-43D0-9C27-4F44FD576284}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{2D1D92BB-4555-4CBE-8D0E-63563D6CE4C6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>1.0.0</ProductVersion>
|
||||||
|
<ProjectGuid>{03c5327d-4e8e-45a7-acd1-e18e7caa3c4a}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Orchard.Azure.CloudService</RootNamespace>
|
||||||
|
<AssemblyName>Orchard.Azure.CloudService</AssemblyName>
|
||||||
|
<StartDevelopmentStorage>True</StartDevelopmentStorage>
|
||||||
|
<Name>OrchardCloudService</Name>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<!-- Items for the project -->
|
||||||
|
<ItemGroup>
|
||||||
|
<ServiceDefinition Include="ServiceDefinition.csdef" />
|
||||||
|
<ServiceConfiguration Include="ServiceConfiguration.cscfg" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Orchard.Azure.Web\Orchard.Azure.Web.csproj">
|
||||||
|
<Name>Orchard.Azure.Web</Name>
|
||||||
|
<Project>{0df8f426-9f30-4918-8f64-a5b40ba12d10}</Project>
|
||||||
|
<Private>True</Private>
|
||||||
|
<RoleType>Web</RoleType>
|
||||||
|
<RoleName>Orchard.Azure.Web</RoleName>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<!-- Import the target files for this project template -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<CloudExtensionsDir Condition=" '$(CloudExtensionsDir)' == '' ">$(MSBuildExtensionsPath)\Microsoft\Cloud Service\v1.0\</CloudExtensionsDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(CloudExtensionsDir)Microsoft.CloudService.targets" />
|
||||||
|
</Project>
|
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ServiceConfiguration serviceName="OrchardCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
|
||||||
|
<Role name="Orchard.Azure.Web">
|
||||||
|
<Instances count="1" />
|
||||||
|
<ConfigurationSettings>
|
||||||
|
<!-- Development Settings -->
|
||||||
|
<Setting name="DiagnosticsConnectionString" value="UseDevelopmentStorage=true" />
|
||||||
|
<Setting name="DataConnectionString" value="UseDevelopmentStorage=true" />
|
||||||
|
|
||||||
|
<!-- Cloud Settings -->
|
||||||
|
<!--
|
||||||
|
<Setting name="DiagnosticsConnectionString" value="DefaultEndpointsProtocol=https; AccountName=ACCOUNT; AccountKey=KEY" />
|
||||||
|
<Setting name="DataConnectionString" value="DefaultEndpointsProtocol=https; AccountName=ACCOUNT; AccountKey=KEY" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
</ConfigurationSettings>
|
||||||
|
</Role>
|
||||||
|
</ServiceConfiguration>
|
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ServiceDefinition name="OrchardCloudService" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
|
||||||
|
<WebRole name="Orchard.Azure.Web">
|
||||||
|
<InputEndpoints>
|
||||||
|
<InputEndpoint name="HttpIn" protocol="http" port="80" />
|
||||||
|
</InputEndpoints>
|
||||||
|
<ConfigurationSettings>
|
||||||
|
<Setting name="DiagnosticsConnectionString" />
|
||||||
|
<Setting name="DataConnectionString" />
|
||||||
|
</ConfigurationSettings>
|
||||||
|
</WebRole>
|
||||||
|
</ServiceDefinition>
|
@@ -0,0 +1,27 @@
|
|||||||
|
<system.diagnostics>
|
||||||
|
<trace autoflush="true"/>
|
||||||
|
<sources>
|
||||||
|
<source name="Default" switchValue="Verbose">
|
||||||
|
<listeners>
|
||||||
|
<add name="OrchardDebugTextLog" />
|
||||||
|
<add name="WebPageTrace"/>
|
||||||
|
</listeners>
|
||||||
|
</source>
|
||||||
|
<source name="Orchard.Localization" switchValue="Warning">
|
||||||
|
<listeners>
|
||||||
|
<add name="OrchardDebugTextLog" />
|
||||||
|
<add name="WebPageTrace"/>
|
||||||
|
</listeners>
|
||||||
|
</source>
|
||||||
|
<source name="Orchard.Data.SessionLocator" switchValue="Information">
|
||||||
|
<listeners>
|
||||||
|
<add name="OrchardDebugTextLog" />
|
||||||
|
<add name="WebPageTrace"/>
|
||||||
|
</listeners>
|
||||||
|
</source>
|
||||||
|
</sources>
|
||||||
|
<sharedListeners>
|
||||||
|
<add name="OrchardDebugTextLog" type="System.Diagnostics.TextWriterTraceListener" initializeData="c:\logs\orchard-debug.txt" />
|
||||||
|
<add name="WebPageTrace" type="System.Web.WebPageTraceListener, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||||
|
</sharedListeners>
|
||||||
|
</system.diagnostics>
|
37
src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config
Normal file
37
src/Orchard.Azure/Orchard.Azure.Web/Config/Host.config
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
|
||||||
|
<configSections>
|
||||||
|
<section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/>
|
||||||
|
</configSections>
|
||||||
|
|
||||||
|
<autofac defaultAssembly="Orchard.Framework">
|
||||||
|
<components>
|
||||||
|
|
||||||
|
<component instance-scope="single-instance"
|
||||||
|
type="Orchard.Azure.Environment.Configuration.AzureShellSettingsManager, Orchard.Azure"
|
||||||
|
service="Orchard.Environment.Configuration.IShellSettingsManager">
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component instance-scope="single-instance"
|
||||||
|
type="Orchard.Azure.Storage.AzureBlobStorageProvider, Orchard.Azure"
|
||||||
|
service="Orchard.Storage.IStorageProvider">
|
||||||
|
<parameters>
|
||||||
|
<parameter name="shellName" value="Default" />
|
||||||
|
</parameters>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component instance-scope="single-instance"
|
||||||
|
type="Orchard.Azure.Environment.Configuration.AzureAppDataFolder, Orchard.Azure"
|
||||||
|
service="Orchard.Environment.Configuration.IAppDataFolder">
|
||||||
|
<parameters>
|
||||||
|
<parameter name="shellName" value="Default" />
|
||||||
|
</parameters>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
|
||||||
|
</components>
|
||||||
|
</autofac>
|
||||||
|
|
||||||
|
</configuration>
|
||||||
|
|
1
src/Orchard.Azure/Orchard.Azure.Web/Global.asax
Normal file
1
src/Orchard.Azure/Orchard.Azure.Web/Global.asax
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<%@ Application Codebehind="Global.asax.cs" Inherits="Orchard.Azure.Web.MvcApplication" Language="C#" %>
|
104
src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs
Normal file
104
src/Orchard.Azure/Orchard.Azure.Web/Global.asax.cs
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Web;
|
||||||
|
using System.Web.Mvc;
|
||||||
|
using System.Web.Routing;
|
||||||
|
using Autofac;
|
||||||
|
using Orchard.Environment;
|
||||||
|
|
||||||
|
namespace Orchard.Azure.Web {
|
||||||
|
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
|
||||||
|
// visit http://go.microsoft.com/?LinkId=9394801
|
||||||
|
|
||||||
|
public class MvcApplication : HttpApplication {
|
||||||
|
private static IOrchardHost _host;
|
||||||
|
|
||||||
|
public static void RegisterRoutes(RouteCollection routes) {
|
||||||
|
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Application_Start() {
|
||||||
|
// This is temporary until MVC2 is officially released.
|
||||||
|
// We want to avoid running against an outdated preview installed in the GAC
|
||||||
|
CheckMvcVersion(
|
||||||
|
new Version("2.0.50217.0")/*MVC2 RTM file version #*/,
|
||||||
|
new Version("2.0.50129.0")/*MVC2 RC2 file version #*/,
|
||||||
|
new Version("2.0.41211.0")/*MVC2 RC file version #*/);
|
||||||
|
|
||||||
|
RegisterRoutes(RouteTable.Routes);
|
||||||
|
|
||||||
|
_host = OrchardStarter.CreateHost(MvcSingletons);
|
||||||
|
_host.Initialize();
|
||||||
|
|
||||||
|
//TODO: what's the failed initialization story - IoC failure in app start can leave you with a zombie appdomain
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Application_BeginRequest() {
|
||||||
|
Context.Items["originalHttpContext"] = Context;
|
||||||
|
|
||||||
|
_host.BeginRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void Application_EndRequest() {
|
||||||
|
_host.EndRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CheckMvcVersion(params Version[] allowedVersions) {
|
||||||
|
Assembly loadedMvcAssembly = typeof(System.Web.Mvc.Controller).Assembly;
|
||||||
|
Version loadedMvcVersion = ReadAssemblyFileVersion(loadedMvcAssembly);
|
||||||
|
|
||||||
|
if ( allowedVersions.All(allowed => loadedMvcVersion != allowed) ) {
|
||||||
|
string message;
|
||||||
|
if ( loadedMvcAssembly.GlobalAssemblyCache ) {
|
||||||
|
message = string.Format(
|
||||||
|
"Orchard has been deployed with a version of {0} that has a different file version ({1}) " +
|
||||||
|
"than the version installed in the GAC ({2}).\r\n" +
|
||||||
|
"This implies that Orchard will not be able to run properly in this machine configuration.\r\n" +
|
||||||
|
"Please un-install MVC from the GAC or install a more recent version.",
|
||||||
|
loadedMvcAssembly.GetName().Name,
|
||||||
|
allowedVersions.First(),
|
||||||
|
loadedMvcVersion);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
message = string.Format(
|
||||||
|
"Orchard has been configured to run with a file version {1} of \"{0}\" " +
|
||||||
|
"but the version deployed with the application is {2}.\r\n" +
|
||||||
|
"This probably implies that Orchard is deployed with a newer version " +
|
||||||
|
"and the source code hasn't been updated accordingly.\r\n" +
|
||||||
|
"Update the Orchard.Web application source code (look for \"CheckMvcVersion\") to " +
|
||||||
|
"specify the correct file version number.\r\n",
|
||||||
|
loadedMvcAssembly.GetName().Name,
|
||||||
|
allowedVersions.First(),
|
||||||
|
loadedMvcVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new HttpException(500, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Version ReadAssemblyFileVersion(Assembly assembly) {
|
||||||
|
object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyFileVersionAttribute), true);
|
||||||
|
if ( attributes == null || attributes.Length != 1 ) {
|
||||||
|
string message = string.Format("Assembly \"{0}\" doesn't have a \"{1}\" attribute",
|
||||||
|
assembly.GetName().Name, typeof(AssemblyFileVersionAttribute).FullName);
|
||||||
|
throw new FileLoadException(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var attribute = (AssemblyFileVersionAttribute)attributes[0];
|
||||||
|
return new Version(attribute.Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void MvcSingletons(ContainerBuilder builder) {
|
||||||
|
builder.RegisterInstance(ControllerBuilder.Current);
|
||||||
|
builder.RegisterInstance(RouteTable.Routes);
|
||||||
|
builder.RegisterInstance(ModelBinders.Binders);
|
||||||
|
builder.RegisterInstance(ModelMetadataProviders.Current);
|
||||||
|
builder.RegisterInstance(ViewEngines.Engines);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
157
src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
Normal file
157
src/Orchard.Azure/Orchard.Azure.Web/Orchard.Azure.Web.csproj
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>9.0.30729</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{0DF8F426-9F30-4918-8F64-A5B40BA12D10}</ProjectGuid>
|
||||||
|
<ProjectTypeGuids>{F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Orchard.Azure.Web</RootNamespace>
|
||||||
|
<AssemblyName>Orchard.Azure.Web</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||||
|
<MvcBuildViews>false</MvcBuildViews>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Autofac, Version=2.1.13.813, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\lib\autofac\Autofac.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Autofac.Configuration, Version=2.1.13.813, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\lib\autofac\Autofac.Configuration.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Autofac.Integration.Web, Version=2.1.13.813, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\lib\autofac\Autofac.Integration.Web.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Autofac.Integration.Web.Mvc, Version=2.1.13.813, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\lib\autofac\Autofac.Integration.Web.Mvc.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Castle.Core, Version=1.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\lib\Castle Windsor 2.0\bin\Castle.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Castle.DynamicProxy2, Version=2.1.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\lib\Castle Windsor 2.0\bin\Castle.DynamicProxy2.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.WindowsAzure.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.WindowsAzure.ServiceRuntime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="Microsoft.WindowsAzure.StorageClient, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="NHibernate.ByteCode.Castle, Version=2.1.2.4000, Culture=neutral, PublicKeyToken=aa95f207798dfdb4, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\lib\fluentnhibernate\NHibernate.ByteCode.Castle.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Core">
|
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data.DataSetExtensions">
|
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data.SQLite, Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\lib\sqlite\x64\System.Data.SQLite.DLL</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>..\..\..\..\..\..\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 2\\Assemblies\System.Web.Mvc.dll</HintPath>
|
||||||
|
<Private>True</Private>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Xml.Linq">
|
||||||
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Web" />
|
||||||
|
<Reference Include="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
|
<Reference Include="System.Web.Abstractions" />
|
||||||
|
<Reference Include="System.Web.Routing" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
|
<Reference Include="System.Web.Services" />
|
||||||
|
<Reference Include="System.EnterpriseServices" />
|
||||||
|
<Reference Include="System.Web.Mobile" />
|
||||||
|
<Reference Include="Orchard.Framework">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>bin\Orchard.Framework.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Orchard.Azure">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>bin\Orchard.Azure.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Global.asax.cs">
|
||||||
|
<DependentUpon>Global.asax</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="WebRole.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Global.asax" />
|
||||||
|
<Content Include="Web.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Config\Diagnostics.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Config\Host.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="App_Data\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target> -->
|
||||||
|
<Target Name="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
|
||||||
|
<AspNetCompiler VirtualPath="temp" PhysicalPath="$(ProjectDir)" />
|
||||||
|
</Target>
|
||||||
|
<ProjectExtensions>
|
||||||
|
<VisualStudio>
|
||||||
|
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||||
|
<WebProjectProperties>
|
||||||
|
<UseIIS>False</UseIIS>
|
||||||
|
<AutoAssignPort>True</AutoAssignPort>
|
||||||
|
<DevelopmentServerPort>60453</DevelopmentServerPort>
|
||||||
|
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||||
|
<IISUrl>
|
||||||
|
</IISUrl>
|
||||||
|
<NTLMAuthentication>False</NTLMAuthentication>
|
||||||
|
<UseCustomServer>False</UseCustomServer>
|
||||||
|
<CustomServerUrl>
|
||||||
|
</CustomServerUrl>
|
||||||
|
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||||
|
</WebProjectProperties>
|
||||||
|
</FlavorProperties>
|
||||||
|
</VisualStudio>
|
||||||
|
</ProjectExtensions>
|
||||||
|
</Project>
|
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("Orchard.Azure.Web")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("Microsoft")]
|
||||||
|
[assembly: AssemblyProduct("Orchard.Azure.Web")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("76077e05-d95f-49c7-b11a-2b0fc9176e7c")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
158
src/Orchard.Azure/Orchard.Azure.Web/Web.config
Normal file
158
src/Orchard.Azure/Orchard.Azure.Web/Web.config
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
Note: As an alternative to hand editing this file you can use the
|
||||||
|
web admin tool to configure settings for your application. Use
|
||||||
|
the Website->Asp.Net Configuration option in Visual Studio.
|
||||||
|
A full list of settings and comments can be found in
|
||||||
|
machine.config.comments usually located in
|
||||||
|
\Windows\Microsoft.Net\Framework\v2.x\Config
|
||||||
|
-->
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||||
|
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||||
|
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||||
|
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
|
||||||
|
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
|
||||||
|
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||||
|
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||||
|
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
|
||||||
|
</sectionGroup>
|
||||||
|
</sectionGroup>
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<appSettings/>
|
||||||
|
<connectionStrings>
|
||||||
|
<add name="ApplicationServices" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient"/>
|
||||||
|
</connectionStrings>
|
||||||
|
<system.web>
|
||||||
|
<!--
|
||||||
|
Set compilation debug="true" to insert debugging
|
||||||
|
symbols into the compiled page. Because this
|
||||||
|
affects performance, set this value to true only
|
||||||
|
during development.
|
||||||
|
-->
|
||||||
|
<compilation debug="true">
|
||||||
|
<assemblies>
|
||||||
|
<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||||
|
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add assembly="System.Web.Abstractions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add assembly="System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add assembly="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||||
|
<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||||
|
<add assembly="System.Data.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||||
|
</assemblies>
|
||||||
|
</compilation>
|
||||||
|
<!--
|
||||||
|
The <authentication> section enables configuration
|
||||||
|
of the security authentication mode used by
|
||||||
|
ASP.NET to identify an incoming user.
|
||||||
|
-->
|
||||||
|
<authentication mode="Forms">
|
||||||
|
<forms loginUrl="~/Account/LogOn" timeout="2880"/>
|
||||||
|
</authentication>
|
||||||
|
<membership>
|
||||||
|
<providers>
|
||||||
|
<clear/>
|
||||||
|
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" passwordFormat="Hashed" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" passwordStrengthRegularExpression="" applicationName="/"/>
|
||||||
|
</providers>
|
||||||
|
</membership>
|
||||||
|
<profile>
|
||||||
|
<providers>
|
||||||
|
<clear/>
|
||||||
|
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ApplicationServices" applicationName="/"/>
|
||||||
|
</providers>
|
||||||
|
</profile>
|
||||||
|
<roleManager enabled="false">
|
||||||
|
<providers>
|
||||||
|
<clear/>
|
||||||
|
<add connectionStringName="ApplicationServices" applicationName="/" name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||||
|
<add applicationName="/" name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||||
|
</providers>
|
||||||
|
</roleManager>
|
||||||
|
<!--
|
||||||
|
The <customErrors> section enables configuration
|
||||||
|
of what to do if/when an unhandled error occurs
|
||||||
|
during the execution of a request. Specifically,
|
||||||
|
it enables developers to configure html error pages
|
||||||
|
to be displayed in place of a error stack trace.
|
||||||
|
|
||||||
|
<customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
|
||||||
|
<error statusCode="403" redirect="NoAccess.htm" />
|
||||||
|
<error statusCode="404" redirect="FileNotFound.htm" />
|
||||||
|
</customErrors>
|
||||||
|
-->
|
||||||
|
<pages>
|
||||||
|
<controls>
|
||||||
|
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
</controls>
|
||||||
|
<namespaces>
|
||||||
|
<add namespace="System.Web.Mvc"/>
|
||||||
|
<add namespace="System.Web.Mvc.Ajax"/>
|
||||||
|
<add namespace="System.Web.Mvc.Html"/>
|
||||||
|
<add namespace="System.Web.Routing"/>
|
||||||
|
<add namespace="System.Linq"/>
|
||||||
|
<add namespace="System.Collections.Generic"/>
|
||||||
|
<add namespace="Orchard.Mvc.Html" />
|
||||||
|
</namespaces>
|
||||||
|
</pages>
|
||||||
|
<httpHandlers>
|
||||||
|
<remove verb="*" path="*.asmx"/>
|
||||||
|
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
|
||||||
|
</httpHandlers>
|
||||||
|
<httpModules>
|
||||||
|
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
</httpModules>
|
||||||
|
</system.web>
|
||||||
|
<system.codedom>
|
||||||
|
<compilers>
|
||||||
|
<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<providerOption name="CompilerVersion" value="v3.5"/>
|
||||||
|
<providerOption name="WarnAsError" value="false"/>
|
||||||
|
</compiler>
|
||||||
|
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" warningLevel="4" type="Microsoft.VisualBasic.VBCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<providerOption name="CompilerVersion" value="v3.5"/>
|
||||||
|
<providerOption name="OptionInfer" value="true"/>
|
||||||
|
<providerOption name="WarnAsError" value="false"/>
|
||||||
|
</compiler>
|
||||||
|
</compilers>
|
||||||
|
</system.codedom>
|
||||||
|
<system.web.extensions/>
|
||||||
|
<!--
|
||||||
|
The system.webServer section is required for running ASP.NET AJAX under Internet
|
||||||
|
Information Services 7.0. It is not necessary for previous version of IIS.
|
||||||
|
-->
|
||||||
|
<system.webServer>
|
||||||
|
<validation validateIntegratedModeConfiguration="false"/>
|
||||||
|
<modules runAllManagedModulesForAllRequests="true">
|
||||||
|
<remove name="ScriptModule"/>
|
||||||
|
<remove name="UrlRoutingModule"/>
|
||||||
|
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
</modules>
|
||||||
|
<handlers>
|
||||||
|
<remove name="WebServiceHandlerFactory-Integrated"/>
|
||||||
|
<remove name="ScriptHandlerFactory"/>
|
||||||
|
<remove name="ScriptHandlerFactoryAppServices"/>
|
||||||
|
<remove name="ScriptResource"/>
|
||||||
|
<remove name="UrlRoutingHandler"/>
|
||||||
|
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
|
||||||
|
<add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd" type="System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||||
|
</handlers>
|
||||||
|
</system.webServer>
|
||||||
|
<runtime>
|
||||||
|
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<dependentAssembly>
|
||||||
|
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
|
||||||
|
<bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0"/>
|
||||||
|
</dependentAssembly>
|
||||||
|
</assemblyBinding>
|
||||||
|
</runtime>
|
||||||
|
</configuration>
|
52
src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs
Normal file
52
src/Orchard.Azure/Orchard.Azure.Web/WebRole.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using Microsoft.WindowsAzure;
|
||||||
|
using Microsoft.WindowsAzure.Diagnostics;
|
||||||
|
using Microsoft.WindowsAzure.ServiceRuntime;
|
||||||
|
|
||||||
|
namespace Orchard.Azure.Web {
|
||||||
|
public class WebRole : RoleEntryPoint {
|
||||||
|
public override bool OnStart() {
|
||||||
|
DiagnosticMonitor.Start("DiagnosticsConnectionString");
|
||||||
|
|
||||||
|
#region Setup CloudStorageAccount Configuration Setting Publisher
|
||||||
|
|
||||||
|
// This code sets up a handler to update CloudStorageAccount instances when their corresponding
|
||||||
|
// configuration settings change in the service configuration file.
|
||||||
|
CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) => {
|
||||||
|
// Provide the configSetter with the initial value
|
||||||
|
configSetter(RoleEnvironment.GetConfigurationSettingValue(configName));
|
||||||
|
|
||||||
|
RoleEnvironment.Changed += (sender, arg) => {
|
||||||
|
if ( arg.Changes.OfType<RoleEnvironmentConfigurationSettingChange>()
|
||||||
|
.Any(change => ( change.ConfigurationSettingName == configName )) ) {
|
||||||
|
// The corresponding configuration setting has changed, propagate the value
|
||||||
|
if ( !configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)) ) {
|
||||||
|
// In this case, the change to the storage account credentials in the
|
||||||
|
// service configuration is significant enough that the role needs to be
|
||||||
|
// recycled in order to use the latest settings. (for example, the
|
||||||
|
// endpoint has changed)
|
||||||
|
RoleEnvironment.RequestRecycle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
// For information on handling configuration changes
|
||||||
|
// see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357.
|
||||||
|
RoleEnvironment.Changing += (sender, e) => {
|
||||||
|
// If a configuration setting is changing
|
||||||
|
if (
|
||||||
|
e.Changes.Any(
|
||||||
|
change => change is RoleEnvironmentConfigurationSettingChange) ) {
|
||||||
|
// Set e.Cancel to true to restart this role instance
|
||||||
|
e.Cancel = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return base.OnStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@@ -51,9 +51,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="CloudBlobContainerExtensions.cs" />
|
<Compile Include="CloudBlobContainerExtensions.cs" />
|
||||||
|
<Compile Include="Environment\Configuration\AzureAppDataFolder.cs" />
|
||||||
<Compile Include="Environment\Configuration\AzureShellSettingsManager.cs" />
|
<Compile Include="Environment\Configuration\AzureShellSettingsManager.cs" />
|
||||||
<Compile Include="Storage\AzureBlobStorageProvider.cs" />
|
<Compile Include="Storage\AzureBlobStorageProvider.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="AzureFileSystem.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Orchard\Orchard.Framework.csproj">
|
<ProjectReference Include="..\Orchard\Orchard.Framework.csproj">
|
||||||
|
@@ -1,250 +1,16 @@
|
|||||||
using System;
|
using Microsoft.WindowsAzure;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Microsoft.WindowsAzure;
|
|
||||||
using Microsoft.WindowsAzure.StorageClient;
|
|
||||||
using System.IO;
|
|
||||||
using Orchard.Storage;
|
using Orchard.Storage;
|
||||||
|
|
||||||
namespace Orchard.Azure.Storage {
|
namespace Orchard.Azure.Storage {
|
||||||
public interface IDependency { }
|
|
||||||
|
|
||||||
public class AzureBlobStorageProvider : IStorageProvider {
|
public class AzureBlobStorageProvider : AzureFileSystem, 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 AzureBlobStorageProvider(string shellName)
|
public AzureBlobStorageProvider(string shellName)
|
||||||
: this(shellName, CloudStorageAccount.FromConfigurationSetting("DataConnectionString")) {
|
: this(shellName, CloudStorageAccount.FromConfigurationSetting("DataConnectionString")) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public AzureBlobStorageProvider(string shellName, CloudStorageAccount storageAccount) {
|
public AzureBlobStorageProvider(string shellName, CloudStorageAccount storageAccount) : base("media", shellName, false, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user