A la découverte de Windows Azure

clip_image002

 

Annoncé par Microsoft le 28 Octobre 2008 et officiellement lancé le premier Janvier 2010, Windows Azure a déjà beaucoup fait parler de lui : il s’agit de la plate-forme de Cloud computing de Microsoft. Cet article est une présentation de cette nouvelle plate-forme pour ceux désirant découvrir le principe et le fonctionnement de Windows Azure.

 

L’informatique dans les nuages

 

 

 

On ne peut pas qualifier Windows Azure de Système d’exploitation à proprement parler. Il s’agit plutôt d’une extension, d’un prolongement de celui-ci « in the Cloud », comprenez dans les nuages.

Qu’est ce que le Cloud computing ?

clip_image004Il s’agit tout simplement d’un concept visant à placer internet au cœur des activités des entreprises. Avec le Cloud computing, les entreprises vont pouvoir utiliser des ressources matérielles distantes afin de créer leurs services, accessibles en lignes bien évidemment. Ainsi, les applications et les données ne se trouvent plus sur un ordinateur local, mais bien dans les nuages : des serveurs distants connectés entre eux.

Le Cloud computing marque le passage du SOA au SaaS. Le SOA ( Service Oriented Architecture ) visait à étendre nos applications vers l’univers d’internet, le SaaS ( Software as a Service ) permet de consommer et payer ces applications à la demande et non plus sur l’achat de licence.

Cependant, avec Windows Azure, Microsoft veut aller un peu plus loin : le « S + S » (Software + Service). Il faut voir le « S+S » comme un mélange entre le SOA et le SaaS.

 

 

 

 

 

 

L’hébergement

 

Pour pouvoir héberger nos applications et nos données, Microsoft a pensé toute une architecture s’articulant autour de ses « Data center ». Actuellement seul deux Data center sont opérationnels, ils sont situés sur le continent Américain. Bien entendu, Microsoft va en construire un peu partout autour du globe et pas n’importe comment. Ces derniers seront architecturés de manière à permettre leur extensibilité et permettront même de greffer des containers construits par d’autres constructeurs.

 

clip_image006En ce qui concerne l’hébergement de données, Windows Azure met à notre disposition l’ « Azure Storage ». Pas d’espace disque brut, pas de base de donnée et donc pas de SQL Server. En fait, l’Azure Storage nous permet de stocker des données binaires, des tableaux ou des piles d’élément et d’y accéder via une API spécifique. Ainsi, pour accéder à nos données nous utiliserons une couche logicielle (sur laquelle nous reviendront un peu plus loin) conçue spécialement pour une utilisation dans le Cloud.

Un des gros avantages de l’Azure Storage est qu’il gère la sécurisation automatique des données, la réplication des données (en deux lieux distincts par exemple) ou encore l’optimisation (répartition des charges, optimisation géographique, partitionnement sur plusieurs disques).

Concernant l’hébergement d’application, il n’y a pas d’accès à un quelconque système d’exploitation mais à des processeurs exécutant une machine virtuelle. Ainsi, si l’application a besoin de plus de puissance (que ce soit de manière continue ou ponctuelle) il est possible d’affecter des processeurs supplémentaires à l’application. Il s’agit la de la gestion de la montée en charge de l’application : on va créer de nouvelles instances d’application.

 

clip_image008Il existe deux types d’instance d’application : les « Web rôle instance » qui sont des applications web classique accessible via un navigateur Web grâce à un IIS7 hébergé directement dans Windows Azure et les « Worker role instance » qui sont des applications s’exécutant en tâche de fond.

Sachez également que Windows Azure nous permet de stocker deux versions de notre application : une version en production et une version de test. Il est également possible de les intervertir à tout moment.

 

 

 

(source schéma : http://www.indiangeek.net/)

Live Framework et services

Afin de compléter l’offre d’hébergement proposée par Windows Azure, une couche de service vient se greffer juste au-dessus. Cette couche est composée des Live Services, des .NET Services, des SQL Services ainsi que des Microsoft SharePoint Services et Dynamics CRM Services. Voyons maintenant en quoi ils consistent.

clip_image010

Les Live Services : Il s’agit d’une couche logicielle de haut niveau permettant la manipulation des différents éléments intervenant dans l’utilisation d’une application (les utilisateurs et leurs données associés).

Les applications accédant aux Live Services utiliseront le LOE (Live Operating Environnement) qui est le cœur du Live Framework. Ce LOE est composé entre autre d’un Live Desktop (un bureau web utilisable depuis un navigateur) et de Mesh (un système de synchronisation et de partage de données)

clip_image012

Les .NET Services : Il s’agit d’une couche logicielle de bas niveau apportant les fonctionnalités nécessaires à toutes applications informatiques : sécurité et authentification, communication, workflow.

Pour ce qui est de la sécurité et de l’authentification, nous avons à notre disposition l’ Access Control Service qui permet d’authentifier et d’accréditer un utilisateur. Concernant la communication, le Service Bus est un bus logiciel sur lequel des points de connexion permettent de connecter soit des services soit des clients. Enfin, pour ce qui est des workflow, nous utilisons les Workflow Services afin d’héberger et d’exécuter nos processus directement dans Windows Azure. Workflow Service est basé sur WF (Workflow foundation) du Framework .NET.

clip_image014

Les SQL Services : Il s’agit encore d’une couche logicielle de bas niveau permettant le reporting, l’analyse et le stockage de données. Contrairement à Azure Storage, ils reposent sur SQL Server 2008. On retrouve notamment les SQL Data Services permettant le stockage et le requêtage de données. Notez que les données ne sont pas gérées de manière relationnelle mais hiérarchique.

 

Conclusion

 

Comme vous pourrez le constater, Microsoft a su analyser a la fois le marché et la concurrence afin de nous dévoiler son écosystème Windows Azure. Sa principale force est finalement une symétrie flagrante entre le On Premises que l’on connaissait déjà avant et le On the Cloud de demain tant sur le plan de l’infrastructure, que sur celui du modèle applicatif ou encore concernant la plateforme de développement.

Azure

Premier contact avec les différents types de stockage dans Azure

19. June 2009 by Leonard.LABAT

Vous avez peut être déjà effectués vos premiers pas dans le cloud en créant votre premier site ou service pour Windows Azure. Si ce n’est pas le cas, je vous invite à suivre ce billet de Julien Dollon :

http://blogs.dotnet-france.com/juliend/post/Azure-Introduction-Azure-Services-Platform-(Windows-Azure-NET-Services-Live-Services-SQL-Services).aspx

Dans ce billet, nous allons nous pencher sur l’utilisation des trois types de storage proposés par Azure, à savoir :

  • Les Queues;
  • Les Blobs;
  • Les Tables.

Pour vous présenter tout ça, je vais utiliser un petit exemple tiré du monde de la restauration. Imaginez que vous êtes au restaurant , le Web Role représente le serveur qui vient prendre votre commande. Bien évidemment, le serveur ne va préparer votre commande instantanément sous vos yeux, il va la transmettre au chef (qui est représenté par le Worker Role) qui la traitera dès qu’il en aura fini avec les commandes prises avant la votre.

La communication entre le Web Role (le serveur) et le Worker Role (le chef) se fait via la Queue. Ainsi, comme il s’agit d’une file, les commandes passées par les clients (d’une manière générale, comprenez des tâches), sont traitées par ordre chronologique par le chef.

Enfin, une fois que le chef a fini d’œuvrer, il renvoi le plat en salle. Les différents plats seront stockés dans les Blobs.

On pourra tenir à jour la liste des plats disponibles. Pour se faire, je vais utiliser les Tables.

Maintenant que vous avez pris connaissance de l’exemple que je vais utiliser, on va pouvoir attaquer. Commencez par créer un projet Web & Worker.

 I. Les Queues

Dans cette première partie, nous allons travailler sur la prise de commande (du côté du projet web) et la réception de la commande (du côté du worker).

Commencez par ajouter une page web.

Complétez le formulaire en lui ajoutant quelques petits contrôles :

  • Un champs pour la saisie du nom du plat;
  • Un bouton pour valider la commande;
  • Un label qui donne l'état du serveur (celui du restaurant hein).

<form id="form1" runat="server">
<div>
    <asp:Label ID="lOrderName" runat="server" Text="Order Name : " /><asp:TextBox ID="tbOrderName" runat="server" /><br />
    <asp:Button ID="bTakeOrder" runat="server" Text="OK"
        onclick="bTakeOrder_Click" /><br />
    <asp:Label ID="lWaiterStatus" runat="server" />
</div>
</form>

Avant de pouvoir utiliser la Queue, il faut configurer un peu vos rôles pour qu’ils puissent se connecter au service de stockage.

Ouvrez le fichier ServiceDefinition.csdef et renseignez le comme ci-dessous.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CloudStorageDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole" enableNativeCodeExecution="false">
    <InputEndpoints>
      <!-- Must use port 80 for http and port 443 for https when running in the cloud -->
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
    <ConfigurationSettings>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="QueueStorageEndpoint"/>
    </ConfigurationSettings>
  </WebRole>
  <WorkerRole name="WorkerRole" enableNativeCodeExecution="false">
    <ConfigurationSettings>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="QueueStorageEndpoint"/>
    </ConfigurationSettings>
  </WorkerRole>
</ServiceDefinition>

Occupez vous ensuite du fichier ServiceConfiguration.cscfg. Remarquez deux choses :

  • - Ici, je travaille en local. Vous le savez surement si vous avez déjà eu une première expérience avec Azure, vous disposez en local des outils Development Fabric et Development Storage qui simulent le fonctionnement du cloud. C’est sur ce deuxième outil que vous pouvez récupérer l’adresse et le port du Queue Storage.
  • Vous pouvez utiliser si vous le voulez des configurations différentes pour les deux rôles.
<?xml version="1.0"?>
<ServiceConfiguration serviceName="CloudStorageDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="WebRole">
    <Instances count="1"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
    </ConfigurationSettings>
  </Role>
  <Role name="WorkerRole">
    <Instances count="1"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Maintenant, ajoutez à votre solution le projet StorageClient présent dans les exemples du SDK d’Azure et référencez le dans le projet Web et le Worker.

Ajoutez ensuite dans le code behind de la page Order un champs de type StorageAccountInfo. Ce type est défini dans le projet que vous venez de récupérer. Utilisez ensuite la méthode GetDefaultQueueStorageAccountFromConfiguration() qui, comme son nom l’indique, va venir lire la configuration que vous avez complétée.

StorageAccountInfo storageAccountInfoQueue;

protected void Page_Load(object sender, EventArgs e)
{
    storageAccountInfoQueue = StorageAccountInfo.GetDefaultQueueStorageAccountFromConfiguration();
}

Chargeons nous ensuite de compléter la méthode bTakeOrder_Click. Il faut commencer par récupérer une instance de la classe QueueStorage en utilisant les infos de configuration que nous avons au préalablement récupérés. La QueueStorage est composée de différents MessageQueue identifiable par leur nom. Ainsi, récupérons un de ces MessageQueue que nous appelerons « orders ». Si il n’existe pas (méthode DoesQueueExists()), il faut le créer (méthode CreateQueue()).

Ensuite, nous pouvons simplement ajouter des messages à la Queue grâce à la méthode PutMessage. Pour finir, on met à jour le label du status du serveur.

protected void bTakeOrder_Click(object sender, EventArgs e)
{
    QueueStorage queueStorage = QueueStorage.Create(storageAccountInfoQueue);

    MessageQueue messageQueue = queueStorage.GetQueue("orders");

    if (!messageQueue.DoesQueueExist())
        messageQueue.CreateQueue();

    messageQueue.PutMessage(new Message(tbOrderName.Text));

    lWaiterStatus.Text = "Order sent to chef";
}

Avant de s’attaquer à l’écriture du Worker, on va vérifier que la prise de commande fonctionne correctement. Lancez l’application et passez quelques commandes de test.

 

Nous pouvons voir le contenu de la Queue en utilisant un petit utilitaire disponible sur CodePlex : Azure Storage Explorer (http://azurestorageexplorer.codeplex.com/)

 

Nos commandes ont bien été ajoutées à la Queue !

Passons maintenant au Worker. Je ne reviens pas sur l’initialisation qui est la même que pour le projet Web. Vous pouvez récupérer un message en utilisant simplement la méthode GetMessage(). Son contenu est ensuite accessible via la méthode ContentAsString(). Enfin, on enlève de le message de la Queue avec DeleteMessage(). J’ai ajouté un petit message de log et une temporisation d’une seconde.

public override void Start()
{
    RoleManager.WriteToLog("Information", "Worker Process entry point called");

    StorageAccountInfo storageAccountInfoQueue = StorageAccountInfo.GetDefaultQueueStorageAccountFromConfiguration();
    QueueStorage queueStorage = QueueStorage.Create(storageAccountInfoQueue);
    MessageQueue messageQueue = queueStorage.GetQueue("orders");

    if (!messageQueue.DoesQueueExist())
        messageQueue.CreateQueue();

    while (true)
    {
        Message message = messageQueue.GetMessage();

        if (message != null)
        {
            RoleManager.WriteToLog("Information", "Chef must cook ... " + message.ContentAsString());
            messageQueue.DeleteMessage(message);
        }

        Thread.Sleep(1000);
    }
}

On lance et on jette un coup d’œil au moniteur du Worker dans la Development Fabric.

 

Un petit coup d’œil dans l’Azure Storage Explorer et vous constaterez que la Queue s’est bien vidée de ses messages. Vous pouvez continuer à tester l’application en prenant de nouvelles commandes du côté Web et en constatant qu’elles sont bien traitées une par une du côté du Worker.

Vous pouvez tester au passage le fonctionnement du multi instance des Worker. Modifiez le fichier ServiceConfiguration.cscfg de la manière suivante :

<?xml version="1.0"?>
<ServiceConfiguration serviceName="CloudStorageDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="WebRole">
    <Instances count="1"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
    </ConfigurationSettings>
  </Role>
  <Role name="WorkerRole">
    <Instances count="2"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Lancez l’application et passez rapidement plusieurs commandes. Du côté de la Development Fabric, vous constaterez que les deux instances du Worker se répartissent bien le travail.

 

  II. Les Blobs

Je rappelle que nous utiliserons les blobs pour stocker les plats préparés par le chef. Ces plats seront simplement représentés par une chaine du caractère correspondant au nom du plat.

La récupération du conteneur de blobs se fait de la même manière que pour récupérer une Queue. N’oubliez pas de compléter le fichier de configuration pour pouvoir vous connecter au service de stockage.

StorageAccountInfo storageAccountInfoBlob = StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();
BlobStorage blobStorage = BlobStorage.Create(storageAccountInfoBlob);
BlobContainer blobContainer = blobStorage.GetBlobContainer("dishes");

if(!blobContainer.DoesContainerExist())
    blobContainer.CreateContainer();

Pour ajouter un blob au conteneur, vous devez utiliser la méthode CreateBlob(). Nous devons passer à cette méthode un objet de type BlobProperties et un autre de type BlobContents. Le premier contiendra le nom du blob et le second son contenu que nous devons lui passer en un tableau de byte.

if (message != null)
{
    RoleManager.WriteToLog("Information", "Chef must cook ... " + message.ContentAsString());

    BlobProperties blobProperties = new BlobProperties(message.ContentAsString());
    ASCIIEncoding encoding = new ASCIIEncoding();
    BlobContents blobContents = new BlobContents(encoding.GetBytes(message.ContentAsString()));
    blobContainer.CreateBlob(blobProperties, blobContents, true);
   
    messageQueue.DeleteMessage(message);

    RoleManager.WriteToLog("Information", "Order ready");
}

 

Intéressons nous un peu à la surcharge de la méthode CreateContainer() qui utilise deux paramètres. Le premier concerne l’association de meta data à votre blob. Le second vous permet de rendre le container accessible depuis une url. Essayez la valeur suivante :

blobContainer.CreateContainer(null, ContainerAccessControl.Public);

Si vous vous rendez sur l’URL suivante, vous pourrez voir le contenu du blob : http://127.0.0.1:10000/devstoreaccount1/dishes/Salade
"Salade"

Essayez maintenant en utilisant la valeur Private.

blobContainer.CreateContainer(null, ContainerAccessControl.Private);

Si vous essayez à présent d’accéder à l’URL, vous pourrez lire :

<Error>
<Code>ResourceNotFound</Code>
<Message>The specified resource does not exist.</Message>
</Error>

Par défaut, la valeur utilisée est Private.

Pour en finir avec les blobs, nous allons voir comment les extraire du conteneur. Dans le projet Web, ajoutez une page appelée GetDish. Il faut utiliser la méthode GetBlob() à laquelle il faut passer le nom du blob ainsi que le BlobContents qui devra être complétée.

protected void Page_Load(object sender, EventArgs e)
{
    StorageAccountInfo storageAccountInfoBlob = StorageAccountInfo.GetDefaultBlobStorageAccountFromConfiguration();

    BlobStorage blobStorage = BlobStorage.Create(storageAccountInfoBlob);
    BlobContainer blobContainer = blobStorage.GetBlobContainer("dishes");

    if (!blobContainer.DoesContainerExist())
        blobContainer.CreateContainer(null, ContainerAccessControl.Private);

    string dish = Request.QueryString["dish"];
    BlobContents blobContents =new BlobContents(Response.OutputStream);

    try
    {
        blobContainer.GetBlob(dish, blobContents, false);
    }
    catch(Exception ex)
    {
        Response.StatusCode = 404;
        Response.End();
    }
}

Essayez d’accéder à l’url suivante : http://127.0.0.1:85/GetDish.aspx?dish=Salade. Le contenu du blob s’affiche bien dans la page.

III. Les Tables

Il est temps à présent de parler du dernier type de stockage mis à votre disposition : les tables. Le schéma de fonctionnement des tables est le suivant : chaque table contient une collection d’entités (on peut les assimiler à des lignes dans la table), chacune de ces entités est composée d’une collection de propriétés (on peut les assimiler à des colonnes) et chacune de ses propriétés porte un nom, un type et une valeur. Les types utilisables sont les suivants :

  • Binary
  • Bool
  • DateTime
  • Double
  • GUID
  • Int
  • Long
  • String

Chose importante : une entité doit obligatoirement porter trois propriétés, une partition key, une row key et un timestamp. Les deux premiers forment un identifiant unique pour l’entité. Dans l’exemple suivant, nous utiliserons l’API fournie par le projet StorageClient. Cette API prend en charge le timestamp, nous n’aurons pas à nous en occuper.

Commencez par modifier le fichier de définition et le fichier de configuration.

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="CloudStorageDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WebRole" enableNativeCodeExecution="false">
    <InputEndpoints>
      <!-- Must use port 80 for http and port 443 for https when running in the cloud -->
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
    <ConfigurationSettings>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="BlobStorageEndpoint"/>
      <Setting name="QueueStorageEndpoint"/>
      <Setting name="TableStorageEndpoint"/>
    </ConfigurationSettings>
  </WebRole>
  <WorkerRole name="WorkerRole" enableNativeCodeExecution="false">
    <ConfigurationSettings>
      <Setting name="AccountName"/>
      <Setting name="AccountSharedKey"/>
      <Setting name="BlobStorageEndpoint"/>
      <Setting name="QueueStorageEndpoint"/>
    </ConfigurationSettings>
  </WorkerRole>
</ServiceDefinition>

<?xml version="1.0"?>
<ServiceConfiguration serviceName="CloudStorageDemo" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration">
  <Role name="WebRole">
    <Instances count="1"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="BlobStorageEndpoint" value="http://127.0.0.1:10000"/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
      <Setting name="TableStorageEndpoint" value="http://127.0.0.1:10002"/>
    </ConfigurationSettings>
  </Role>
  <Role name="WorkerRole">
    <Instances count="1"/>
    <ConfigurationSettings>
      <Setting name="AccountName" value="devstoreaccount1"/>
      <Setting name="AccountSharedKey" value="Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="/>
      <Setting name="BlobStorageEndpoint" value="http://127.0.0.1:10000"/>
      <Setting name="QueueStorageEndpoint" value="http://127.0.0.1:10001"/>
    </ConfigurationSettings>
  </Role>
</ServiceConfiguration>

Ensuite, il faut créer la classe qui représentera l’entité plat. On oublie pas de définir les deux propriétés partition key et row key. La classe doit dériver de la classe TableStorageEntity, classe fournie par le projet StorageClient.

public class Dish : TableStorageEntity
{
    public string DishName { get; set; }

    public Dish()
    {
        PartitionKey = "Dishes";
        RowKey = DateTime.Now.Ticks.ToString();
    }
}

Ajoutez maintenant une référence à l’assembly System.Data.Services.Client. Créez une classe RestaurantContext qui dérivera de TableStorageDataServiceContext (qui nous vient encore et toujours de StorageClient). On ajoute la déclaration de la table Dishes.

public class RestaurantContext : TableStorageDataServiceContext
{
    public IQueryable<Dish> Dishes
    {
        get
        {
            return CreateQuery<Dish>("Dishes");
        }
    }
}

Il est maintenant temps de générer les tables représentant les entités que vous venez de définir. Pour se faire, Visual Studio dispose d’un petit bouton magique. Faîtes un clic droit sur le projet Cloud et choisissez « Create Test Storage Tables ».

 

Si vous ouvrez Microsoft SQL Server Management, vous pourrez constater que la table a bien été générée :

 

Attention ! Cette manière de faire ne marche que pour créer les tables en local. Pour pouvoir créer une table sur le cloud, vous devrez passer par le code.

TableStorage.CreateTablesFromModel(typeof(RestaurantContext),
    StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration());

On va maintenant ajouter une petite méthode statique à la classe RestaurantContext histoire de nous faciliter l’ajout d’un plat à la table Dishes.

public static void AddDish(Dish dish)
{
    RestaurantContext restaurantContext = new RestaurantContext();

    restaurantContext.AddObject("Dishes", dish);

    restaurantContext.SaveChanges();
}

On ajoute une page AddDish.aspx. Sur cette page on place une textbox, un bouton et un label.

<asp:TextBox ID="tbDishName" runat="server" />
<asp:Button ID="bAddDish" runat="server" Text="Add" onclick="bAddDish_Click" />
<asp:Label ID="lStatus" runat="server" />

Dans le code behind, on crée un objet de type Dish et on l’insère dans la table.

protected void bAddDish_Click(object sender, EventArgs e)
{
    Dish dish = new Dish()
    {
        DishName = tbDishName.Text
    };

    RestaurantContext.AddDish(dish);

    lStatus.Text = tbDishName.Text + " added";
}

Testez ce nouveau formulaire et admirez le contenu de la table Dishes via Azure Storage Explorer.

 

Dernière chose à faire : récupérer le contenu de la table pour l’afficher dans une liste déroulante sur la page Order.aspx. On ajoute un composant DropDownList et on profite du databinding pour le remplir.

<asp:Label ID="lOrderName" runat="server" Text="Order Name : " /><asp:DropDownList ID="ddlOrderName" runat="server" /><br />
<asp:Button ID="bTakeOrder" runat="server" Text="OK"
    onclick="bTakeOrder_Click" /><br />
<asp:Label ID="lWaiterStatus" runat="server" />

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        RestaurantContext restaurantContext = new RestaurantContext(StorageAccountInfo.GetDefaultTableStorageAccountFromConfiguration());
        ddlOrderName.DataSource = restaurantContext.Dishes;
        ddlOrderName.DataValueField = "DishName";
        ddlOrderName.DataBind();
    }
}

Un petit coup d’œil sur la page Order.aspx et on constate que le contenu de la table est correctement récupéré.

 

Voila, j’espère que ce billet saura vous guider dans vos premiers pas avec les systèmes de stockage mis à disposition par Windows Azure. A bientôt !

C#, Azure , , , ,