Um dos recursos providos pelo Windows Azure storage é a administração de Blobs. Os Blobs (Binary Large Objects) são coleções de dados binários armazenados em uma única entidade de forma não estruturada. Blobs são tipicamente imagens, áudios ou outros tipos de artefatos de multimídia. O armazenamento de blobs requer cuidados, pois não são dados estruturados (como dados de bancos de dados estruturais e instâncias de classes) e geralmente estão associados com grandes quantidades de dados binários (esta é a origem do termo binary large objects).
Para ter uma visão mais geral sobre o Windows Azure storage leia este link: https://ferhenriquef.com/2013/05/16/windows-azure-storage/
A seguir discutiremos um pouco mais sobre as características existentes no Windows Azure para administração dos blobs. Veremos recursos como containers, storage accounts, permissões, metadados e outros.
Criando um Windows Azure storage account
Antes de começarmos a trabalhar com o Windows Azure storage é preciso criar um Windows Azure Storage account. Abra seu portal do Windows Azure e clique na opção “Armazenamento”, localizada no menu lateral.
Clique em “+Novo” para criar um novo Windows Azure storage account. Podemos utilizar a opção de criação rápida, informando apenas a URL e a localização geográfica dos nossos dados.
Após informados esses dados o Windows Azure fará o processamento necessário e o Windows Azure storage account será criado.
Nosso Windows Azure storage account depois de criado deverá se parecer com a imagem abaixo:
Antes de começar a programar…
Para começar a trabalhar com o Windows Azure storage é indicado fazer o download de dois recursos:
– Windows Azure SDK: http://www.microsoft.com/en-us/download/details.aspx?id=35448
– Instalar o NuGet do Windows Azure Storage: http://nuget.org/packages/WindowsAzure.Storage
Conectando no Windows Azure storage
Para realizarmos uma conexão com o Windows Azure storage é preciso fazer uso de das chaves de acesso da conta do Windows Azure storage. Quando criamos uma conta no Windows Azure storage são criadas duas chaves de acesso. Essas chaves de acesso são equivalentes e ambas podem ser utilizadas para acessar a sua conta do Windows Azure storage.
Mas por que duas chaves são geradas? São geradas duas chaves para facilitar a criação de políticas de rotação de senhas. A abordagem de duas chaves de acesso permite que existam duas chaves de acesso válidas, sendo que enquanto um sistema é migrado para uma nova chave de acesso os demais sistemas que dependem das chaves de acesso não ficarão fora do ar.
Para acessar as chaves de acesso basta abrir o portal do Windows Azure, acessar a Seção de Armazenamento e clicar em “Gerenciar Chaves de Acesso”. Nesta janela estarão as chaves de acesso primária e secundária.
Repare que na janela de “Gerenciamento de Chaves de Acesso” temos o campo “Nome da conta de armazenamento”, que também será utilizado para realizar a autenticação entre a aplicação e o Windows Azure storage.
Abaixo temos um exemplo de código que faz uso da conta de armazenamento e da chave de acesso primária para criação de uma conexão com o Windows Azure storage.
public static CloudStorageAccount GetStorageAccount() { string accountName = "<data account name>"; string primaryKey = "<primary key>"; StorageCredentials credentials = new StorageCredentials(accountName, primaryKey); CloudStorageAccount storageAccount = new CloudStorageAccount(credentials, true); return storageAccount; }
Esse bloco será bastante útil, pois será utilizado sempre que for preciso estabelecer uma conexão com o Windows Azure storage.
Containers
O container é um agrupamento lógico utilizado para armazenar um conjunto de blobs. Um container pode armazenar de zero a um infinito número de blobs. Também não existe uma quantidade limite de containers que podem ser criados em um Windows Azure storage account.
O objetivo dos containers é agrupar um conjunto de blobs para que os dados armazenados na nuvem possam ser gerenciados de maneira mais organizada. Além disso, os containers possuem recursos de controle de permissões que possibilitam a definição de políticas de acesso e manipulação dos dados armazenados na nuvem.
A existência de um container é obrigatória para o upload de blobs.
O código apresentado abaixo faz uso das credenciais de acesso ao Windows Azure storage para verificar se um determinado container existe, e se o container não existir, então forçar a sua criação.
private static CloudBlobContainer GetContainer(string containerName) { var account = GetStorageAccount(); CloudBlobClient blobClient = account.CreateCloudBlobClient(); CloudBlobContainer container = blobClient.GetContainerReference(containerName); bool created = container.CreateIfNotExists(); return container; }
Uma referência…
Para o upload de um blob é necessário fornecer um valor como nome do blob. Esse valor funciona como referência e distinguirá um blob dos demais.
Ao criar um nome para um blob procure certificar-se que este valor é único e não será utilizado por outro blob. Esta preocupação é importante, pois dois blobs distintos não podem ter o mesmo nome dentro de um mesmo container senão dados serão sobrescritos erroneamente.
Nomenclatura de containers e blobs
Existem algumas regras básicas para nomenclatura de containers e blobs. Para nomeação de containers é recomendado utilizar sequências de caracteres minúsculos entre 3 e 63 caracteres, que comecem com letras ou números, e que contenham apenas letras, números e hífens.
A regra de nomenclatura dos blobs é um pouco diferente. Podemos utilizar letras maiúsculas e minúsculas na criação de nossos blobs, além dos nomes dos blobs poderem variar entre um caractere a 1024 caracteres aceitando outros tipos de caracteres além de letras e números.
Upload de strings
Como primeiro exemplo de upload de dados para o Windows Azure storage, faremos o upload de um texto. Para tanto, será preciso utilizar um bloco de código semelhante ao apresentado abaixo:
public static void SaveData(string reference, string message) { const string BLOB_CONTAINER_NAME = "posts"; var container = GetContainer(BLOB_CONTAINER_NAME); CloudBlockBlob blob = container.GetBlockBlobReference(reference); ASCIIEncoding encoding = new ASCIIEncoding(); var content = new MemoryStream(encoding.GetBytes(message)); blob.UploadFromStream(content); }
Veja que faremos uso dos métodos “GetStorageAccount” e “GetContainer”, apresentados anteriormente.
Após passados os parâmetros para o método e executado o método “SaveData”, veremos que foi criado um container chamado “posts” no nosso serviço de armazenamento do Windows Azure storage.
Clicando no container, serão exibidos os blobs existentes.
Repare que existe uma coluna chamada URL. Esta coluna contém a URL de acesso ao blob, que poderá ser distribuída para que o conteúdo do blob seja visualizado. Neste momento não será possível acessar o conteúdo do blob por meio de sua URL, pois as configurações do container não permitem isso. O modelo de segurança dos containers será discutido mais à frente.
Download de strings
Para recuperar os dados que foram salvos no container é preciso utilizar um bloco de código como o apresentado abaixo. Vale ressaltar que o código abaixo contém um StreamReader exclusivo para conversão do stream em string.
public static string GetStringData(string reference) { const string BLOB_CONTAINER_NAME = "posts"; var container = GetContainer(BLOB_CONTAINER_NAME); CloudBlockBlob blob = container.GetBlockBlobReference(reference); if (!blob.Exists()) throw new System.IndexOutOfRangeException("Blob not found!"); string returnValue = string.Empty; using (Stream stream = new MemoryStream()) { blob.DownloadToStream(stream); stream.Seek(0, SeekOrigin.Begin); returnValue = new StreamReader(stream).ReadToEnd(); } return returnValue; }
Upload e download de bytes
Para fazer o upload de arquivos (sejam esses arquivos imagens, arquivos de áudio, documentos, etc) faremos o upload de bytes, assim como estamos fazendo com as strings. A diferença entre o algoritmo de upload de strings e o algoritmo de upload de arquivos é mínina, pois o algoritmo de upload de string faz a conversão de strings para bytes. Abaixo o código necessário para o upload de arquivos.
public static void SaveData(string reference, byte[] data) { const string BLOB_CONTAINER_NAME = "posts"; var container = GetContainer(BLOB_CONTAINER_NAME); CloudBlockBlob blob = container.GetBlockBlobReference(reference); ASCIIEncoding encoding = new ASCIIEncoding(); var content = new MemoryStream(data); blob.UploadFromStream(content); }
Para o download de bytes o algoritmo também é bastante semelhante ao algoritmo de download de strings, exceto pelo fato de que não precisamos extrair uma string do stream. O código necessário para fazer o download do conteúdo é apresentado abaixo.
public static byte[] GetByteData(string reference) { const string BLOB_CONTAINER_NAME = "posts"; byte[] returnValue = null; var container = GetContainer(BLOB_CONTAINER_NAME); CloudBlockBlob blob = container.GetBlockBlobReference(reference); if (!blob.Exists()) throw new System.IndexOutOfRangeException("Blob not found!"); using (Stream stream = new MemoryStream()) { blob.DownloadToStream(stream); returnValue = stream.ToArray(); } return returnValue; }
Permissões
Quando criamos um container, para o armazenamento de blobs, este container é criado com permissões privadas. Assim, qualquer pessoa que tente acessar um blob por meio de sua URL irá receber uma mensagem de Resource Not Found.
Para compartilharmos blobs através de suas URLs devemos alterar as permissões dos containers. Existem três diferentes tipos de permissões para os containers, sendo eles:
Permissão |
Acesso |
Off |
Indica que o container é privado. Não é possível acessar os blobs ou o próprio container. |
Blob |
Atribui acesso somente leitura para todos os blobs contidos no container, mas não ao container. |
Container |
Atribui acesso somente leitura para o container e todos os blobs contidos por ele. |
O bloco abaixo demonstra como alterar as permissões de um container, tornado seus blobs públicos por meio da permissão “Blob”.
public static void SetPublicAccess(strin containerName) { var container = GetContainer(containerName); var permission = container.GetPermissions(); if (permission.PublicAccess == BlobContainerPublicAccessType.Off) { BlobContainerPermissions newPermission = new BlobContainerPermissions(); newPermission.PublicAccess = BlobContainerPublicAccessType.Blob; container.SetPermissions(newPermission); } }
Metadados customizados
Mais um recurso interessante ao trabalharmos com blobs são os metadados customizados. Os metadados customizados nada mais são do que atributos personalizáveis que conseguimos adicionar nos blobs.
Apenas armazenar os blobs nem sempre é suficiente, muita vezes teremos de adicionar atributos customizados para identificar dados descritivos dos blobs.
O bloco abaixo adiciona um blob e cria um metadado customizado chamado “Origem”, onde o nome da máquina que fez o upload é salvo.
public static void SaveData(string reference, byte[] data) { const string BLOB_CONTAINER_NAME = "posts"; var container = GetContainer(BLOB_CONTAINER_NAME); CloudBlockBlob blob = container.GetBlockBlobReference(reference); ASCIIEncoding encoding = new ASCIIEncoding(); var content = new MemoryStream(data); blob.UploadFromStream(content); blob.Metadata["Origem"] = Environment.MachineName; blob.SetMetadata(); }
Por
MSc. Fernando Henrique Inocêncio Borba Ferreira
Microsoft Most Valuable Professional – Visual C#
Revisão
Itamar Nunes
Referências
Developing Cloud Applications with Windows Azure Storage – Paul Mehner
http://en.wikipedia.org/wiki/Binary_large_object
[…] Para criar um Windows Azure storage account leia a seção de nome "Criando um Windows Azure storage account" deste outro post: https://ferhenriquef.com/2013/06/09/windows-azure-storage-blob/ […]
Parabêns pelo seu post.
Tenho uma pergunta muito importante: tenho um sistema que guarda arquivos digitais. O acesso aos arquivos é feito por login e senha controlados no meu sistema.
Teria como criar links temporarios para arquivos no Windows Azure?
O que eu queria é que ao usuário clicar no arquivo, meu sistema checa se ele tem privilégio, se ele tiver lança um link para o arquivo armazenado no Azure válido por alguns segundos.
Ou também poderia criar um link com alguma chave temporária.
Sei que uma alternativa seria ler o arquivo do windows azure para meu servidor e depois echoar ele para o browser do cliente, mas isso não seria legal porque perderia tempo e usaria banda adicional.
Tem alguma dica ?
Oi Cristiano,
Tudo bem?
Dê uma olhada em SAS (Security Access Signature). Vc pode criar URLs com SAS e definir m período limite no qual o usuário pode visualizar os dados.
Um link de referência: http://www.dotnetcurry.com/ShowArticle.aspx?ID=901
Obrigado por postar.
[]s!
Exatamente o que eu precisava.
Excelente post, parabéns.
Obrigado, Fabiano!
[]s!