Trabajando con el Storage de Windows Azure

  • 04 de enero de 2011
  • Valoración:
  • 0 Comentarios
  • .NET
Trabajamos con el servicio Storage de Windows Azure, que nos permite almacenar información a modo de base de datos.
En el Manual de Windows Azure estamos tratando esta herramienta para la programación en la nube. De modo que, ahora que ya sabemos lo necesario para jugar un poco con Azure, vamos a interactuar con el servicio Storage

Este servicio incorporado en Windows Azure nos permite almacenar información, como si de una base de datos se tratara. En este artículo, a modo de simple pincelada introductoria, veremos qué debemos hacer para que nuestro pequeño ejemplo trabaje con datos utilizando con el Storage.

Listado 2. Entidad de metadatos (imgMetaData.cs)
inteusing
System;
using Microsoft.WindowsAzure.StorageClient;
namespace WebRole1
{
public class imgMetaData : TableServiceEntity
{
public imgMetaData()
{
PartitionKey = "meteosat";
RowKey = Guid.NewGuid().ToString();
}
public string Observacion { get; set; }
public DateTime Fecha { get; set; }
public string ContainerRef { get; set; }
public string BlobRef { get; set; }
}
}

Nota: Al trabajar con .NET, podemos utilizar la librería Microsoft.WindowsAzure. StorageClient, que nos encapsulará las llamadas vía REST para que nos resulte más cómodo trabajar con Storage.
Para almacenar los datos en una tabla, lo primero que vamos a necesitar es crear una estructura que represente los metadatos de la imagen que deseamos almacenar. Lo haremos mediante una nueva clase que implemente una entidad heredando de TableServiceEntity, clase que ubicaremos en un nuevo fichero imgMetaData.cs dentro del proyecto de rol Web (listado 2). En el constructor de nuestra nueva entidad se inicializan las propiedades heredadas PartitionKey y RowKey, que implementan claves de agrupación e identificación de datos en la nube.

Listado 3. Servicio de contexto (imgMetaDataServiceContext.cs)
using System;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
namespace WebRole1
{
public class imgMetaDataServiceContext : TableServiceContext
{
public imgMetaDataServiceContext(string baseAdress,
StorageCredentials credentials) : base(baseAdress, credentials)
{
}
public IQueryable<imgMetaData> imgMetaData
{
get { return this.CreateQuery<imgMetaData>("imgMetaData"); }
}
public void AddImage(string observacion, DateTime fecha,
string containerRef, string blobRef)
{
AddObject("imgMetaData", new imgMetaData {
Observacion = observacion, Fecha = fecha,
ContainerRef = containerRef, BlobRef = blobRef });
SaveChanges();
}
}
}

Ahora que ya tenemos nuestra entidad, deberemos generar el codigo minimo necesario para interactuar con colecciones de dichas entidades. Para ello, tambien en el rol Web, creamos otra nueva clase en el fichero imgMetaDataService] Context.cs, esta vez heredando de TableServiceContext (listado 3). En nuestro ejemplo nos centraremos en dos metodos: uno para recuperar entidades de metadatos y otro para agregarlas.

Nota: Es necesario agregar una referencia a la librería System.Data.Services. Client para poder compilar el código.

Vamos ahora a crear la cadena de conexión, que de momento apuntará a nuestro entorno local: dentro de la carpeta Roles del proyecto WeatherService, accedemos a las propiedades del WebRole1 (tal y como veíamos en la figura 2), y en el apartado "Settings" añadimos el elemento DataConnectionString con valor UseDevelopmentStorage=true. A continuación, nos centraremos en el evento OnStart del rol Web. En él mapeamos la configuración del servicio y nos conectamos al Storage, para así poder crear el contenedor BLOB de imágenes y la tabla que contendrá los metadatos. Todo ello puede verse en el listado 4.

Listado 4. Evento OnStart en WebRole.cs
// Creamos la conexión con el servicio de Storage
CloudStorageAccount.SetConfigurationSettingPublisher(
(configName, configSetter) => {
configSetter(ConfigurationManager.ConnectionStrings[configName].ConnectionString);
});
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
// Creamos el contenedor BLOB para almacenar las imágenes
CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference("meteosat");
container.CreateIfNotExist();
// Configuramos el contenedor con acceso público
var permissions = container.GetPermissions();
permissions.PublicAccess = BlobContainerPublicAccessType.Container;
container.SetPermissions(permissions);
// Creamos la tabla para almacenar los metadatos
CloudTableClient.CreateTablesFromModel(typeof(imgMetaDataServiceContext), storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);

Por último, nos queda implementar el evento Click del botón btnGuardar, cuyo cuerpo se muestra en el listado 5.

Listado 5. BtnGuardar_Click en Default.aspx.cs
// Inicializamos la cuenta de Storage
var storageAccount =
CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
// El nombre del contenedor no puede tener mayúsculas
string containerName = "meteosat";
// Almacenamos la imagen
CloudBlobClient blobStorage = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobStorage.GetContainerReference(containerName);
string uniqueBlobName = string.Format("Imagenes/{0}", Guid.NewGuid().ToString());
CloudBlockBlob blob = container.GetBlockBlobReference(uniqueBlobName);
WebRequest req = WebRequest.Create(Imagen.Src);
WebResponse response = req.GetResponse();
Stream stream = response.GetResponseStream();
blob.UploadFromStream(stream);
// Almacenamos los metadatos en la tabla
var operations = new imgMetaDataServiceContext(storageAccount.TableEndpoint.ToString(), storageAccount.Credentials);
operations.AddImage(txtObservaciones.Text, DateTime.Now, containerName,uniqueBlobName);

Con estos sencillos pasos, nuestra aplicación ya almacena datos en el Storage; pero deberemos tener en cuenta que los datos se almacenan en local. Para interactuar con la nube, tenemos que cambiar nuestra cadena de conexión con los datos, que obtendremos como resultado de crear un servicio de Storage en el portal de desarrollo de Azure (del mismo modo que antes hemos creado un Hosted Service).

En el siguiente artículo veremos el SQL Azure que nos permite trabajar con almacenamiento relacional.