A simple distributed App with Azure AppFabric Applications (part 1)–Une application distribuée simple avec Azure AppFabric Applications (1ère partie)

English

Français

AppFabric Applications is feature that just arrived as a CTP in June 2011. It brings a same view of a distributed application model from development to operations, which is part of what is often called devOps. The MSDN documentation about that feature is available at https://msdn.microsoft.com/en-us/library/hh239716.aspx An overview is available at https://www.microsoft.com/windowsazure/appfabric/overview/ Let’s try that with a simple distributed application composed of a web front end, a web service, a database, and a distributed cache. In this part 1, we only try running it in the local environement (only SQL and the cache will run on Azure). In part 2, we will run the whole distributed App on Azure. After having downloaded and installed the AppFabric Visual Studio 2010 tools, we create a new Visual Studio 2010 solution. AppFabric Applications est une fonctionnalité qui vient de sortir en CTP en juin 2011. Elle apporte une vue commune d’une application distribuée sous forme de modèle, que ce soit en développement, ou en exploitation, ce qui est tout à fait dans la tendance devOps. La documentation MSDN à propos de cette fonctionnalité est disponible à https://msdn.microsoft.com/en-us/library/hh239716.aspx Une vue d’ensemble est disponible à https://www.microsoft.com/windowsazure/appfabric/overview/ Essayons cela avec une application distribuée assez simple composée d’un frontal Web, d’un web service, d’une base de données, et d’un cache distribué. Dans cette 1ère parte, on essaie uniquement dans l’environnement local (seuls SQL et le cache distribué tourneront dans Azure). Dans la deuxième partie, on testera l’ensemble de l’application distribuée dans Azure. Après avoir téléchargé et installé les outils AppFabric pour Visual Studio 2010, on crée une nouvelle solution Visual Studio 2010.

 

 

image

image

Let’s add a web service Ajoutons un service web

image

image

image

Let’s relate the ASP.NET Web application to the WCF Web Service. Mettons en relation l’application Web ASP.NET avec le service web WCF

image

image

Let’s also rename the imports so that it makes more sense inside the code renommons également les importations de façon à ce que les noms aient plus de sens dans le code

image

image

NB: in this CTP version, we have to also replace “Import1” by “ImportCache” and “Import2” by “ImportSql” in the ServiceReferences.g.cs C# file NB: dans cette version CTP, il est aussi nécessaire de remplacer “Import1” par “ImportCache” et “Import2”  par “ImportSql” dans le fichier C# ServiceReferences.g.cs

image

Let’s configure the SQL and Cache services so that they correspond to repective targets. First, create a cache namespace Configurons maintenant les services SQL et de cache de façon à ce qu’ils correspondent à leurs cibles respectives. En premier lieu, créons un namepsace pour le cache.

image

image

image

image

Let’s copy the authentication token to the clipboard and paste it in the App Model, in the Cache service properties Copions le jeton d’authentification dans le presse papier et collons-le dans le modèle de l’application, dans les propriétés du service Cache

image

image

let’s do the same for the Cache service URL faisons de même pour l’URL du service Cache

image

image

We’ll do the same for SQL by creating a new SQL Azure database and add its references to the SQL service in the model. The details of how the SQL Azure database is created is not shown here, but you can see it there for instance. Nous allons faire de même pour SQL en créant une nouvelle base de données SQL Azure et ajouter ses références dans le service SQL du modèle. Les détails sur la façon de créer la base SQL Azure n’est pas montré ici, mais vous pourrez la trouver par exemple.

image

the fully qualified DNS name as well as the login and password are used to update the connection string in the app model. Asimple way to get the connection string is to connect from Visual Studio and copy the connection string from the VS connection properties Le nom DNS complet, ainsi que le login et le mot de passe sont utilisés pour mettre à jour la chaîne de connexion dans le modèle de l’application. Un moyen simple d’obtenir la chapine de connexion est aussi de se connecter à la base depuis Visual Studio et de la copier depuis les propriétés de cette connexion

image

image

image

image

image

image

From SQL Server Management Studio 2008 R2, let’s connect to the SQL Azure database and add a table with some data Depuis SQL Server Management Studio 2008 R2, connectons-nous à la base SQL Azure et ajoutons une table avec des données

CREATE TABLE sample_table
(
    c1 int NOT NULL,
    c2 varchar(50) NULL,
    CONSTRAINT PK_sample_table PRIMARY KEY (c1)
)
GO

INSERT INTO sample_table VALUES (1, 'initial value')
GO

image

Let’s now call the SQL Azure database, the WCF Web Service and the AppFabric Cache thru the App model (one of the features brought by app modelling in Appfabric Applications is to get routed to the right services at runtime). In this sample, this is done in the HomeController.cs file: Appelons maintenant la base SQL Azure, le service web WCF et le cache AppFabric via le modèle d’application (une des fonctionnalités qu’apporte la modélisation d’applications dans AppFabric Applications est d’être routé vers les bons services au moment de l’exécution). Dans cet exemple, cela est fait dans le fichier HomeController.cs:

image

The initial code le code initial
  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Web;
  5: using System.Web.Mvc;
  6:  
  7: namespace MVCWebApp.Controllers
  8: {
  9:     [HandleError]
  10:     public class HomeController : Controller
  11:     {
  12:         public ActionResult Index()
  13:         {
  14:             ViewData["Message"] = "Welcome to ASP.NET MVC!";
  15:  
  16:             return View();
  17:         }
  18:  
  19:         public ActionResult About()
  20:         {
  21:             return View();
  22:         }
  23:     }
  24: }
  
is replaced by est remplacé par
  
  1:         public ActionResult Index()
  2:         {
  3:             const string cacheKey = "Message";
  4:  
  5:             string message = null;
  6:             var dataCache = ServiceReferences.CreateImportCache();
  7:  
  8:             string messageFromCache = dataCache.Get(cacheKey) as string;
  9:             if (messageFromCache != null)
  10:             {
  11:                 message = messageFromCache + " (from cache)";
  12:             }
  13:             else
  14:             { // cache miss
  15:  
  16:                 // get data from SQL Azure database
  17:                 using (var sqlConnection = ServiceReferences.CreateImportSql())
  18:                 {
  19:                     using (var sqlCommand = sqlConnection.CreateCommand())
  20:                     {
  21:                         sqlCommand.CommandText = "SELECT c2 from sample_table where c1=1";
  22:                         sqlConnection.Open();
  23:                         message = (string)sqlCommand.ExecuteScalar();
  24:                     }
  25:                 }
  26:  
  27:                 // transform data thru Web Service
  28:                 var wcfService = ServiceReferences.CreateImportWebService();
  29:                 
  30:                 // use a composite type from the Web Service contract definition
  31:                 var compositeType = new AppFabricContainer1.WCFWebService.Service1.CompositeType();
  32:                 compositeType.StringValue = message;
  33:                 compositeType.BoolValue = true;
  34:                 
  35:                 // call the Web Service
  36:                 message = wcfService.GetDataUsingDataContract(compositeType).StringValue + " at " + DateTime.UtcNow.ToLongTimeString();
  37:  
  38:                 //put the message into the cache for next time
  39:                 dataCache.Add(cacheKey, message, new TimeSpan(0, 0, 10)); // 10 seconds
  40:             }
  41:  
  42:             ViewData["Message"] = string.Format("Welcome! Current message is {0}", message);
  43:  
  44:             return View();
  45:         }
The reference to services thru the model are at lines 6, 17 and 28. Let’s now try. NB: in this CTP version, we must start without debugging. Les références aux services à travers le modèle sont aux lignes 6, 17 et 28. Essayons maintenant. NB: dans cette version CTP, nous devons démarrer dans débogage.

image

image

The error is because on my machine, the IIS worker process does not have access to the Internet because it does not have access to the CorpNet proxy. So we try to add a line of code in Global.asax.cs that gives access to the proxy after having stopped the application (CTRL-C in the command window which appeared with the local deployment) L’erreur vient de ce que sur ma machine, les processus de travail IIS n’ont pas accès à Internet parce qu’ils n’ont pas accès au proxy du réseau d’entreprise. Nous essayons donc de donner accès via une ligne de code dans Global.asax.cs après avoir arrêté l’application (CTRL-C dans la fenêtre de ligne de commandes qui est apparue avec le déploiement local)

image

image

  1: System.Net.HttpWebRequest.DefaultWebProxy = new System.Net.WebProxy("europroxy", true);

 

CTRL + F5

 

The following error occurs l’erreur suivante se produit

ErrorCode<ERRCA0017>:SubStatus<ES0006>:There is a temporary failure. Please retry later. (One or more specified cache servers are unavailable, which could be caused by busy network or servers. For on-premises cache clusters, also verify the following conditions. Ensure that security permission has been granted for this client account, and check that the AppFabric Caching Service is allowed through the firewall on all cache hosts. Also the MaxBufferSize on the server must be greater than or equal to the serialized object size sent from the client.)

this is because not only the Web App must access the Internet; the simulated AppFabric container, which is in other processes where we don’t have code also needs access to the Internet. This can be fixed by following what is described at https://msdn.microsoft.com/en-us/library/hh239697.aspx. So let’s stop the application and the container, remove the Global.asax.cs line of code, configure proxy client and let’s restart. NB: in order to shut down the container before resetting IIS, one can do this: - show the compute emulator (start with the Azure icon in the Windows’ systray) - remove the container’s deployment cela vient du fait que l’application Web n’est pas la seule à avoir besoin d’un accès à Internet; le conteneur AppFabric, qui est dans d’autres processus dans lesquels nous n’avons pas de code a lui aussi besoin de cet accès à Internet. Cela peut être corrigé en suivant ce qui est expliqué à https://msdn.microsoft.com/en-us/library/hh239697.aspx. Arrêtons donc l’application et le conteneur, enlevons la ligne de code dans Global.asax, configurons le client proxy et redémarrons. NB: de façon à arrêter le conteneur avant de redémarrer IIS, il est possible de procéder comme suit: - afficher l’émulateur compute (à partir de l’icône du systray Windows) - supprimer le déploiement du conteneur

image

image

So, after having done this and restarted, we get Après avoir fait cela et redémarré, nous avons donc

image

by refreshing the page, we get En rafraîchissant la page, nous avons

image

in this second page the message is composed of: - “initial value” coming from SQL Azure - “valueSuffix” coming from the Web Service - “at 16:55:42” added by the web app - “(from cache)” added by the web app because the second time, the value was retrieved from the distributed cache in Azure. The App.cs model also has other views: Dans cette deuxième page le message est composé comme suit: - “initial value” vient de SQL Azure - “valueSuffix” vient du service web - “at 16:55:42” a été ajouté par l’application Web - “(from cache)” a été ajouté par l’application Web puisque la deuxième fois, la valeur a été récupérée dans le cache distribué Azure. Le modèle App.cs a aussi d’autres vues:

image

image

image

image

In part 2, we’ll deploy this to Azure’s AppFabric and see how it behaves. Dans la 2ème partie, nous déploierons cela dans Azure AppFabric et verrons comment cela se présente.

 

Smile

Benjamin