- PVSM.RU - https://www.pvsm.ru -
В этой статье – как скопировать объект и корзину (bucket) из Amazon S3 в хранилище блобов Windows Azure.
Одним из значительных нововведений после 7 июня 2012 года стало усовершенствование функции Copy Blob. При написании этой статьи я использовал материалы команды разработки, которые можно найти здесь: http://blogs.msdn.com/b/windowsazurestorage/archive/2012/06/12/introducing-asynchronous-cross-account-copy-blob.aspx [1]. Что привлекло моё внимание – функциональность copy blob позволяет копировать блобы извне Windows Azure, если они публично доступны. То есть им нет необходимости находиться в Windows Azure.
Это заставило меня сесть и подумать.. То есть сейчас у меня есть вариант простого переноса моих файлов в хранилище блобов Windows Azure, при этом большинство работы будет выполнено самой платформой. Поэтому я и подумал, а не написать ли простое приложение, которое попробует скопировать файл (объект) из Amazon S3 в хранилище блобов Windows Azure. Получилось это сделать за несколько часов (часов потому что не было аккаунта в S3 до определенного момента, соответственно знания о клиентской библиотеке для хранилища были несколько ограничены). Но что я хочу сказать: это реально работает и это реально просто сделать.
Я подумал о нескольких сценариях, в которых могло бы понадобиться копирование контента из одного облачного провайдера в хранилище блобов Windows Azure.
Со всеми новыми фичами и снижением цен хранилище Windows Azure – реальная альтернатива другим облачным провайдерам, предоставляющим услуги облачного хранилища. Это может стать одной из причин, по которой вы перейдете с используемого провайдера на Windows Azure Storage. Либо вы всегда хотели перейти, но не могли придумать, как перенести данные с хранилища. Новая функция Copy Blob делает решение этой проблемы суперпростым.
Теперь можно легко использовать хранилище блобов как место для резервирования данных из используемого облачного хранилища. Это было возможно и раньше, но было довольно болезненным процессом, так как требовало кучу кода.
С последними нововведениями это стало реально просто. Теперь не надо писать код для копирования байт из источника в блоб в Windows Azure. Все это делает платформа. Вы просто говорите, где находится источник и куда его надо перенести, вызываете функцию копирования и всё.
OK, хватит разговоров! Давайте посмотрим на код. Я создал простое консольное приложение (код ниже), но прежде чем я перейду к нему, хотелось бы обсудить ещё пару моментов. .
Перед запуском кода нужно совершить несколько действий:
1. Создать аккаунт хранилища: обратите внимание, что новая функциональность будет работать только в том случае, если аккаунт хранилища создан после 7-го июня 2012 года (почему – см. примечание [2], прим. переводчика).
2. Скачайте последнюю версию клиентской библиотеки хранилища: на момент написания статьи официально зарелизенной версией библиотеки является 1.7. К сожалению, новая функциональность в ней не работает, поэтому нужно скачать 1.7.1 с GitHub [3]. Скачайте исходники и скомпилируйте.
3. Проверьте публичную доступность объекта/блоба: функция Copy Blobs может копировать только публично доступные блобы извне Windows Azure. Поэтому, в случае Amazon S3, нужно удостовериться, что объект имеет разрешения как минимум уровня READ для анонимных пользователей.
Как я уже сказал выше, код очень прост:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
namespace CopyAmazonObjectToBlobStorage
{
class Program
{
private static string azureStorageAccountName = “";
private static string azureStorageAccountKey = "";
private static string azureBlobContainerName = "";
private static string amazonObjectUrl = "";
private static string azureBlobName = "";
static void Main(string[] args)
{
CloudStorageAccount csa = new CloudStorageAccount(new StorageCredentialsAccountAndKey(azureStorageAccountName, azureStorageAccountKey), true);
CloudBlobClient blobClient = csa.CreateCloudBlobClient();
var blobContainer = blobClient.GetContainerReference(azureBlobContainerName);
Console.WriteLine("Trying to create the blob container....");
blobContainer.CreateIfNotExist();
Console.WriteLine("Blob container created....");
var blockBlob = blobContainer.GetBlockBlobReference(azureBlobName);
Console.WriteLine("Created a reference for block blob in Windows Azure....");
Console.WriteLine("Blob Uri: " + blockBlob.Uri.AbsoluteUri);
Console.WriteLine("Now trying to initiate copy....");
blockBlob.StartCopyFromBlob(new Uri(amazonObjectUrl), null, null, null);
Console.WriteLine("Copy started....");
Console.WriteLine("Now tracking blob's copy progress....");
bool continueLoop = true;
while (continueLoop)
{
Console.WriteLine("");
Console.WriteLine("Fetching lists of blobs in Azure blob container....");
var blobsList = blobContainer.ListBlobs(true, BlobListingDetails.Copy);
foreach (var blob in blobsList)
{
var tempBlockBlob = (CloudBlob) blob;
var destBlob = blob as CloudBlob;
if (tempBlockBlob.Name == azureBlobName)
{
var copyStatus = tempBlockBlob.CopyState;
if (copyStatus != null)
{
Console.WriteLine("Status of blob copy...." + copyStatus.Status);
var percentComplete = copyStatus.BytesCopied / copyStatus.TotalBytes;
Console.WriteLine("Total bytes to copy...." + copyStatus.TotalBytes);
Console.WriteLine("Total bytes copied...." + copyStatus.BytesCopied);
if (copyStatus.Status != CopyStatus.Pending)
{
continueLoop = false;
}
}
}
}
Console.WriteLine("");
Console.WriteLine("==============================================");
System.Threading.Thread.Sleep(1000);
}
Console.WriteLine("Process completed....");
Console.WriteLine("Press any key to terminate the program....");
Console.ReadLine();
}
}
}
Код достаточно прост. Что я делаю: я указываю учетные данные для доступа к хранилищу Windows Azure и URL блоба-источника (в Amazon S3); создаю контейнер блобов в Windows Azure и начинаю копирование блоба с URL источника. После отправки запроса на копирование всё, что делает приложение, это мониторит процесс копирования. Как вы видите, ни одной строки кода для копирования байт из источника в приемник. Всё это делает Windows Azure.
Вот как выглядит объект в Amazon S3:

После того, как объект скопирован, я могу увидеть его в хранилище блобов Windows Azure, используя Cloud Storage Studio [4].

Как вы увидели, Windows Azure предоставляет возможность простого переноса данных. Если вы рассматриваете возможность перехода с другой облачной платформы на Windows Azure, но беспокоились о всяких связанных с этим проблемах, одной проблемой стало меньше.
Я создал простой пример, который копирует один файл из Amazon S3 в хранилище блобов Windows Azure. Эту функциональность можно расширить до копирования всех объектов из корзины Amazon S3 в контейнер блобов Windows Azure. Давайте перейдем к следующей статье – как скопировать корзину из Amazon S3 в хранилище блобов Windows Azure, используя Copy Blob.
Перед запуском кода нужно совершить несколько действий:
Код очень простой. Учтите, что он только для демонстрации. Можете модифицировать его как вам необходимо.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Amazon.S3.Util;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Globalization;
namespace CopyAmazonBucketToBlobStorage
{
class Program
{
private static string azureStorageAccountName = “”;
private static string azureStorageAccountKey = “”;
private static string azureBlobContainerName = “”;
private static string amazonAccessKey = “”;
private static string amazonSecretKey = “”;
private static string amazonBucketName = “”;
private static string objectUrlFormat = “https://{0}.s3.amazonaws.com/{1}”;
private static Dictionary<string, CopyBlobProgress> CopyBlobProgress;
static void Main(string[] args)
{
//Создание ссылки на аккаунт хранилища Windows Azure
CloudStorageAccount azureCloudStorageAccount = new CloudStorageAccount(new StorageCredentialsAccountAndKey(azureStorageAccountName, azureStorageAccountKey), true);
//Получение ссылки на контейнер блоба, куда будут скопированы объекты.
var blobContainer = azureCloudStorageAccount.CreateCloudBlobClient().GetContainerReference(azureBlobContainerName);
//Создание контейнера блобов, если это необходимо.
Console.WriteLine(«Trying to create the blob container....»);
blobContainer.CreateIfNotExist();
Console.WriteLine(«Blob container created....»);
//Создание ссылки на клиент Amazon
AmazonS3Client amazonClient = new AmazonS3Client(amazonAccessKey, amazonSecretKey);
//Инициализация словаря
CopyBlobProgress = new Dictionary<string, CopyBlobProgress>();
string continuationToken = null;
bool continueListObjects = true;
//Так как ListObjects может возвратить за один раз не более 1000 объектов, //вызываем функцию до тех пор, пока не будут возвращены все объекты.
while (continueListObjects)
{
ListObjectsRequest requestToListObjects = new ListObjectsRequest()
{
BucketName = amazonBucketName,
Marker = continuationToken,
MaxKeys = 100,
};
Console.WriteLine(«Trying to list objects from S3 Bucket....»);
//Получение списка объектов в Amazon S3
var listObjectsResponse = amazonClient.ListObjects(requestToListObjects);
//Список объектов
var objectsFetchedSoFar = listObjectsResponse.S3Objects;
Console.WriteLine(«Object listing complete. Now starting the copy process....»);
//Просматриваем, не доступны ли еще объекты. Сначала обрабатываем полученные объекты, потом переходим на следующее множество с использованием continuation token.
continuationToken = listObjectsResponse.NextMarker;
foreach (var s3Object in objectsFetchedSoFar)
{
string objectKey = s3Object.Key;
//ListObjects возвращает файлы и папки, пропускаем папки, проверяя для этого значение S3 Object Key. Если оно кончается на /, предполагаем что это папка.
if (!objectKey.EndsWith(«/»))
{
//формируем URL для копирования
string urlToCopy = string.Format(CultureInfo.InvariantCulture, objectUrlFormat, amazonBucketName, objectKey);
//Создаем экземпляр CloudBlockBlob
CloudBlockBlob blockBlob = blobContainer.GetBlockBlobReference(objectKey);
var blockBlobUrl = blockBlob.Uri.AbsoluteUri;
if (!CopyBlobProgress.ContainsKey(blockBlobUrl))
{
CopyBlobProgress.Add(blockBlobUrl, new CopyBlobProgress()
{
Status = CopyStatus.NotStarted,
});
//Запускаем копирование. Оборачиваем его в блок try/catch
//так как копирование из Amazon S3 будет произведено только для публично доступных объектов.
try
{
Console.WriteLine(string.Format(«Trying to copy »{0}» to »{1}»«, urlToCopy, blockBlobUrl));
blockBlob.StartCopyFromBlob(new Uri(urlToCopy));
CopyBlobProgress[blockBlobUrl].Status = CopyStatus.Started;
}
catch (Exception exception)
{
CopyBlobProgress[blockBlobUrl].Status = CopyStatus.Failed;
CopyBlobProgress[blockBlobUrl].Error = exception;
}
}
}
}
Console.WriteLine(««);
Console.WriteLine(«==========================================================«);
Console.WriteLine(««);
Console.WriteLine(«Checking the status of copy process....»);
//Мониторим процесс
bool checkForBlobCopyStatus = true;
while (checkForBlobCopyStatus)
{
//Получаем список блобов в контейнере блобов
var blobsList = blobContainer.ListBlobs(true, BlobListingDetails.Copy);
foreach (var blob in blobsList)
{
var tempBlockBlob = blob as CloudBlob;
var copyStatus = tempBlockBlob.CopyState;
if (CopyBlobProgress.ContainsKey(tempBlockBlob.Uri.AbsoluteUri))
{
var copyBlobProgress = CopyBlobProgress[tempBlockBlob.Uri.AbsoluteUri];
if (copyStatus != null)
{
Console.WriteLine(string.Format(«Status of »{0}» blob copy....», tempBlockBlob.Uri.AbsoluteUri, copyStatus.Status));
switch (copyStatus.Status)
{
case Microsoft.WindowsAzure.StorageClient.CopyStatus.Aborted:
if (copyBlobProgress != null)
{
copyBlobProgress.Status = CopyStatus.Aborted;
}
break;
case Microsoft.WindowsAzure.StorageClient.CopyStatus.Failed:
if (copyBlobProgress != null)
{
copyBlobProgress.Status = CopyStatus.Failed;
}
break;
case Microsoft.WindowsAzure.StorageClient.CopyStatus.Invalid:
if (copyBlobProgress != null)
{
copyBlobProgress.Status = CopyStatus.Invalid;
}
break;
case Microsoft.WindowsAzure.StorageClient.CopyStatus.Pending:
if (copyBlobProgress != null)
{
copyBlobProgress.Status = CopyStatus.Pending;
}
break;
case Microsoft.WindowsAzure.StorageClient.CopyStatus.Success:
if (copyBlobProgress != null)
{
copyBlobProgress.Status = CopyStatus.Success;
}
break;
}
}
}
}
var pendingBlob = CopyBlobProgress.FirstOrDefault(c => c.Value.Status == CopyStatus.Pending);
if (string.IsNullOrWhiteSpace(pendingBlob.Key))
{
checkForBlobCopyStatus = false;
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
if (string.IsNullOrWhiteSpace(continuationToken))
{
continueListObjects = false;
}
Console.WriteLine(««);
Console.WriteLine(«==========================================================«);
Console.WriteLine(««);
}
Console.WriteLine(«Process completed....»);
Console.WriteLine(«Press any key to terminate the program....»);
Console.ReadLine();
}
}
public class CopyBlobProgress
{
public CopyStatus Status
{
get;
set;
}
public Exception Error
{
get;
set;
}
}
public enum CopyStatus
{
NotStarted,
Started,
Aborted,
Failed,
Invalid,
Pending,
Success
}
}
Код достаточно прост. Приложение:
Для управления контентом в Amazon S3 я использовал Bucket Explorer [6], который показал следующее состояние:

После окончания копирования следующее состояние хранилища блобов Windows Azure показал Cloud Storage Studio [4].

Резюме
Я создал простой пример, который копирует все содержимое из корзины Amazon S3 в хранилище блобов Windows Azure.
Резюме от переводчика
Эмоции Гаурава о новых возможностях API понятны — честно говоря, до 7 июня 2012 года API для использования сервисов хранилищ местами хромало на функциональность, о чем говорит переводная серия статей того же Гаурава о сравнении хранилищ Windows Azure и Amazon. Теперь же возможность использовать хранилище Windows Azure в качестве того же места для резервирования, да ещё и с возможностью регулировать степень избыточности (теперь доступно два типа), позволяет избежать, наверное, последствий любого катаклизма и создать действительно отказотерпимый (:) сервис.
Примечание от переводчика
Сервисы хранилища Windows Azure могут принимать запросы, которые указывают конкретную версию каждой операции (сервиса), при этом разработчик может указать версию, используя заголовок x-ms-version. Естественно, что функциональность различных версий и механизмы работы (не концептуальные) могут различаться.
Надо учитывать правила системы, по которой сервис блобов определяет, какую версию использовать для интерпретации параметров SAS:
1. Если в запросе есть заголовок x-ms-version, но нет signedversion, используется версия 2009-07-17 для интерпретации параметров SAS, для операции же используется версия, указанная в x-ms-version.
2. Если в запросе нет заголовка x-ms-version и нет signedversion, но владелец аккаунта установил версию сервиса, используя операцию Set Blob Service Properties, будет использована версия 2009-07-07 для интерпретации параметров SAS, для операции же используется версия, указанная владельцем аккаунта для сервиса.
3. Если в запросе нет заголовка x-ms-version, нет signedversion и владелец аккаунта не устанавливал версию сервиса, будет использована версия 2009-07-17 для интерпретации параметров SAS. Если контейнер имеет права public и ограничения доступа были установлены с использованием операции Set Container ACL, использующей версию 2009-09-19 (или новее).будет использована версия 2009-09-19 для операции.
Подробнее [7] про версии и поддерживаемую ими функциональность.
Перевод соответствующих постов Gaurav Mantri:
Объекты [8]
Корзины [9]
Автор: ahriman
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/microsoft/10163
Ссылки в тексте:
[1] http://blogs.msdn.com/b/windowsazurestorage/archive/2012/06/12/introducing-asynchronous-cross-account-copy-blob.aspx: http://blogs.msdn.com/b/windowsazurestorage/archive/2012/06/12/introducing-asynchronous-cross-account-copy-blob.aspx
[2] примечание: #version
[3] GitHub: https://github.com/WindowsAzure/azure-sdk-for-net/tree/sdk_1.7.1
[4] Cloud Storage Studio: http://www.cerebrata.com/Products/CloudStorageStudio
[5] сайта Amazon AWS: http://aws.amazon.com/sdkfornet/
[6] Bucket Explorer: http://www.bucketexplorer.com/
[7] Подробнее: http://msdn.microsoft.com/en-us/library/windowsazure/dd894041
[8] Объекты: http://gauravmantri.com/2012/06/14/how-to-copy-an-object-from-amazon-s3-to-windows-azure-blob-storage-using-copy-blob/
[9] Корзины: http://gauravmantri.com/2012/06/15/how-to-copy-a-bucket-from-amazon-s3-to-windows-azure-blob-storage-using-copy-blob/
Нажмите здесь для печати.