Blobs – Azure Storage [UWP]

Contenidos recomendados:

Los blobs son parte de los servicios de Azure Storage que permiten resolver distintos problemas para el almacenamiento de datos en las aplicaciones. En este artículo se hablará de los Blobs de Azure asumiendo que ya saben lo que son, que tienen una Storage Account en Azure, que saben cómo conectarse a los servicios desde una aplicación, etc. En los contenidos recomendados hay un artículo dedicado a la introducción de este tipo de servicios de almacenamiento de Azure.

 

Haciendo un repaso muy rápido por la taxonomía de los blobs recordemos que una cuenta de almacenamiento de azure puede tener varios contenedores y estos últimos son los que almacenan los blobs. También recordemos que podemos crear carpetas en los contenedores pero que estas son solamente un agregado visual para mantener el orden en una interfaz de usuario porque los contenedores no tienen noción de lo que son las carpetas.

Untitled

 

Para poder utilizar los blobs en las aplicaciones UWP hay que agregar la referencia a WindowsAzure.Storage .

Untitled.png

Desde Visual Studio se puede entrar al Cloud Explorer que es el panel dedicado a los servicios de Azure y administrar la Storage Account muy fácilmente. Para entrar al Cloud Explorer: View>Cloud Explorer, o tambien Ctrl+|, Ctrl+X.

ScreenCloudExplorer

Desde el portal de Azure podemos crear Storage Accounts, containers, administrar los blobs, etc. Azure SDK brinda la posibilidad de hacer todo eso en Visual Studio solo con un par de clicks desde el panel Cloud Explorer. En la siguiente imagen pueden ver que contamos con un container llamado ngblobcontainer en el que contamos con tres archivos de office y una carpeta Images.

ScreenContainerAzureSDK

 

Conexión a los Blobs

Lo primero que habría que hacer es conectarse a la cuenta de Azure mediante la siguiente línea con la cadena de conexión que obtenemos en el portal de Azure o utilizando el emulador de almacenamiento de la Azure SDK.

ScreenPrimaryConnectionStringAzurePortal

var storageaccount = CloudStorageAccount.Parse("**CONNECTION STRING**");
var storageaccount = CloudStorageAccount.Parse("UseDevelopmentStorage=true");

Una vez con la cuenta de almacenamiento de Azure obtenida se puede crear el cliente que permite hacer todas las operaciones con los blobs.

CloudBlobClient clientStorgeAccount = storageAccount.CreateCloudBlobClient();

 

Obtener contenedor

Podemos acceder a una referencia del contenedor mediante el método GetContainerReference que se encuentra dentro del cliente de la Storage Account que creamos anteriormente.

App.clientStorgeAccount.GetContainerReference("ngblobcontainer");

 

Cargar blob

Con las siguientes líneas subo una imagen al contenedor dentro de una carpeta Images. Nuevamente recuerden que las carpetas son solamente una manera de crear una sensación de organización para los archivos del contenedor pero que en realidad los archivos están todos mezclados dentro del contenedor.

public async Task AddBlobFile(StorageFile blobFile)
{
    await container.CreateIfNotExistsAsync();
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(String.Format("Images/{0}", blobFile.Name));
    await blockBlob.UploadFromFileAsync(blobFile);
}

 

Descargar blob

Con GetBlockBlobReference traemos el archivo deseado a través de su path y lo descargamos dentro de un StorageFile con DownloadFileAsync.

public async Task<StorageFile> GetFile(string name)
{
    await container.CreateIfNotExistsAsync();
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(String.Format("Images/{0}", name));

    StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(name, CreationCollisionOption.ReplaceExisting);

    await blockBlob.DownloadToFileAsync(file);
    return file;
}

 

Obtener todos los blobs del container

En un caso real lo más probable es que cada usuario que almacene sus archivos en un container tenga en una base de datos los nombres o el path de los blobs que le pertenecen. Si queremos descargar todos sus archivos es tan sencillo como en el caso anterior agregando un foreach y devolviendo la lista de esos archivos.

public async Task<List<StorageFile>> GetBlobFiles(List<ImageFile> lista)
{
    List<StorageFile> StorageFileList = new List<StorageFile>();
    foreach (var i in lista)
    {
        StorageFileList.Add(await GetBlobFile(i.Path));
    }
    return StorageFileList;
}

 

Privacidad de los contenedores

Podemos configurar la seguridad de nuestros contenedores con tres distintas opciones.

  • Contenedor privado (Off): Solo el dueño de la StorageAccount tiene acceso al contenedor y a sus blobs.
  • Blob público (Blob): El blob es público y cualquier persona puede acceder a este. Sin embargo, si el contenedor es privado no podremos acceder a la lista de blobs pero si a los blobs públicos individualmente.
  • Contenedor público (Container): Esta es la opción más abierta y permite acceder a la lista de todos los blobs que contiene y a tener acceso a esos blobs.

Podemos establecer la privacidad del contendor de la siguiente manera:

public async Task SetContainerPermissions(int type)
{
    BlobContainerPermissions bcp = new BlobContainerPermissions();

    switch (type)
    {
        case 1:
            bcp.PublicAccess = BlobContainerPublicAccessType.Blob;
            break;
        case 2:
            bcp.PublicAccess = BlobContainerPublicAccessType.Container;
            break;
        case 3:
            bcp.PublicAccess = BlobContainerPublicAccessType.Off;
            break;
    }
    await container.SetPermissionsAsync(bcp);
}

Al intentar acceder a los blobs o a la lista de blobs del contenedor mediante la uri recibiremos distintas respuestas dependiendo de la privacidad que hayamos establecido en el contenedor. Si no tenemos acceso Azure directamente nos indicara que el archivo no existe por mas de que esto no sea cierto por razones de seguridad.

 

Concesion de blobs

Si intentamos editar un documento que tenemos en un container (por ejemplo un archivos txt), tendremos que evitar que ese archivo sea accedido al mismo tiempo por otro cliente. Para esto existen las concesiones de los blobs que permiten bloquear el archivo temporalmente para que podamos editarlo tranquilos y evitar cualquier tipo de posibilidad de que el archivo se corrompa al intentar acceder a el de dos lugares a la vez.

Podemos obtener una concesion de un blob de la siguiente manera:

public async Task<AccessCondition> AcquireLeaseBlob(string name, int time)
{
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(String.Format("Images/{0}", name));

    var leaseName = await blockBlob.AcquireLeaseAsync(TimeSpan.FromSeconds(60), null);
    var accessCondition = AccessCondition.GenerateLeaseCondition(leaseName);
    return accessCondition;
}

En el ejemplo anterior obtenemos la concesión de ese blob durante 60 segundos. Esto quiere decir que solamente nosotros podremos realizar operaciones en el archivo durante 1 minuto o hasta que liberemos el blob programáticamente. Para liberarlo lo hacemos de la siguiente manera.

public async Task ReleaseLeaseBlob(AccessCondition accessCondition, string name)
{
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(String.Format("Images/{0}", name));
    await blockBlob.ReleaseLeaseAsync(accessCondition);
}

 

Ejemplo

Con todo esto visto, podemos hacer una app de ejemplo muy sencilla. Nos permite subir imágenes al container desde la app y almacenar los nombres de los archivos en una base de datos interna sqlite. Una vez subido en la segunda pantalla tenemos una lista de todos nuestros archivos en un combobox que nos posibilita seleccionar una y descargarlo o elimiarlo del container. Creamos un servicio para gestionar todas las operaciones que tienen que ver con los blobs.
Screen1App

Screen2App
IMPORTANTE: Para poder probar el ejemplo deben agregar la cadena de conexion de su propia Azure Storage Account.

 

Descargar código

 

Deja un comentario