Компонент хранилища “облачной” платформы Windows Azure предоставляет масштабируемое хранилище. Компонент хранилища не имеет возможности использовать реляционную модель и является альтернативой (либо дополняющим решением) SQL Azure – масштабируемой “облачной” версией SQL Server.
В хранилище Windows Azure существует четыре абстракции, отвечающих за сервисы хранилища:
1) Блобы – простые именованные файлы + метаданные
2) Диски– долговечные тома NTFS, используемые приложениями Windows Azure. Основаны на блобах
3)Таблицы– структурированное хранилище. Таблица – множество сущностей, сущность – множество свойств
4)Очереди – надежное хранение и доставка сообщений для приложения
На изображении представлена концептуальная архитектура и адресация ссылок на блобы.
-Приватные
-По умолчанию, для доступа нужен ключ аккаунта
-Полное публичное чтение
-Публичное только чтение
Существует два типа блобов:
Необходимо учитывать различия, имеющиеся между хранилищем блобов в локальном эмуляторе и хранилищем блобов в облаке.
public static void CreateBlobContainer(string container) { //получение настройки конфигурации хранилища var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //создание ссылки на контейнер var blobContainer = blobClient.GetContainerReference(container); //создание контейнера blobContainer.CreateIfNotExist(); }
Сначала создается blobClient типа CloudBlobClient, необходимый для предоставления операций, доступных для управления блобами и контейнерами блобов, после чего получается ссылка на контейнер блобов и с помощью метода CreateIfNotExists контейнер создается, если его ранее не было. Доступен также метод Create, однако в случае существования контейнера с таким именем будет выброшено исключение, поэтому безопаснее использовать CreateIfNotExists.
При создании контейнера блобов необходимо учитывать следующие ограничения:
- Имя контейнера должно начинаться с буквы или цифры, и может содержать только буквы, цифры и символы дефиса.
- Все буквы должны быть низшего регистра.
- Длина имени должна быть от 3 до 63 символов.
- Имя не может содержат дефис после точки.
Таким образом, у вас не получится создать контейнер с именем myContainer – только mycontainer.
public static void CreateBlobContainerAsync(string container) { //получение настройки конфигурации хранилища var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //получение ссылки на контейнер var blobContainer = blobClient.GetContainerReference(container); //начало процесса создания контейнера blobContainer.BeginCreateIfNotExist(EndCreateCloudBlobContainer, blobContainer); } public static void EndCreateCloudBlobContainer(IAsyncResult asyncResult) { var blobContainer = (CloudBlobContainer)asyncResult.AsyncState; blobContainer.EndCreateIfNotExist(asyncResult); }
protected void DeleteBlobContainer(string containerName) { //получение настройки конфигурации хранилища CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //получение ссылки на контейнер var blobContainer = blobClient.GetContainerReference(containerName); //удаление контейнера blobContainer.Delete(); }
Для создания блоба в указанном контейнере достаточно воспользоваться методом GetBlobReference объекта контейнера, передав ему наименование блоба. После этого будет создан пустой блоб, который необходимо чем-либо заполнить.
protected void AddBlob() { try{ //получение настройки конфигурации хранилища CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //получение ссылки на контейнер mycontainer var blobContainer = blobClient.GetContainerReference("mycontainer"); //получение ссылки на блоб newblob var blob = blobContainer.GetBlobReference("newblob"); //загрузка в блоб файла Untitled.wmv blob.UploadFile(@"c:\Untitled.wmv"); } catch (StorageClientException e) { Console.WriteLine("Storage client error encountered: " + e.Message); System.Environment.Exit(1); } }
protected void DeleteBlob(string blobName) { //получение настройки конфигурации хранилища CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //получение ссылки на блоб var blob = blobClient.GetBlobReference(blobName); //удаление блоба в случае его существования blob.DeleteIfExists(); }
Блобы могут иметь ассоциированные с ними метаданные. Заголовки метаданных могут быть определены по запросу при создании нового контейнера или блоба, или при «привязке» метаданных к уже существующим ресурсам
protected void AssociateMetadata(string containerName) { //создание коллекции значений ключ-значение NameValueCollection metadata = new NameValueCollection(); //получение настройки конфигурации хранилища CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); //получение ссылки на контейнер var blobContainer = blobClient.GetContainerReference(containerName); //определение метаданных metadata["id"] = "1"; metadata["name"] = "mycontainer"; //добавление метаданных в словарь метаданных для контейнера blobContainer.Metadata.Add(metadata); //”коммит” метаданных blobContainer.SetMetadata(); //получение ссылки на блоб var blob = blobContainer.GetBlobReference("newblob"); //добавление метаданных в словарь метаданных для блоба blob.Metadata.Add(metadata); //”коммит” метаданных blob.SetMetadata(); }
protected void GetMetadata(string containerName) { CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); var blobContainer = blobClient.GetContainerReference(containerName); blobContainer.FetchAttributes(); var metadataContainer = blobContainer.Metadata; System.Diagnostics.Trace.WriteLine(metadataContainer["id"]); //метаданные для блоба var blob = blobContainer.GetBlobReference("newblob"); blob.FetchAttributes(); var metadata = blob.Metadata; System.Diagnostics.Trace.WriteLine(string.Format("content-type: {0}", blob.Properties.ContentType)); blob.Properties.ContentType = "image/jpeg"; System.Diagnostics.Trace.WriteLine(string.Format("content-type after changing: {0}", blob.Properties.ContentType)); }
Класс BlobContainerPublicAccessType является enumeration, состоящим из следующих возможных значений прав доступа:
protected void SetBlobContainerPermissions(BlobContainerPublicAccessType publicAccess) { var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); var blobContainer = blobClient.GetContainerReference("mycontainer"); //определение разрешений путем создания легковесного объекта blobContainer.SetPermissions (new BlobContainerPermissions() { PublicAccess = publicAccess }); }
Shared Access Policies и Shared Access Signatures позволяют создать некоторые правила доступа к блобу или контейнеру, определяющие права доступа и период доступа.
Shared Access Policy: Политика определяет время начала действия политики, время истечения и набор разрешений для Shared Access Signatures.
Shared Access Signature: URL, предоставляющий доступ к контейнеру и блобу.
protected void SetSAS() { var blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); var blobContainer = blobClient.GetContainerReference("mycontainer"); //создание объекта разрешений на контейнер var permissions = new BlobContainerPermissions(); //добавление политики на “только чтение” permissions.SharedAccessPolicies.Add("readonly", new SharedAccessPolicy() { SharedAccessStartTime = null, Permissions = SharedAccessPermissions.Read }); //добавление политики на “только запись” permissions.SharedAccessPolicies.Add("writeonly", new SharedAccessPolicy() { SharedAccessStartTime = null, Permissions = SharedAccessPermissions.Write }); //”коммит” разрешений blobContainer.SetPermissions(permissions); var blob = blobClient.GetBlobReference("mycontainer/Untitled.wmv"); //получение сигнатуры var sas = blob.GetSharedAccessSignature(new SharedAccessPolicy() { SharedAccessExpiryTime = DateTime.UtcNow.AddDays(5) }, "readonly"); System.Diagnostics.Trace.WriteLine(string.Format("Shared Access Signature for blob {0} is {1}, full link is {0}{1}", blob.Uri.AbsoluteUri, sas)); }
Сервис блобов Windows Azure имеет поддержку копирования существующих блобов. Кроме этого сервис блобов Windows Azure поддерживает создание снапшотов блобов. Разница между снапшотом и копией блоба состоит в том, что снапшоты являются read-only и блоб-источник поддерживает связь со своими снапшотами; копии же можно изменять. После создания снапшота блоба блоб-источник не может быть удален до тех пор, пока существует хотя бы один его снапшот.
protected void CopyAndSnapshotBlob() { CloudBlobClient blobClient = CloudStorageAccount.FromConfigurationSetting("DataStorage").CreateCloudBlobClient(); var blobContainer = blobClient.GetContainerReference("mycontainer"); var srcBlob = blobContainer.GetBlobReference("newblob"); var newBlob = blobContainer.GetBlobReference("newblobcopy"); ; newBlob.CopyFromBlob(srcBlob); newBlob.FetchAttributes(new BlobRequestOptions { BlobListingDetails = BlobListingDetails.Metadata }); newBlob.Metadata["id"] = "2"; newBlob.Metadata["name"] = "copy of blob"+srcBlob.Metadata["name"]; newBlob.SetMetadata(); System.Diagnostics.Trace.WriteLine("Скопированный блоб имеет имя"+newBlob.Metadata["name"]); var snapshot = srcBlob.CreateSnapshot(); System.Diagnostics.Trace.WriteLine("Был создан снапшот для:" + srcBlob.Uri + " в момент времени: " + snapshot.SnapshotTime); }
Учитываем, что у вас уже созданы аккаунт хранилища и сервис для выполнения вашего приложения, а также создан ASP.NET проект с ассоциированным для него Windows Azure облачным проектом.
При программировании собственного облачного проекта не забудьте определить провайдера конфигурации в методе Application_Start (global.asax):
void Application_Start(object sender, EventArgs e) { CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) => { var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName); configSettingPublisher(connectionString); } );
А также строку подключения к хранилищу. Для этого:
1. Измените в описании сервиса настройки конфигурации, необходимые для доступа к сервису таблиц Windows Azure: откройте в облачном проекте папку Roles, щелкните правой кнопкой мыши на WebRole и выберите Properties.
2. Перейдите на вкладку Settings, нажмите Add Setting и создайте новую настройку конфигурации с именем DataConnectionString. Укажите её тип как Connection String, после чего нажмите на кнопку с троеточием и настройте строку подключения к хранилищу на использование локального эмулятора хранилища – Use storage emulator.
3. Нажмите CTRL-S для сохранения изменений.
Примечание: Библиотека StorageClient использует эти настройки для доступа к хранилищу Windows Azure.
DataConnectionString: Это строка подключения к аккаунту Windows Azure, программно используя которую, мы можем осуществить доступ к хранилищу данных и другой функциональности Windows Azure. Эта строка подключения может использовать либо аккаунт Windows Azure в «облаке», либо локальный эмулятор.
Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString: Это строка подключения к серверу Windows Azure, аналогичная DataConnectionString, но отведённая под нужды диагностики.
После этого поместите все вышеприведенные методы в файл Default.aspx.cs (либо любой другой code-behind файл, который хотите) и вставьте следующий код в обработчик события Page_Load:
protected void Page_Load(object sender, EventArgs e) { CreateBlobContainer("mycontainer"); CreateBlobContainerAsync("mycontainerasync"); DeleteBlobContainer("mycontainerasync"); DeleteBlob("newblob"); AddBlob(); AssociateMetadata("mycontainer"); GetMetadata("mycontainer"); SetBlobContainerPermissions(BlobContainerPublicAccessType.Blob); SetSAS(); CopyAndSnapshotBlob(); }
После запуска в локальном эмуляторе обратите внимание на лог трассировки – в нём вы увидите все сведения, которые выводятся в методах. Кроме этого, вы можете воспользоваться Server Explorer в Visual Studio 2010 для просмотра содержимого вашего локального сервиса хранилища.
Диаграмма класса для наглядности того, что должно было получиться в результате:
Alexander Belotserkovskiy edited Original. Comment: added info about differences between emulator and cloud blob storage