📜 ⬆️ ⬇️

Quick start of the first project in Windows Azure. Web sites. Website Migration to Cloud Services

Good afternoon, dear colleagues.

The first five parts of the cycle are available here . In this part of the series, we will look at how to migrate our simple website to Cloud Services (ex-Hosted Services) using a simple application that will use the WIndows Azure role model, the Windows Azure Service Bus, and storage services.


Let's consider the following scenario: you have already deployed your web site (for example, a standard ASP.NET MVC 4 web site, which will be further considered) on Windows Azure Web Sites, but after some time you discovered that additional web sites are required functionality - it is necessary that the user can go to your website and upload images to their own gallery. We implement such a scenario with the help of one website functionality, however, the list of requirements also includes the condition of flexible scalability of your website. In the event that you use only Windows Azure Web Sites, you can scale your website only as a whole, which is an inefficient solution - most likely, the main burden will be on image handlers rather than on the user web interface. Migrating the website to Cloud Services and rethinking the architecture based on the Windows Azure Cloud Services role model, as well as using Windows Azure Blob Storage and Service Bus Queues will help create an effective implementation of such a scenario. In this part of the loop, you will create a cloud application, which will consist of two layers:
')
1) Web interface implemented as a web role. On the main page of the application, the user will be able to upload images, as well as view already downloaded images. After the image is loaded, the web role will send the image to the blob storage in the blob container, whose name will be preset to simplify the task, then put the message consisting of a link to the image blob into the Service Bus queue.

2) An image processor implemented as a Worker role. The handler in the infinite loop will poll the Service Bus queue for messages from the Web role, and if there is a message in the queue, pick it up, receive a link to the blob with the image, then use the copy-source blob mechanism to create a new blob with with the same image and put it in the blob storage.

Setup of Cloud Services on the Windows Azure platform


Open http://windows.azure.com in your web browser and log in using your Windows Live ID, which has a Windows Azure account associated with it.

Create a new storage account in which the application data will be stored. In the Windows Azure menu, click New Storage Account . In the Create a New Storage Account dialog box that appears, select your subscription in the Choose a subscription drop-down list. In the Enter a URL text box, type the name of your storage account, for example, <yourname> gallery , where <yourname> is a unique name. Windows Azure uses this value to create the URLs of the vault account services entry points. Select Create or choose an affinity group and click in the Create a new affinity group drop-down list. In the Create a New Affinity Group dialog box, type the name of the affine group in the Affinity Group Name text box, select a location from the drop-down list and click OK. Back in the Create a New Storage Account dialog box, click Create to create a new storage account.

Wait until the end of the initialization process and update the Storage Accounts “tree”. Notice that the Properties panel shows the URL associated with each service in the storage account. Record the public name of the storage account — the first segment of the URL of your entry points. Click the View button , located next to the Primary access key in the Properties panel. In the View Storage Access Keys dialog box, click Copy to Clipboard (next to Primary Access Key) . The copied value will be needed to configure the application.

Create a computational service that will execute the code for your application: in the left pane, click Hosted Services and click the New Hosted Service button located in the menu. In the Create a new Hosted Service dialog box, select your subscription from the Choose a subscription drop-down list. Enter the service name in the Enter a name for your service text box and enter the URL by entering the appropriate value Enter a URL prefix for your service , for example, <yourname> gallery , where < yourname > should be a unique name. Windows Azure uses this value to create a URL for entry points to the service. In the Create or choose an affinity group drop-down list, select the affine group that you created earlier for the storage account. Specify Do not Deploy. Click OK to create the service and wait until the initialization process is complete. Click the Service Bus tab , Access Control & Caching. Click the Service Bus tab . Click New . In the Create a new Service Namespace dialog box that opens, enter the name of your Namespace (for example, mytestservicebus) , select the location region and click Create Namespace. . Select the created namespace and click the View button on the Properties panel in the Default Key field . Copy the Default Issuer and Default Key values ​​from the Default Key dialog box.

Deployment and storage services are configured; Service Bus namespace created.

Configuring an ASP.NET MVC 4 Application


Open Visual Studio 2012 with admin rights.

Click New Project . Select the Web \ ASP.NET MVC 4 Web Application template (Fig. 1). Name the project MVC4Gallery . Select Internet Application and uncheck the option Create a unit test project. Click OK. Wait for the creation of the project.

clip_image001[6]

Fig. 1. List of web project templates in Visual Studio 2012

Right-click on the Models directory . Click Add => Class. In the dialog that opens, enter Image. cs and click OK . Replace the contents of the Image file . cs to the code below.

using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace MVC4Gallery.Models { public class Image { public string Title{ get; set; } public string Link{ get; set; } }} 

Open the Views \ Home \ Index file . cshtml and replace its contents with the code below.

 <header> <div class="content-wrapper"> <div class="float-left"> <p class="site-title">   - </div> </div> </header> <div id="body"> <section class="featured"> <div class="content-wrapper"> <form action="/Home/Upload" method="post" enctype="multipart/form-data"> <label for="title"> <label for="FileData"> </label> <input type="file" id="FileData" name="FileData" /><br /> <input type="submit" value="" /> </form>    "": @foreach (var image in ViewData.Model) { @image.Title <br /> <img width="100" height="100" src="@image.Link" /><br /> } </div> </section> </div> 

Open the file Controllers \ HomeController. cs and replace its contents with the code below. The required dependencies and libraries will be added in the next paragraph.

 using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Web; using System.Web.Mvc; using Microsoft.ServiceBus.Messaging; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient; using MVC4Gallery.Models; namespace MvcApplication1.Controllers { public class HomeController : Controller { public ActionResult Index() { List<Image> images = getBlobs("ourgallery"); return View(images); } [HttpPost] [ActionName("Upload")] public ActionResult Upload(string author, string title) { this.SendBlobToStorage(author); return RedirectToAction("Index"); } public void SendBlobToStorage(string author) { try { HttpPostedFileBase file = Request.Files[0]; CloudBlob blob = getBlobContainer("ourgallery").GetBlobReference(file.FileName); NameValueCollection metadata = new NameValueCollection(); metadata["title"] = file.FileName; blob.UploadFromStream(file.InputStream); BrokeredMessage msg = new BrokeredMessage(blob.Uri.AbsoluteUri); SendBrokeredMessageToServiceBusQueue(msg); } catch (StorageClientException e) { Console.WriteLine("      : " + e.Message); System.Environment.Exit(1); }} public List<Image> getBlobs(string author){ CloudBlobContainer container = getBlobContainer(author); List<Image> images = new List<Image>(); foreach (CloudBlob blob in container.ListBlobs()) { blob.FetchAttributes(); Image image = new Image(); image.Link = blob.Uri.AbsoluteUri; image.Title = blob.Metadata["title"]; images.Add(image); } return images; } public static CloudBlobContainer getBlobContainer(string userId) { var account = CloudStorageAccount.FromConfigurationSetting("storageaccount"); CloudBlobContainer container = account.CreateCloudBlobClient().GetContainerReference(userId); container.CreateIfNotExist(); var permissions = container.GetPermissions(); permissions.PublicAccess = BlobContainerPublicAccessType.Container; container.SetPermissions(permissions); return container; } public static void SendBrokeredMessageToServiceBusQueue(BrokeredMessage msg) { QueueDescription qd = new QueueDescription("servicebustest"); qd.MaxSizeInMegabytes = 5120; qd.DefaultMessageTimeToLive = new TimeSpan(0, 1, 0); string connectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); QueueClient Client = QueueClient.CreateFromConnectionString(connectionString, "servicebustest"); Client.Send(msg); }}} 


Right-click on the References directory . Select Add Reference . In the dialog that opens (pic. 3), select the following assemblies:

Microsoft.WindowsAzure.StorageClient 1.7.0.0
Microsoft.WindowsAzure.Configuration 1.7.0.0
Microsoft.WindowsAzure.ServiceRuntime 1.7.0.0
Microsoft.ServiceBus 1.7.0.0
System.Runtime.Serialization 4.0.0.0

clip_image003[4]
Fig. 3. Selection of assemblies for the project.

Open the Global file . asax and add the code below to the Application _ Start () method.

 CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) => { var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName); configSettingPublisher(connectionString); }); 


Right click on the project . Select Add Windows Azure Cloud Service Project (Figure 4).

clip_image005[4]
Fig. 4. Add a cloud project to the solution

Right-click on Roles in the created MVC 4 Gallery project . Azure . Select Add . Click the New Worker Role Project (Figure 5).

clip_image006[4]
Fig. 5. Adding a project for the Worker role to the solution

In Windows Azure Tools 1.7 , a new Worker-role template has been added, already configured to use the Service Bus. In the Add New Role Project window, select Worker Role with Service Bus Queue and click Add (Figure 6).

clip_image008[4]
Fig. 6. Adding a Worker Role Project Configured to Use Service Bus Queue

Open the WorkerRole.cs file and replace its contents with the code below.

 using System; using System.Collections.Specialized; using System.Diagnostics; using System.Net; using System.Threading; using Microsoft.ServiceBus; using Microsoft.ServiceBus.Messaging; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.StorageClient; namespace WorkerRoleWithSBQueue1 { public class WorkerRole : RoleEntryPoint { // The name of your queue const string QueueName = "servicebustest"; // QueueClient is thread-safe. Recommended that you cache // rather than recreating it on every request QueueClient Client; bool IsStopped; public override void Run() { while (!IsStopped) { try { //   BrokeredMessage receivedMessage = null; receivedMessage = Client.Receive(); if (receivedMessage != null) { //  .       ,      ,     . GetBlobFromStorage("ourgallery", receivedMessage.GetBody<string>()); receivedMessage.Complete(); }} catch (MessagingException e) { if (!e.IsTransient) { Trace.WriteLine(e.Message); throw; } Thread.Sleep(10000); } catch (OperationCanceledException e) { if (!IsStopped) { Trace.WriteLine(e.Message); throw; }}}} public override bool OnStart() { CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSettingPublisher) => { var connectionString = RoleEnvironment.GetConfigurationSettingValue(configName); configSettingPublisher(connectionString); }); //      ServicePointManager.DefaultConnectionLimit = 12; //     ,      string sbconnectionString = CloudConfigurationManager.GetSetting("Microsoft.ServiceBus.ConnectionString"); var namespaceManager = NamespaceManager.CreateFromConnectionString(sbconnectionString); if (!namespaceManager.QueueExists(QueueName)) { namespaceManager.CreateQueue(QueueName); } //     Service Bus Client = QueueClient.CreateFromConnectionString(sbconnectionString, QueueName); IsStopped = false; return base.OnStart(); } public override void OnStop() { //     Service Bus IsStopped = true; Client.Close(); base.OnStop(); } public void GetBlobFromStorage(string author, string title) { try { CloudBlob sourceBlob = getBlobContainer("ourgallery").GetBlobReference(title); CloudBlob newBlob = getBlobContainer("ourgallery").GetBlobReference(title + "small_copy"); newBlob.CopyFromBlob(sourceBlob); NameValueCollection metadata = new NameValueCollection(); metadata["title"] = title + "small_copy"; } catch (StorageClientException e) { Console.WriteLine(" : " + e.Message); System.Environment.Exit(1); }} public static CloudBlobContainer getBlobContainer(string userId) { var account = CloudStorageAccount.FromConfigurationSetting("storageaccount"); CloudBlobContainer container = account.CreateCloudBlobClient().GetContainerReference(userId); container.CreateIfNotExist(); return container; }}} 

Add the WebRole.cs file to the MVC4Gallery project and replace its contents with the code below.

 using System; using System.Collections.Generic; using System.Linq; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.Diagnostics; using Microsoft.WindowsAzure.ServiceRuntime; using Microsoft.WindowsAzure.StorageClient; namespace MVC4Gallery { public class WebRole : RoleEntryPoint { public override bool OnStart() { RoleEnvironment.Changing += RoleEnvironmentChanging; return base.OnStart(); } private void RoleEnvironmentChanging(object sender, RoleEnvironmentChangingEventArgs e) { if (e.Changes.Any(change => change is RoleEnvironmentConfigurationSettingChange)) { e.Cancel = true; }}}} 

Double-click with the right mouse button on the MVC 4 Gallery in the Roles cloud project in order to open the graphical user interface of the web-role (Fig. 7).

clip_image010[4]
Fig. 7. Graphical Web Role Management Interface

On the Configuration tab, uncheck the Enable Diagnostics option . Go to the Settings tab, click Add Setting and create a new configuration setting named storageaccount . Specify its type as a Connection String, then click on the button with the ellipsis and configure the connection string. The required data was recorded in Part 1. Click Add Setting and enter the name Microsoft.ServiceBus.ConnectionString (type - String) , and then insert the following line in the Value field:

Endpoint = sb: // [namespacename] .servicebus.windows.net; SharedSecretIssuer = owner; SharedSecretValue = [DefaultKey]

Where is the namespace name for the Endpoint part , Default Issuer for SharedSecretIssuer and Default Key for SharedSecretValue . Click OK. Double-right-click on WorkerRoleWithSBQueue 1 in the Roles cloud project to open the Worker-role graphical user interface.

On the Configuration tab, uncheck the Enable Diagnostics option . Go to the Settings tab, click Add Setting and create a new configuration setting named storageaccount . Specify its type as a Connection String, then click on the button with the ellipsis and configure the connection string. The required data was recorded in Part 1. Click OK. Paste the required values ​​into the connection string to customize the Microsoft.ServiceBus.ConnectionString. The required data was recorded in Part 1 - the name of the namespace for the Endpoint part , Default Issuer for SharedSecretIssuer and Default Key for SharedSecretValue . Save the changes and close the GUI for managing the Worker role.

Run the project by pressing F5. The project will start in the local compute emulator and launch the browser with the Home / Index view .

Select an image and click Save . After loading the image, the page will refresh. Please note that at the moment only one image is shown - the one that you downloaded. After a while (just a few seconds is enough) refresh the page - it will take the image handler to interrogate the queue, receive a message from the web role, load a blob, create a copy of it and put a new blob in the repository.

Deploying an ASP.NET MVC 4 application to Windows Azure platform in Cloud Services from Visual Studio 2012



In order to deploy the application to Cloud Services on the Windows Azure platform, you need to adjust the publishing functionality in Visual Studio 2012 accordingly.

Right-click on the MVC 4 Gallery cloud project . Azure. Click Publish . In the dialog that opens, expand the list under Choose your subscription and select <Manage ...> (fig. 12).

clip_image012[4]
Fig. 12.

In the Windows Azure Cloud Service Project Management dialog that opens, click New. Enter any convenient name for the new certificate that will be used to deploy the application. Click Ok Click the Copy the full path link . Navigate to the Windows Azure Management Portal. Click the Hosted Services, Storage Accounts & CDN tab . . Click on the Management Certificates tab . . On the Management Certificates tab, click Add Certificate . In the Add New Management Certificate dialog box that opens, click Browse and paste the path to the certificate from the Visual Studio to the File Name field. Click Open. Click Ok. Go to the Hosted Services tab and copy the Subscription ID from the Properties panel. Go to Visual Studio 2012. Paste the copied subscription ID into the appropriate field (Figure 13). Click OK .

clip_image014[4]
Fig. 13.

Click Close . Click Next. On the Windows Azure Publish Settings page , you can configure advanced deployment options. Click Publish. You can observe the deployment process in the Windows Azure Activity Log view (Figure 14).

clip_image016[4]
Fig. 14. Presentation of Windows Azure Activity Log

Go to the Windows Azure Management Portal to the Hosted Services tab . Select the deployed application and click the link in the DNS Name field on the Properties panel to go to the website (Fig. 15).
clip_image018
Fig. 15. Windows Azure Management Portal

Note that the site looks the same as after deploying it to a local computing emulator. This is due to the fact that in both cases the real storage of Windows Azure is used. Add a new image and observe the result.

Source: https://habr.com/ru/post/150418/


All Articles