Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Resolving merge conflict.

  • Loading branch information...
commit 47e72f0a7600e7c3770473494615874b9a205f12 2 parents 3b07f22 + 38b09bd
Alma Jenks v-aljenk authored
Showing with 1,595 additions and 97 deletions.
  1. +0 −1  articles/0-markdown-template-for-new-articles.md
  2. +620 −0 articles/cdn-cloud-service-with-cdn.md
  3. +256 −0 articles/cdn-serve-content-from-cdn-in-your-web-application.md
  4. +411 −0 articles/hdinsight-mahout.md
  5. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-1-browser-access.PNG
  6. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-2-home-page.PNG
  7. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-5-memegenerator.PNG
  8. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-6-addview.PNG
  9. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-7-configureview.PNG
  10. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-1-new-project.PNG
  11. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-10-createcdn.png
  12. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-11-disablequerya.png
  13. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-12-disablequeryb.png
  14. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-13-testcdn.png
  15. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-2-select-role.PNG
  16. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-3-mvc-template.PNG
  17. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-4-publish-a.png
  18. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-5-publish-signin.png
  19. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-6-publish-signedin.png
  20. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-7-publish-createserviceandstorage.png
  21. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-8-publish-finalize.png
  22. BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-9-published.png
  23. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-mvc-1-accountkey.PNG
  24. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-1.PNG
  25. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-10.PNG
  26. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-blob.PNG
  27. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-cdn.PNG
  28. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequerya.PNG
  29. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequeryb.PNG
  30. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2.PNG
  31. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-fail.PNG
  32. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-succeed.PNG
  33. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-4.PNG
  34. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-5.PNG
  35. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-6.PNG
  36. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-7.PNG
  37. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-8.PNG
  38. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-9.PNG
  39. BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-updates-1.PNG
  40. BIN  articles/media/hdinsight-mahout/connect.png
  41. BIN  articles/media/hdinsight-mahout/enableremote.png
  42. BIN  articles/media/hdinsight-mahout/hadoopcli.png
  43. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/browse_vm_preview_portal.png
  44. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/connect_vm_preview_portal.png
  45. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/create_vm_preview_portal.png
  46. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/image_gallery_preview_portal.png
  47. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/new_button_preview_portal.png
  48. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/vm_diagnostics_status_preview_portal.png
  49. BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/vm_startboard_preview_portal.png
  50. +1 −63 articles/mobile-services-android-get-started-users.md
  51. +78 −0 articles/mobile-services-dotnet-backend-android-get-started-users.md
  52. +9 −1 articles/mobile-services-dotnet-backend-calling-sharepoint-on-behalf-of-user.md
  53. +5 −1 articles/mobile-services-dotnet-backend-ios-get-started-users.md
  54. +5 −1 articles/mobile-services-dotnet-backend-windows-phone-get-started-users.md
  55. +8 −3 articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users.md
  56. +5 −1 articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users.md
  57. +1 −1  articles/mobile-services-dotnet-backend-xamarin-android-get-started-users.md
  58. +7 −2 articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users.md
  59. +0 −2  articles/mobile-services-windows-phone-handling-conflicts-offline-data.md
  60. +0 −1  articles/mobile-services-windows-store-dotnet-adal-sso-authentication.md
  61. +0 −2  articles/mobile-services-windows-store-dotnet-handling-conflicts-offline-data.md
  62. +2 −2 articles/virtual-machines-create-custom.md
  63. +0 −1  articles/virtual-machines-create-upload-vhd-windows-server.md
  64. +2 −2 articles/virtual-machines-install-symantec.md
  65. +2 −2 articles/virtual-machines-install-trend.md
  66. +95 −0 articles/virtual-machines-windows-tutorial-azure-preview.md
  67. +5 −1 articles/virtual-machines-windows-tutorial.md
  68. +2 −0  includes/CreateVirtualMachineWindowsTutorial.md
  69. +8 −0 includes/free-trial-note.md
  70. BIN  includes/media/virtual-machines-create-WindowsVM/agent-and-extensions.png
  71. BIN  includes/media/virtual-machines-create-WindowsVM/chooseimage.png
  72. BIN  includes/media/virtual-machines-create-WindowsVM/commandbarnew.png
  73. BIN  includes/media/virtual-machines-create-WindowsVM/resourceconfiguration.png
  74. BIN  includes/media/virtual-machines-create-WindowsVM/vmconfiguration.png
  75. BIN  includes/media/virtual-machines-create-WindowsVM/vmcreated.png
  76. +64 −0 includes/mobile-services-android-authenticate-app.md
  77. +9 −10 includes/virtual-machines-create-WindowsVM.md
1  articles/0-markdown-template-for-new-articles.md
View
@@ -1,4 +1,3 @@
-<properties title="required" pageTitle="required" description="required" metaKeywords="" services="" solutions="" documentationCenter="" authors="" videoId="" scriptId="" />
<!--This is a basic template that shows you how to use mark down to create a topic that includes a TOC, sections with subheadings, links to other azure.microsoft.com topics, links to other sites, bold text, italic text, numbered and bulleted lists, code snippets, and images. For fancier markdown, find a published topic and copy the markdown or HTML you want. For more details about using markdown, see http://sharepoint/sites/azurecontentguidance/wiki/Pages/Content%20Guidance%20Wiki%20Home.aspx.-->
<!--Properties section (above): this is required in all topics. Please fill it out!-->
620 articles/cdn-cloud-service-with-cdn.md
View
@@ -0,0 +1,620 @@
+<properties linkid="cdn-cloud-service-with-cdn" urlDisplayName="Integrate a cloud application with Azure CDN" pageTitle="Integrate a cloud application with Azure CDN" metaKeywords="Azure tutorial, Azure web app tutorial, ASP.NET, CDN, MVC, cloud service" description="A tutorial that teaches you how to deploy a cloud application that serves content from an integrated Azure CDN endpoint" metaCanonical="" services="cdn" documentationCenter=".NET" title="Integrate a cloud application with Azure CDN" authors="cephalin" solutions="" manager="wpickett" editor="tysonn" />
+
+<a name="intro"></a>
+# Integrate a cloud application with Azure CDN #
+***By [Cephas Lin](https://twitter.com/Cephas_MSFT) Updated 18 July 2014.***
+
+Azure CDN can be integrated with a cloud service, serving any content from the cloud service's CDN directory. This approach gives you the following advantages:
+
+- Easily deploy and update images, scripts, and stylesheets in your cloud application's project directories
+- Easily upgrade the NuGet packages in your cloud application, such as jQuery or Bootstrap versions
+- Manage your Web application and your CDN-served content all from the same Visual Studio interface
+- Unified deployment workflow for your Web application and your CDN-served content
+- Integrate ASP.NET bundling and minification with Azure CDN
+
+## What you will learn ##
+
+In this tutorial, you will learn how to:
+
+- [Integrate an Azure CDN endpoint with your cloud application and serve static content in your Web pages from Azure CDN](#deploy)
+- [Configure cache settings for static content in your cloud application](#caching)
+- [Serve content from controller actions through Azure CDN](#controller)
+- [Serve bundled and minified content through Azure CDN while preserving the script debugging experience in Visual Studio](#bundling)
+- [Configure fallback your scripts and CSS when your Azure CDN is offline](#fallback)
+
+## What you will build ##
+
+You will deploy a cloud service Web role using the default ASP.NET MVC template, add code to serve content from an integrated Azure CDN, such as an image, controller action results, and the default JavaScript and CSS files, and also write code to configure the fallback mechanism for bundles served in the event that the CDN is offline.
+
+## What you will need ##
+
+This tutorial has the following prerequisites:
+
+- An active [Microsoft Azure account](http://azure.microsoft.com/en-us/account/)
+- Visual Studio 2013 with [Azure SDK](http://go.microsoft.com/fwlink/p/?linkid=323510&clcid=0x409)
+
+<div class="wa-note">
+ <span class="wa-icon-bulb"></span>
+ <h5><a name="note"></a>You need an Azure account to complete this tutorial:</h5>
+ <ul>
+ <li>You can <a href="http://azure.microsoft.com/en-us/pricing/free-trial/?WT.mc_id=A261C142F">open an Azure account for free</a> - You get credits you can use to try out paid Azure services, and even after they're used up you can keep the account and use free Azure services, such as Web Sites.</li>
+ <li>You can <a href="http://azure.microsoft.com/en-us/pricing/member-offers/msdn-benefits-details/?WT.mc_id=A261C142F">activate MSDN subscriber benefits</a> - Your MSDN subscription gives you credits every month that you can use for paid Azure services.</li>
+ <ul>
+</div>
+
+<a name="deploy"></a>
+## Deploy a cloud application with an integrated CDN endpoint ##
+
+In this section, you will deploy the default ASP.NET MVC application template in Visual Studio 2013 to a cloud service Web role, and then integrate it with a new CDN endpoint. Follow the instructions below:
+
+1. In Visual Studio 2013, create a new Azure cloud service from the menu bar by going to **File > New > Project > Cloud > Windows Azure Cloud Service**. Give it a name and click **OK**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-1-new-project.PNG)
+
+2. Select **ASP.NET Web Role** and click the **>** button. Click OK.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-2-select-role.PNG)
+
+3. Select **MVC** and click **OK**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-3-mvc-template.PNG)
+
+4. Now, publish this Web role to an Azure cloud service. Right-click the cloud service project and select **Publish**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-4-publish-a.png)
+
+5. If you have not yet signed into Microsoft Azure, click the **Sign In** button.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-5-publish-signin.png)
+
+6. In the sign-in page, sign in with the Microsoft account you used to activate your Azure account.
+7. One you're signed in, click **Next**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-6-publish-signedin.png)
+
+8. Assuming that you haven't created a cloud service or storage account, Visual Studio will help you create both. In the **Create Cloud Service and Account** dialog, type the desired service name. Then, click **Create**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-7-publish-createserviceandstorage.png)
+
+ >[WACOM.NOTE]Note that I'm using **East Asia** as the region for this cloud service. My goal here is to make sure that the cloud service (and the content in the storage account) is far enough away from the client (in this case, my computer in the US) to test the CDN later.
+9. In the publish settings page, verify the configuration and click **Publish**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-8-publish-finalize.png)
+
+ >[WACOM.NOTE] The publishing process for cloud services takes a long time. The Enable Web Deploy for all roles option can make debugging your cloud application much quicker by providing fast (but temporary) updates to your Web roles. For more information on this option, see [Publishing a Cloud Service using the Azure Tools](http://msdn.microsoft.com/en-us/library/ff683672.aspx).
+
+ When the **Windows Azure Activity Log** shows that publishing status is **Completed**, you will create a CDN endpoint that's integrated with this cloud service.
+
+1. To create a CDN endpoint, log into your [Azure management portal](http://manage.windowsazure.com/).
+2. Click **New** > **App Services** > **CDN** > **Quick Create**. Select **http://*&lt;servicename>*.cloudapp.net/cdn/** and click **Create**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-10-createcdn.png)
+
+ >[WACOM.NOTE] Once your CDN endpoint is created, the Azure portal will show you its URL and the origin domain that it's integrated with. However, it can take awhile for the new CDN endpoint's configuration to be fully propagated to all the CDN node locations.
+
+ Note that the CDN endpoint is tied to the path **cdn/** of your cloud service. You can either create a **cdn** folder in your **WebRole1** project, or you can use URL rewrite to strip all incoming links of this path. In this tutorial, you will take the latter route.
+
+3. Back in the Azure portal, in the **CDN** tab, click the name of the CDN endpoint you just created.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-11-disablequerya.png)
+
+3. Click **Enable Query String** to enable query strings in the CDN cache. Once you enable this, the same link accessed with different query strings will be cached as separate entries.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-12-disablequeryb.png)
+
+ >[WACOM.NOTE] While enabling the query string is not necessary for this tutorial section, you want to do this as early as possible for convenience since any change here is going to take time to propagate to all the CDN nodes, and you don't want any non-query-string-enabled content to clog up the CDN cache (updating CDN content will be discussed later).
+
+3. Ping your CDN endpoint to make sure that it's propagated to the CDN nodes. You may need to wait up to an hour before it will respond to pings.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-13-testcdn.png)
+
+2. Back in Visual Studio 2013, open **Web.config** in your **WebRole1** project and add the following code into the `<system.webServer>` tag:
+ <pre class="prettyprint">
+ &lt;system.webServer&gt;
+ <mark>&lt;rewrite&gt;
+ &lt;rules&gt;
+ &lt;rule name=&quot;RewriteIncomingCdnRequest&quot; stopProcessing=&quot;true&quot;&gt;
+ &lt;match url=&quot;^cdn/(.*)$&quot;/&gt;
+ &lt;action type=&quot;Rewrite&quot; url=&quot;{R:1}&quot;/&gt;
+ &lt;/rule&gt;
+ &lt;/rules&gt;
+ &lt;/rewrite&gt;</mark>
+ ...
+ &lt;/system.webServer&gt;
+ </pre>
+
+4. Publish the cloud service again. Right-click the cloud service project and select **Publish**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-cs-4-publish-a.png)
+
+1. When the publishing status is **Completed**, open a browser window and navigate to **http://*&lt;cdnName>*.vo.msecnd.net/Content/bootstrap.css**. In my setup, this URL is:
+
+ http://az632148.vo.msecnd.net/Content/bootstrap.css
+
+ Which corresponds to the following origin URL at the CDN endpoint:
+
+ http://cephalinservice.cloudapp.net/cdn/Content/bootstrap.css
+
+ After URL rewrite in my Web app, the actual file that gets cached to my CDN cache is:
+
+ http://cephalinservice.cloudapp.net/Content/bootstrap.css
+
+ When you navigate to **http://*&lt;cdnName>*.vo.msecnd.net/Content/bootstrap.css**, you will be prompted to download the bootstrap.css that came from your published Web app.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-1-browser-access.PNG)
+
+You can similarly access any publicly accessible URL at **http://*&lt;serviceName>*.cloudapp.net/**, straight from your CDN endpoint. For example:
+
+- A .js file from the /Script path
+- Any content file from the /Content path
+- Any controller/action
+- If the query string is enabled at your CDN endpoint, any URL with query strings
+
+In fact, with the above configuration, you can host the entire cloud application from **http://*&lt;cdnName>*.vo.msecnd.net/**. If I navigate to **http://az632148.vo.msecnd.net/**, I get the action result from Home/Index.
+
+![](media/cdn-cloud-service-with-cdn/cdn-2-home-page.PNG)
+
+This does not mean, however, that it's always a good idea (or generally a good idea) to serve an entire cloud application through Azure CDN. Some of the caveats are:
+
+- This approach requires your entire site to be public, because Azure CDN cannot serve any private content.
+- If the CDN endpoint goes offline for any reason, whether scheduled maintenance or user error, your entire cloud application goes offline unless the customers can be redirected to the origin URL **http://*&lt;serviceName>*.cloudapp.net/**.
+- Even with the custom Cache-Control settings (see [Configure caching options for static files in your cloud application](#caching)), a CDN endpoint does not improve the performance of highly-dynamic content. If you tried to load the home page from your CDN endpoint as shown above, notice that it took at least 5 seconds to load the default home page the first time, which is a fairly simple page. Imagine what would happen to the client experience if this page contains dynamic content that must update every minute. Serving dynamic content from a CDN endpoint requires short cache expiration, which translates to frequent cache misses at the CDN endpoint. This hurts the performance or your cloud application and defeats the purpose of a CDN.
+
+The alternative is to determine which content to serve from Azure CDN on a case-by-case basis in your cloud application. To that end, you have already seen how to access individual content files from the CDN endpoint. I will show you how to serve a specific controller action through the CDN endpoint in [Serve content from controller actions through Azure CDN](#controller).
+
+You can specify a more restrictive URL rewrite rule to limit the content accessible through your CDN endpoint. For example, to limit URL rewrite to the *\Scripts* folder, change the above rewrite rule as follows:
+<pre class="prettyprint">
+&lt;rule name=&quot;RewriteIncomingCdnRequest&quot; stopProcessing=&quot;true&quot;&gt;
+ &lt;match url=&quot;^cdn/<mark>Scripts/</mark>(.*)$&quot;/&gt;
+ &lt;action type=&quot;Rewrite&quot; url=&quot;<mark>Scripts/</mark>{R:1}&quot;/&gt;
+&lt;/rule&gt;
+</pre>
+
+<a name="caching"></a>
+## Configure caching options for static files in your cloud application ##
+
+With Azure CDN integration in your cloud application, you can specify how you want static content to be cached in the CDN endpoint. To do this, open *Web.config* from your Web role project (e.g. WebRole1) and add a `<staticContent>` element to `<system.webServer>`. The XML below configures the cache to expire in 3 days.
+<pre class="prettyprint">
+&lt;system.webServer&gt;
+ <mark>&lt;staticContent&gt;
+ &lt;clientCache cacheControlMode=&quot;UseMaxAge&quot; cacheControlMaxAge=&quot;3.00:00:00&quot;/&gt;
+ &lt;/staticContent&gt;</mark>
+ ...
+&lt;/system.webServer&gt;
+</pre>
+
+Once you do this, all static files in your cloud application will observe the same rule in your CDN cache. For more granular control of cache settings, add a *Web.config* file into a folder and add your settings there. For example, add a *Web.config* file to the *\Content* folder and replace the content with the following XML:
+
+ <?xml version="1.0"?>
+ <configuration>
+ <system.webServer>
+ <staticContent>
+ <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="15.00:00:00"/>
+ </staticContent>
+ </system.webServer>
+ </configuration>
+
+This setting causes all static files from the *\Content* folder to be cached for 15 days.
+
+For more information on how to configure the `<clientCache>` element, see [Client Cache &lt;clientCache>](http://www.iis.net/configreference/system.webserver/staticcontent/clientcache).
+
+In [Serve content from controller actions through Azure CDN](#controller), I will also show you how you can configure cache settings for controller action results in the CDN cache.
+
+<a name="controller"></a>
+## Serve content from controller actions through Azure CDN ##
+
+When you integrate a cloud service Web role with Azure CDN, it is relatively easy to serve content from controller actions through the Azure CDN. Other than serving your cloud application directly through Azure CDN (demonstrated above), [Maarten Balliauw](https://twitter.com/maartenballiauw) shows you how to do it with a fun MemeGenerator controller in [Reducing latency on the web with the Windows Azure CDN](http://channel9.msdn.com/events/TechDays/Techdays-2014-the-Netherlands/Reducing-latency-on-the-web-with-the-Windows-Azure-CDN). I will simply reproduce it here.
+
+Suppose in your cloud application you want to generate memes based on a Chuck Norris image like this:
+
+![](media/cdn-cloud-service-with-cdn/cdn-5-memegenerator.PNG)
+
+You have a simple `Index` action that allows the customers to specify the superlatives in the image, then generates the meme once they post to the action. Since it's Chuck Norris, you would expect this page to become wildly popular globally. This is a good example of serving semi-dynamic content with Azure CDN.
+
+Follow the steps above to setup this controller action:
+
+1. In the *\Controllers* folder, create a new .cs file called *MemeGeneratorController.cs* and replace the content with the following code. Be sure to replace the highlighted portion with your CDN name.
+ <pre class="prettyprint">
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Drawing;
+ using System.IO;
+ using System.Net;
+ using System.Web.Hosting;
+ using System.Web.Mvc;
+ using System.Web.UI;
+
+ namespace WebRole1.Controllers
+ {
+ public class MemeGeneratorController : Controller
+ {
+ static readonly Dictionary<string, Tuple<string ,string>> Memes = new Dictionary<string, Tuple<string, string>>();
+
+ public ActionResult Index()
+ {
+ return View();
+ }
+
+ [HttpPost, ActionName(&quot;Index&quot;)]
+ public ActionResult Index_Post(string top, string bottom)
+ {
+ var identifier = Guid.NewGuid().ToString();
+ if (!Memes.ContainsKey(identifier))
+ {
+ Memes.Add(identifier, new Tuple&lt;string, string&gt;(top, bottom));
+ }
+
+ return Content(&quot;&lt;a href=\&quot;&quot; + Url.Action(&quot;Show&quot;, new {id = identifier}) + &quot;\&quot;&gt;here&#39;s your meme&lt;/a&gt;&quot;);
+ }
+
+
+ [OutputCache(VaryByParam = &quot;*&quot;, Duration = 1, Location = OutputCacheLocation.Downstream)]
+ public ActionResult Show(string id)
+ {
+ Tuple<string, string> data = null;
+ if (!Memes.TryGetValue(id, out data))
+ {
+ return new HttpStatusCodeResult(HttpStatusCode.NotFound);
+ }
+
+ if (Debugger.IsAttached) // Preserve the debug experience
+ {
+ return Redirect(string.Format(&quot;/MemeGenerator/Generate?top={0}&bottom={1}&quot;, data.Item1, data.Item2));
+ }
+ else // Get content from Azure CDN
+ {
+ return Redirect(string.Format(&quot;http://<mark>&lt;cdnName&gt;</mark>.vo.msecnd.net/MemeGenerator/Generate?top={0}&amp;bottom={1}&quot;, data.Item1, data.Item2));
+ }
+ }
+
+ [OutputCache(VaryByParam = "*", Duration = 3600, Location = OutputCacheLocation.Downstream)]
+ public ActionResult Generate(string top, string bottom)
+ {
+ string imageFilePath = HostingEnvironment.MapPath(&quot;~/Content/chuck.bmp&quot;);
+ Bitmap bitmap = (Bitmap)Image.FromFile(imageFilePath);
+
+ using (Graphics graphics = Graphics.FromImage(bitmap))
+ {
+ SizeF size = new SizeF();
+ using (Font arialFont = FindBestFitFont(bitmap, graphics, top.ToUpperInvariant(), new Font("Arial Narrow", 100), out size))
+ {
+ graphics.DrawString(top.ToUpperInvariant(), arialFont, Brushes.White, new PointF(((bitmap.Width - size.Width) / 2), 10f));
+ }
+ using (Font arialFont = FindBestFitFont(bitmap, graphics, bottom.ToUpperInvariant(), new Font("Arial Narrow", 100), out size))
+ {
+ graphics.DrawString(bottom.ToUpperInvariant(), arialFont, Brushes.White, new PointF(((bitmap.Width - size.Width) / 2), bitmap.Height - 10f - arialFont.Height));
+ }
+ }
+
+ MemoryStream ms = new MemoryStream();
+ bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
+ return File(ms.ToArray(), &quot;image/png&quot;);
+ }
+
+ private Font FindBestFitFont(Image i, Graphics g, String text, Font font, out SizeF size)
+ {
+ // Compute actual size, shrink if needed
+ while (true)
+ {
+ size = g.MeasureString(text, font);
+
+ // It fits, back out
+ if (size.Height < i.Height &&
+ size.Width < i.Width) { return font; }
+
+ // Try a smaller font (90% of old size)
+ Font oldFont = font;
+ font = new Font(font.Name, (float)(font.Size * .9), font.Style);
+ oldFont.Dispose();
+ }
+ }
+ }
+ }
+ </pre>
+
+2. Right-click in the default `Index()` action and select **Add View**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-6-addview.PNG)
+
+3. Accept the settings below and click **Add**.
+
+ ![](media/cdn-cloud-service-with-cdn/cdn-7-configureview.PNG)
+
+4. Open the new *Views\MemeGenerator\Index.cshtml* and replace the content with the following simple HTML for submitting the superlatives:
+
+ <h2>Meme Generator</h2>
+
+ <form action="" method="post">
+ <input type="text" name="top" placeholder="Enter top text here" />
+ <br />
+ <input type="text" name="bottom" placeholder="Enter bottom text here" />
+ <br />
+ <input class="btn" type="submit" value="Generate meme" />
+ </form>
+
+5. Publish the cloud application again and navigate to **http://*&lt;serviceName>*.cloudapp.net/MemeGenerator/Index** in your browser.
+
+When you submit the form values to `/MemeGenerator/Index`, the `Index_Post` action method returns a link to the `Show` action method with the respective input identifier. When you click the link, you reach the following code:
+<pre class="prettyprint">
+[OutputCache(VaryByParam = &quot;*&quot;, Duration = 1, Location = OutputCacheLocation.Downstream)]
+public ActionResult Show(string id)
+{
+ Tuple<string, string> data = null;
+ if (!Memes.TryGetValue(id, out data))
+ {
+ return new HttpStatusCodeResult(HttpStatusCode.NotFound);
+ }
+
+ if (Debugger.IsAttached) // Preserve the debug experience
+ {
+ return Redirect(string.Format(&quot;/MemeGenerator/Generate?top={0}&bottom={1}&quot;, data.Item1, data.Item2));
+ }
+ else // Get content from Azure CDN
+ {
+ return Redirect(string.Format(&quot;http://<mark>&lt;cdnName&gt;</mark>.vo.msecnd.net/MemeGenerator/Generate?top={0}&amp;bottom={1}&quot;, data.Item1, data.Item2));
+ }
+}
+</pre>
+
+If your local debugger is attached, then you will get the regular debug experience with a local redirect. If it's running in the cloud service, then it will redirect to:
+
+ http://<yourCDNName>.vo.msecnd.net/MemeGenerator/Generate?top=<formInput>&bottom=<formInput>
+
+Which corresponds to the following origin URL at your CDN endpoint:
+
+ http://<youCloudServiceName>.cloudapp.net/cdn/MemeGenerator/Generate?top=<formInput>&bottom=<formInput>
+
+After URL rewrite rule previously applied, the actual file that gets cached to your CDN endpoint is:
+
+ http://<youCloudServiceName>.cloudapp.net/MemeGenerator/Generate?top=<formInput>&bottom=<formInput>
+
+You can then use the `OutputCacheAttribute` attribute on the `Generate` method to specify how the action result should be cached, which Azure CDN will honor. The code below specify a cache expiration of 1 hour (3,600 seconds).
+
+ [OutputCache(VaryByParam = "*", Duration = 3600, Location = OutputCacheLocation.Downstream)]
+
+Likewise, you can serve up content from any controller action in your cloud application through your Azure CDN, with the desired caching option.
+
+In the next section, I will show you how to serve the bundled and minified scripts and CSS through Azure CDN.
+
+<a name="bundling"></a>
+## Integrate bundling and minification with Azure CDN ##
+
+Scripts and CSS stylesheets change infrequently and are prime candidates for the Azure CDN cache. Serving the entire Web role through your Azure CDN is the easiest way to integrate bundling and minification with Azure CDN. However, as you may not want to do this, I will show you how to do it while preserving the desired develper experience of ASP.NET bundling and minification, such as:
+
+- Great debug mode experience
+- Streamlined deployment
+- Immediate updates to clients for script/CSS version upgrades
+- Fallback mechanism when your CDN endpoint fails
+- Minimize code modification
+
+In the **WebRole1** project that you created in [TODO](#integrate), open *App_Start\BundleConfig.cs* and take a look at the `bundles.Add()` method calls.
+
+ public static void RegisterBundles(BundleCollection bundles)
+ {
+ bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
+ "~/Scripts/jquery-{version}.js"));
+ ...
+ }
+
+The first `bundles.Add()` statement adds a script bundle at the virtual directory `~/bundles/jquery`. Then, open *Views\Shared\_Layout.cshtml* to see how the script bundle tag is rendered. You should be able to find the following line of Razor code:
+
+ @Scripts.Render("~/bundles/jquery")
+
+When this Razor code is run in the Azure Web role, it will render a `<script>` tag for the script bundle similar to the following:
+
+ <script src="/bundles/jquery?v=FVs3ACwOLIVInrAl5sdzR2jrCDmVOWFbZMY6g6Q0ulE1"></script>
+
+However, when it is run in Visual Studio by typing `F5`, it will render each script file in the bundle individually (in the case above, only one script file is in the bundle):
+
+ <script src="/Scripts/jquery-1.10.2.js"></script>
+
+This enables you to debug the JavaScript code in your development environment while reducing concurrent client connections (bundling) and improving file download performance (minification) in production. It's a great feature to preserve with Azure CDN integration. Furthermore, since the rendered bundle already contains an automatically generated version string, you want to replicate that functionality so the whenever you update your jQuery version through NuGet, it can be updated at the client side as soon as possible.
+
+Follow the steps below to integration ASP.NET bundling and minification with your CDN endpoint.
+
+1. Back in *App_Start\BundleConfig.cs*, modify the `bundles.Add()` methods to use a different [Bundle constructor](http://msdn.microsoft.com/en-us/library/jj646464.aspx), one that specifies a CDN address. To do this, replace the `RegisterBundles` method definition with the following code:
+ <pre class="prettyprint">
+ public static void RegisterBundles(BundleCollection bundles)
+ {
+ <mark>bundles.UseCdn = true;
+ var version = System.Reflection.Assembly.GetAssembly(typeof(Controllers.HomeController))
+ .GetName().Version.ToString();
+ var cdnUrl = &quot;http://&lt;yourCDNName&gt;.vo.msecnd.net/{0}?v=&quot; + version;</mark>
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/jquery&quot;<mark>, string.Format(cdnUrl, &quot;bundles/jquery&quot;)</mark>).Include(
+ &quot;~/Scripts/jquery-{version}.js&quot;));
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/jqueryval&quot;<mark>, string.Format(cdnUrl, &quot;bundles/jqueryval&quot;)</mark>).Include(
+ &quot;~/Scripts/jquery.validate*&quot;));
+
+ // Use the development version of Modernizr to develop with and learn from. Then, when you&#39;re
+ // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
+ bundles.Add(new ScriptBundle(&quot;~/bundles/modernizr&quot;<mark>, string.Format(cdnUrl, &quot;bundles/modernizer&quot;)</mark>).Include(
+ &quot;~/Scripts/modernizr-*&quot;));
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/bootstrap&quot;<mark>, string.Format(cdnUrl, &quot;bundles/bootstrap&quot;)</mark>).Include(
+ &quot;~/Scripts/bootstrap.js&quot;,
+ &quot;~/Scripts/respond.js&quot;));
+
+ bundles.Add(new StyleBundle(&quot;~/Content/css&quot;<mark>, string.Format(cdnUrl, &quot;Content/css&quot;)</mark>).Include(
+ &quot;~/Content/bootstrap.css&quot;,
+ &quot;~/Content/site.css&quot;));
+ }
+ </pre>
+
+ Be sure to replace `<yourCDNName>` with the name of your Azure CDN.
+
+ In plain words, you are setting `bundles.UseCdn = true` and added a carefully crafted CDN URL to each bundle. For example, the first constructor in the code:
+
+ new ScriptBundle("~/bundles/jquery", string.Format(cdnUrl, "bundles/jquery"))
+
+ is the same as:
+
+ new ScriptBundle("~/bundles/jquery", string.Format(cdnUrl, "http://<yourCDNName>.vo.msecnd.net/bundles/jquery?v=<W.X.Y.Z>"))
+
+ This constructor tells ASP.NET bundling and minification to render individual script files when debugged locally, but use the specified CDN address to access the script in question. However, note two important characteristics with this carefully crafted CDN URL:
+
+ - The origin for this CDN URL is `http://<yourCloudService>.cloudapp.net/bundles/jquery?v=<W.X.Y.Z>`, which is actually the virtual directory of the script bundle in your cloud application.
+ - Since you are using CDN constructor, the CDN script tag for the bundle no longer contains the automatically generated version string in the rendered URL. You must manually generate a unique version string every time the script bundle is modified to force a cache miss at your Azure CDN. At the same time, this unique version string must remain constant through the life of the deployment to maximize cache hits at your Azure CDN after the bundle is deployed.
+ - The query string v=<W.X.Y.Z> pulls from *Properties\AssemblyInfo.cs* in your Web role project. You can have a deployment workflow that includes incrementing the assembly version every time you publish to Azure. Or, you can just modify *Properties\AssemblyInfo.cs* in your project to automatically increment the version string every time you build, using the wildcard character '*'. For example:
+
+ [assembly: AssemblyVersion("1.0.0.*")]
+
+ Any other strategy to streamline generating a unique string for the life of a deployment will work here.
+
+3. Republish the cloud application and access the home page.
+
+4. View the HTML code for the page. You should be able to see the CDN URL rendered, with a unique version string every time you republish changes to your cloud application. For example:
+ <pre class="prettyprint">
+ ...
+
+ &lt;link href=&quot;http://az632148.vo.msecnd.net/Content/css?v=1.0.0.25449&quot; rel=&quot;stylesheet&quot;/&gt;
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/modernizer?v=1.0.0.25449&quot;&gt;&lt;/script&gt;
+
+ ...
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/jquery?v=1.0.0.25449&quot;&gt;&lt;/script&gt;
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/bootstrap?v=1.0.0.25449&quot;&gt;&lt;/script&gt;
+
+ ...</pre>
+
+5. In Visual Studio, debug the cloud application in Visual Studio by typing `F5`.,
+
+6. View the HTML code for the page. You will still see each script file individually rendered so that you can have a consistent debug experience in Visual Studio.
+ <pre class="prettyprint">
+ ...
+
+ &lt;link href=&quot;/Content/bootstrap.css&quot; rel=&quot;stylesheet&quot;/&gt;
+ &lt;link href=&quot;/Content/site.css&quot; rel=&quot;stylesheet&quot;/&gt;
+
+ &lt;script src=&quot;/Scripts/modernizr-2.6.2.js&quot;&gt;&lt;/script&gt;
+
+ ...
+
+ &lt;script src=&quot;/Scripts/jquery-1.10.2.js&quot;&gt;&lt;/script&gt;
+
+ &lt;script src=&quot;/Scripts/bootstrap.js&quot;&gt;&lt;/script&gt;
+ &lt;script src=&quot;/Scripts/respond.js&quot;&gt;&lt;/script&gt;
+
+ ...
+ </pre>
+
+<a name="fallback"></a>
+## Fallback mechanism for CDN URLs ##
+
+When your Azure CDN endpoint fails for any reason, you want your Web page to be smart enough to access your origin Web server as the fallback option for loading JavaScript or Bootstrap. It's one thing to lose images on your website due to CDN unavailability, but another to lose crucial page functionality provided by your scripts and stylesheets.
+
+The [Bundle](http://msdn.microsoft.com/en-us/library/system.web.optimization.bundle.aspx) class contains a property called [CdnFallbackExpression](http://msdn.microsoft.com/en-us/library/system.web.optimization.bundle.cdnfallbackexpression.aspx) that enables you to configure the fallback mechanism for CDN failure. To use this property, follow the steps below:
+
+1. In your Web role project, open *App_Start\BundleConfig.cs*, where you added a CDN URL in each [Bundle constructor](http://msdn.microsoft.com/en-us/library/jj646464.aspx), and make the following highlighted changes to add fallback mechanism to the default bundles:
+ <pre class="prettyprint">
+ public static void RegisterBundles(BundleCollection bundles)
+ {
+ var version = System.Reflection.Assembly.GetAssembly(typeof(BundleConfig))
+ .GetName().Version.ToString();
+ var cdnUrl = &quot;http://cdnurl.vo.msecnd.net/.../{0}?&quot; + version;
+ bundles.UseCdn = true;
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/jquery&quot;, string.Format(cdnUrl, &quot;bundles/jquery&quot;))
+ <mark>{ CdnFallbackExpression = &quot;window.jquery&quot; }</mark>
+ .Include(&quot;~/Scripts/jquery-{version}.js&quot;));
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/jqueryval&quot;, string.Format(cdnUrl, &quot;bundles/jqueryval&quot;))
+ <mark>{ CdnFallbackExpression = &quot;$.validator&quot; }</mark>
+ .Include(&quot;~/Scripts/jquery.validate*&quot;));
+
+ // Use the development version of Modernizr to develop with and learn from. Then, when you&#39;re
+ // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
+ bundles.Add(new ScriptBundle(&quot;~/bundles/modernizr&quot;, string.Format(cdnUrl, &quot;bundles/modernizer&quot;))
+ <mark>{ CdnFallbackExpression = &quot;window.Modernizr&quot; }</mark>
+ .Include(&quot;~/Scripts/modernizr-*&quot;));
+
+ bundles.Add(new ScriptBundle(&quot;~/bundles/bootstrap&quot;, string.Format(cdnUrl, &quot;bundles/bootstrap&quot;))
+ <mark>{ CdnFallbackExpression = &quot;$.fn.modal&quot; }</mark>
+ .Include(
+ &quot;~/Scripts/bootstrap.js&quot;,
+ &quot;~/Scripts/respond.js&quot;));
+
+ bundles.Add(new StyleBundle(&quot;~/Content/css&quot;, string.Format(cdnUrl, &quot;Content/css&quot;)).Include(
+ &quot;~/Content/bootstrap.css&quot;,
+ &quot;~/Content/site.css&quot;));
+ }</pre>
+
+ When `CdnFallbackExpression` is not null, script is injected into the HTML to test whether the bundle is loaded successfully and, if not, access the bundle directly from the origin Web server. This property needs to be set to a JavaScript expression that tests whether the respective CDN bundle is loaded properly. The expression needed to test each bundle differs according to the content. For the default bundles above:
+
+ - `window.jquery` is defined in jquery-{version}.js
+ - `$.validator` is defined in jquery.validate.js
+ - `window.Modernizr` is defined in modernizer-{version}.js
+ - `$.fn.modal` is defined in bootstrap.js
+
+ You might have noticed that I did not set CdnFallbackExpression for the `~/Cointent/css` bundle. This is because currently there is a [bug in System.Web.Optimization](https://aspnetoptimization.codeplex.com/workitem/104) that injects a `<script>` tag for the fallback CSS instead of the expected `<link>` tag.
+
+ There is, however, a good [Style Bundle Fallback](https://github.com/EmberConsultingGroup/StyleBundleFallback) offered by [Ember Consulting Group](https://github.com/EmberConsultingGroup).
+
+2. To use the workaround, create a new .cs file in your Web role project's *App_Start* folder called *StyleBundleExtensions.cs*, and replace its content with the [code from GitHub](https://github.com/EmberConsultingGroup/StyleBundleFallback/blob/master/Website/App_Start/StyleBundleExtensions.cs).
+
+4. In *App_Start\StyleFundleExtensions.cs*, rename the namespace to your Web role's name (e.g. **WebRole1**).
+
+3. Go back to `App_Start\BundleConfig.cs` and modify the last `bundles.Add` statement with the following highlighted code:
+ <pre class="prettyprint">
+ bundles.Add(new StyleBundle("~/Content/css", string.Format(cdnUrl, "Content/css"))
+ <mark>.IncludeFallback("~/Content/css", "sr-only", "width", "1px")</mark>
+ .Include(
+ "~/Content/bootstrap.css",
+ "~/Content/site.css"));
+ </pre>
+
+ This new extension method uses the same idea to inject script in the HTML to check the DOM for the a matching class name, rule name, and rule value defined in the CSS bundle, and falls back to the origin Web server if it fails to find the match.
+
+4. Publish the cloud application again and access the home page.
+5. View the HTML code for the page. You should find injected scripts similar to the following:
+ <pre class="prettyprint">...
+
+ &lt;link href=&quot;http://az632148.vo.msecnd.net/Content/css?v=1.0.0.25474&quot; rel=&quot;stylesheet&quot;/&gt;
+ <mark>&lt;script&gt;(function() {
+ var loadFallback,
+ len = document.styleSheets.length;
+ for (var i = 0; i &lt; len; i++) {
+ var sheet = document.styleSheets[i];
+ if (sheet.href.indexOf(&#39;http://az632148.vo.msecnd.net/Content/css?v=1.0.0.25474&#39;) !== -1) {
+ var meta = document.createElement(&#39;meta&#39;);
+ meta.className = &#39;sr-only&#39;;
+ document.head.appendChild(meta);
+ var value = window.getComputedStyle(meta).getPropertyValue(&#39;width&#39;);
+ document.head.removeChild(meta);
+ if (value !== &#39;1px&#39;) {
+ document.write(&#39;&lt;link href=&quot;/Content/css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;&#39;);
+ }
+ }
+ }
+ return true;
+ }())||document.write(&#39;&lt;script src=&quot;/Content/css&quot;&gt;&lt;\/script&gt;&#39;);&lt;/script&gt;</mark>
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/modernizer?v=1.0.0.25474&quot;&gt;&lt;/script&gt;
+ <mark>&lt;script&gt;(window.Modernizr)||document.write(&#39;&lt;script src=&quot;/bundles/modernizr&quot;&gt;&lt;\/script&gt;&#39;);&lt;/script&gt;</mark>
+
+ ...
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/jquery?v=1.0.0.25474&quot;&gt;&lt;/script&gt;
+ <mark>&lt;script&gt;(window.jquery)||document.write(&#39;&lt;script src=&quot;/bundles/jquery&quot;&gt;&lt;\/script&gt;&#39;);&lt;/script&gt;</mark>
+
+ &lt;script src=&quot;http://az632148.vo.msecnd.net/bundles/bootstrap?v=1.0.0.25474&quot;&gt;&lt;/script&gt;
+ <mark>&lt;script&gt;($.fn.modal)||document.write(&#39;&lt;script src=&quot;/bundles/bootstrap&quot;&gt;&lt;\/script&gt;&#39;);&lt;/script&gt;</mark>
+
+ ...
+ </pre>
+
+ Note that injected script for the CSS bundle still contains the errant remnant from the `CdnFallbackExpression` property in the line:
+
+ }())||document.write('<script src="/Content/css"><\/script>');</script>
+
+ But since the first part of the || expression will always return true (in the line directly above that), the document.write() function will never run.
+
+# More Information #
+[Overview of the Azure Content Delivery Network (CDN)](http://msdn.microsoft.com/library/azure/ff919703.aspx)
+[Serve Content from Azure CDN in Your Web Application](http://azure.microsoft.com/en-us/Documentation/Articles/cdn-serve-content-from-cdn-in-your-web-application/)
+[ASP.NET Bundling and Minification](http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification)
+[Using CDN for Azure](http://azure.microsoft.com/en-us/documentation/articles/cdn-how-to-use/)
256 articles/cdn-serve-content-from-cdn-in-your-web-application.md
View
@@ -0,0 +1,256 @@
+<properties linkid="cdn-serve-content-from-cdn-in-your-web-application" urlDisplayName="Use Content from a CDN in Your Web Application" pageTitle="Use Content from a CDN in Your Web Application" metaKeywords="Azure tutorial, Azure web app tutorial, ASP.NET, CDN" description="A tutorial that teaches you how to use content from a CDN to improve the performance of your Web application." metaCanonical="" services="cdn" documentationCenter=".NET" title="Use Content from a CDN in Your Web Application" authors="cephalin" solutions="" manager="wpickett" editor="tysonn" />
+
+# Serve Content from Azure CDN in Your Web Application #
+***By [Cephas Lin](https://twitter.com/Cephas_MSFT) Updated 18 July 2014.***
+
+This tutorial shows you how to take advantage of Azure CDN to improve the reach and performance of your Web application. Azure CDN can help improve the performance of your Web application when:
+
+- You have many links to static or semi-static content on your pages
+- Your application is accessed by clients globally
+- You want to offload traffic from your Web server
+- You want to increase the perceived load/refresh time of your pages
+
+## What you will learn ##
+
+In this tutorial, you will learn how to do the following:
+
+- [Serve static content from an Azure CDN endpoint](#deploy)
+- [Automate content upload from your ASP.NET application to your CDN endpoint](#upload)
+- [Configure the CDN cache to reflect the desired content update](#update)
+- [Serve fresh content immediately using query strings](#query)
+
+## What you will need ##
+
+This tutorial has the following prerequisites:
+
+- An active [Microsoft Azure account](http://azure.microsoft.com/en-us/account/). You can sign up for a trial account
+- Visual Studio 2013 with [Azure SDK](http://go.microsoft.com/fwlink/p/?linkid=323510&clcid=0x409)
+- A simple ASP.NET MVC application to test CDN URLs. [Automate content upload from your ASP.NET application to your CDN endpoint](#upload) uses an ASP.NET MVC application as an example.
+- [Azure PowerShell](http://go.microsoft.com/?linkid=9811175&clcid=0x409) (used by [Automate content upload from your ASP.NET application to your CDN endpoint](#upload))
+
+<div class="wa-note">
+ <span class="wa-icon-bulb"></span>
+ <h5><a name="note"></a>You need an Azure account to complete this tutorial:</h5>
+ <ul>
+ <li>You can <a href="http://azure.microsoft.com/en-us/pricing/free-trial/?WT.mc_id=A261C142F">open an Azure account for free</a> - You get credits you can use to try out paid Azure services, and even after they're used up you can keep the account and use free Azure services, such as Web Sites.</li>
+ <li>You can <a href="http://azure.microsoft.com/en-us/pricing/member-offers/msdn-benefits-details/?WT.mc_id=A261C142F">activate MSDN subscriber benefits</a> - Your MSDN subscription gives you credits every month that you can use for paid Azure services.</li>
+ <ul>
+</div>
+
+<a name="static"></a>
+## Serve static content from an Azure CDN endpoint ##
+
+In this tutorial section, you will learn how to create a CDN and use it to serve your static content. The major steps involved are:
+
+1. Create a storage account
+2. Create a CDN linked to the storage account
+3. Create a blob container in your storage account
+4. Upload content to your blob container
+5. Link to the the content you uploaded using its CDN URL
+
+Let's get to it. Follow the steps below to start using the Azure CDN:
+
+1. To create a CDN endpoint, log into your [Azure management portal](http://manage.windowsazure.com/).
+1. Create a storage account by clicking **New > Data Services > Storage > Quick Create**. Specify a URL, a location, and click **Create Storage Account**.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-1.PNG)
+
+ >[WACOM.NOTE] Note that I'm using East Asia as the region as it is far enough away for me to test my CDN from North America later.
+
+2. Once the new storage account's status is **Online**, create a new CDN endpoint that's tied to the storage account you created. Click **New > App Services > CDN > Quick Create**. Select the storage account you created and click **Create**.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2.PNG)
+
+ >[WACOM.NOTE] Once your CDN is created, the Azure portal will show you its URL and the origin domain that it's tied to. However, it can take awhile for the CDN endpoint's configuration to be fully propagated to all the node locations.
+
+3. Test your CDN endpoint to make sure that it's online by pinging it. If your CDN endpoint has not propagated to all the nodes, you will see a message similar to the one below.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-fail.PNG)
+
+ Wait another hour and test again. Once your CDN endpoint has finished propagating to the nodes, it should respond to your pings.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-succeed.PNG)
+
+4. At this point, you can already see where the CDN endpoint determines to be the closest CDN node to you. From my desktop computer, the responding IP address is **93.184.215.201**. Plug it into a site like [www.ip-address.org](http://www.ip-address.org) and see that the server is located in Washington D.C.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-4.PNG)
+
+ For a list of all CDN node locations, see [Azure Content Delivery Network (CDN) Node Locations](http://msdn.microsoft.com/en-us/library/azure/gg680302.aspx).
+
+3. Back in the Azure portal, in the **CDN** tab, click the name of the CDN endpoint you just created.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequerya.PNG)
+
+3. Click **Enable Query String** to enable query strings in the Azure CDN cache. Once you enable this, the same link accessed with different query strings will be cached as separate entries.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequeryb.PNG)
+
+ >[WACOM.NOTE] While enabling the query string is not necessary for this part of the tutorial, you want to do this as early as possible for convenience sake since any change here is going to take time to propagate to the rest of the nodes, and you don't want any non-query-string-enabled content to clog up the CDN cache (updating CDN content will be discussed later). You will find out how to take advantage of this in [Serve fresh content immediately through query strings](#query).
+
+6. In Visual Studio 2013, in Server Explorer, click the **Connect to Windows Azure** button.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-5.PNG)
+
+7. Follow the prompt to sign into your Azure account.
+8. Once you sign in, expand the **Windows Azure > Storage > your storage account**. Right-click **Blob** and select **Create Blob Container**.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-6.PNG)
+
+8. Specify a blob container name and click **OK**.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-7.PNG)
+
+9. In Server Explorer, double-click the blob container you created to manage it. You should see the management interface in the center pane.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-8.PNG)
+
+10. Click the **Upload Blob** button to upload images, scripts, or stylesheets that are used by your Web pages into the blob container. The upload progress will be shown in the **Windows Azure Activity Log**, and the blobs will appear in the container view when they are uploaded.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-9.PNG)
+
+11. Now that you have uploaded the blobs, you must make them public for you to access them. In Server Explorer, right-click the container and select **Properties**. Set the **Public Read Access** property to **Blob**.
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-10.PNG)
+
+12. Test the public access of your blobs by navigating to the URL for one of the blobs in a browser. For example, I can test the first image in my uploaded list with `http://cephalinstorage.blob.core.windows.net/cdn/cephas_lin.png`.
+
+ Note that I'm not using the HTTPS address given in the blob management interface in Visual Studio. By using HTTP, you test whether the content is publicly accessible, which is a requirement for Azure CDN.
+
+13. If you can see the blob rendered properly in your browser, change the URL from `http://<yourStorageAccountName>.blob.core.windows.net` to the URL of your Azure CDN. In my case, to test the first image at my CDN endpoint, I would use `http://az623979.vo.msecnd.net/cdn/cephas_lin.png`.
+
+ >[WACOM.NOTE] You can find the CDN endpoint's URL in the Azure management portal, in the CDN tab.
+
+ If you compare the performance of direct blob access and CDN access, you can see the performance gain from using Azure CDN. Below is the Internet Explorer 11 F12 developer tools screenshot for blob URL access of my image:
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-blob.PNG)
+
+ And for CDN URL access of the same image
+
+ ![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-cdn.PNG)
+
+ Pay attention to the numbers for the **Request** timing, which is the time to first byte, or the time taken to send the request and receive the first response from the server. When I access the blob, which is hosted in the East Asia region, it takes 266 ms for me - since the request must traverse the entire Pacific Ocean just to get to the server. However, when I access the Azure CDN, it takes only 16 ms, which is nearly a **20-fold gain in performance**!
+
+15. Now, it's just a matter of using the new link in your Web page. For example, I can add the following image tag:
+
+ <img alt="Mugshot" src="http://az623979.vo.msecnd.net/cdn/cephas_lin.png" />
+
+In this section, you have learned how to create a CDN endpoint, upload content to it, and link to CDN contentfrom any Web page.
+
+<a name="upload"></a>
+## Automate content upload from your ASP.NET application to your CDN endpoint ##
+
+If you want to easily upload all of the static content in your ASP.NET Web application to your CDN endpoint, or if your deploy your Web application using continuous delivery (for an example, see [Continuous Delivery for Cloud Services in Azure](http://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-continuous-delivery/)), you can use Azure PowerShell to automate the synchronization of the latest content files to Azure blobs every time you deploy your Web application. For example, you can run the script at [Upload Content Files from ASP.NET Application to Azure Blobs](http://gallery.technet.microsoft.com/scriptcenter/Upload-Content-Files-from-41c2142a) upload all the content files in an ASP.NET application. To use this script:
+
+4. From the **Start** menu, run **Windows Azure PowerShell**.
+5. In the Azure PowerShell window, run `Get-AzurePublishSettingsFile` to download a publish settings file for your Azure account.
+6. Once you have downloaded your publish settings file, run the following:
+
+ Import-AzurePublishSettingsFile "<yourDownloadedFilePath>"
+
+ >[WACOM.NOTE] Once you import your publish settings file, it will be the default Azure account used for all Azure PowerShell sessions. This means that the above steps only need to be done once.
+
+1. Download the script from the [download page]((http://gallery.technet.microsoft.com/scriptcenter/Upload-Content-Files-from-41c2142a)). Save it into your ASP.NET application's project folder.
+2. Right-click the downloaded script and click **Properties**.
+3. Click **Unblock**.
+4. Open a PowerShell window and run the following:
+
+ cd <ProjectFolder>
+ .\UploadContentToAzureBlobs.ps1 -StorageAccount "<yourStorageAccountName>" -StorageContainer "<yourContainerName>"
+
+This script uploads all files from your *\Content* and *\Scripts* folders to the specified storage account and container. It has the following advantages:
+
+- Automatically replicate the file structure of your Visual Studio project
+- Automatically create blob containers as needed
+- Reuse the same Azure storage account and CDN endpoint for multiple Web applications, each in a separate blob container
+- Easily update the Azure CDN with new content. For more information on updating content, see [Configure the CDN cache to reflect the desired content update](#update).
+
+For the `-StorageContainer` parameter, it makes sense to use the name of your Web application, or the Visual Studio project name. Whereas I used the generic "cdn" as the container name previously, using the name of your Web application allows related content to be organized into the same easily identifiable container.
+
+Once the content has finished uploading, you can link to anything in your *\Content* and *\Scripts* folder in your HTML code, such as in your .cshtml files, using `http://<yourCDNName>.vo.msecnd.net/<containerName>`. Here is an example of something I can use in a Razor view:
+
+ <img alt="Mugshot" src="http://az623979.vo.msecnd.net/MyMvcApp/Content/cephas_lin.png" />
+
+For an example of integrating PowerShell scripts into your continuous delivery configuration, see [Continuous Delivery for Cloud Services in Azure](http://azure.microsoft.com/en-us/documentation/articles/cloud-services-dotnet-continuous-delivery/).
+
+<a name="update"></a>
+## Configure the CDN cache to reflect the desired content update ##
+
+Now, suppose after you have uploaded the static files from your Web app in a blob container, you make a change to one of the files in your project and upload it to the blob container again. You may think that it's automatically updated to your CDN endpoint, but are actually puzzled why you don't see the update reflected when you access the content's CDN URL.
+
+The truth is that the CDN does indeed automatically update from your blob storage, but it does so by applying a default 7-day caching rule to the content. This means that once a CDN node pulls your content from blob storage, the same content is not refreshed until it expires in the cache.
+
+The good news is that you can customize cache expiration. Similar to most browsers, Azure CDN respects the expiration time specified in the content's Cache-Control header. You can specify a custom Cache-Control header value by navigating to the blob container in the Azure portal and editing the blob properties. The screenshot below shows cache expiration set to 1 hour (3600 seconds).
+
+![](media/cdn-serve-content-from-cdn-in-your-web-application/cdn-updates-1.PNG)
+
+You can also do this in your PowerShell script to set all blobs' Cache-Control headers. For the script in [Automate content upload from your ASP.NET application to your CDN endpoint](#upload), find the following code snippet:
+
+ Set-AzureStorageBlobContent `
+ -Container $StorageContainer `
+ -Context $context `
+ -File $file.FullName `
+ -Blob $blobFileName `
+ -Properties @{ContentType=$contentType} `
+ -Force
+
+and modify it as follows:
+
+ Set-AzureStorageBlobContent `
+ -Container $StorageContainer `
+ -Context $context `
+ -File $file.FullName `
+ -Blob $blobFileName `
+ -Properties @{ContentType=$contentType, CacheControl="public, max-age=3600"} `
+ -Force
+
+You may still need to wait for the full 7-day cached content on your Azure CDN to expire before it pulls the new content, with the new Cache-Control header. This illustrates the fact that custom caching values do not help if you want your content update to go live immediately, such as JavaScript or CSS updates. However, you can work around this issue by versioning your content through query strings. For more information, see [Serve fresh content immediately using query strings](#query).
+
+There is, of course, a time and place for caching. For example, you may have content that does not require the frequent update, such as the upcoming World Cup games that can be refreshed every 3 hours, but gets enough global traffic that you want to offload it from your own Web server. That can be a good candidate to use the Azure CDN caching.
+
+<a name="query"></a>
+## Serve fresh content immediately using query strings ##
+
+In Azure CDN, you can enable query strings so that content from URLs with specific query strings are cached separately. This is a great feature to use if you want to push certain content updates to the client browsers immediately instead of waiting for the cached CDN content to expire. Suppose I publish my Web page with a version number in the URL.
+<pre class="prettyprint">
+&lt;link href=&quot;http://az623979.vo.msecnd.net/MyMvcApp/Content/bootstrap.css<mark>?v=3.0.0</mark>&quot; rel=&quot;stylesheet&quot;/&gt;
+</pre>
+
+When I publish a CSS update and use a different version number in my CSS URL:
+<pre class="prettyprint">
+&lt;link href=&quot;http://az623979.vo.msecnd.net/MyMvcApp/Content/bootstrap.css<mark>?v=3.1.1</mark>&quot; rel=&quot;stylesheet&quot;/&gt;
+</pre>
+
+To a CDN endpoint that has query strings enabled, the two URLs are unique to each other, and it will make a new request to my Web server to retrieve the new *bootstrap.css*. To a CDN endpoint that doesn't have query strings enabled, however, these are the same URL, and it will simply serve the cached *bootstrap.css*.
+
+The trick then is to update the version number automatically. In Visual Studio, this is easy to do. In a .cshtml file where I would use the link above, I can specify a version number based on the assembly number.
+<pre class="prettyprint">
+@{
+ <mark>var cdnVersion = System.Reflection.Assembly.GetAssembly(
+ typeof(MyMvcApp.Controllers.HomeController))
+ .GetName().Version.ToString();</mark>
+}
+
+...
+
+&lt;link href=&quot;http://az623979.vo.msecnd.net/MyMvcApp/Content/bootstrap.css<mark>?v=@cdnVersion</mark>&quot; rel=&quot;stylesheet&quot;/&gt;
+</pre>
+
+If you change the assembly number as part of every publish cycle, then you can likewise be sure to get a unique version number every time you publish your Web app, which will remain the same until the next publish cycle. Or, you can make Visual Studio automatically increment the assembly version number every time the Web app builds by opening *Properties\AssemblyInfo.cs* in your Visual Studio project and use `*` in `AssemblyVersion`. For example:
+
+ [assembly: AssemblyVersion("1.0.0.*")]
+
+## What about bundled scripts and CSS? ##
+
+Currently, the only place you find adequate integration between ASP.NET bundling and Azure CDN is in [Azure Cloud Services](http://azure.microsoft.com/en-us/services/cloud-services/). Without Azure Cloud Services, it is possible to use Azure CDN for your script bundles, with the following caveats:
+
+- You must manually upload the bundled scripts to blob storage. A programmatic solution is proposed at [stackoverflow](http://stackoverflow.com/a/13736433).
+- In your .cshtml files, transform the rendered script/CSS tags to use the Azure CDN. For example:
+
+ @Html.Raw(Styles.Render("~/Content/css").ToString().Insert(0, "http://<yourCDNName>.vo.msecnd.net"))
+
+For more information on integrating Azure CDN with Azure Cloud Services, see [Integrate a cloud application with Azure CDN](http://azure.microsoft.com/en-us/documentation/articles/cloud-services-how-to-create-deploy/).
+
+# More Information #
+[Overview of the Azure Content Delivery Network (CDN)](http://msdn.microsoft.com/library/azure/ff919703.aspx)
+[Integrate a cloud application with Azure CDN](http://azure.microsoft.com/en-us/Documentation/Articles/cdn-cloud-service-with-cdn/)
+[Using CDN for Azure](http://azure.microsoft.com/en-us/documentation/articles/cdn-how-to-use/)
411 articles/hdinsight-mahout.md
View
@@ -0,0 +1,411 @@
+<properties title="How to use Mahout with HDNishgt" pageTitle="How to use Mahout with Microsoft Azure HDInsight" description="Learn how to use Mahout to run jobs with HDInsight" metaKeywords="Azure hdinsight mahout, Azure hdinsight machine learning" services="hdinsight" solutions="" documentationCenter="big-data" authors="larryfr" videoId="" scriptId="" />
+
+#How to use Apache Mahout with HDInsight
+
+Learn how to use [Apache Mahout](http://mahout.apache.org) with Microsoft Azure HDInsight (Hadoop).
+
+> [WACOM.NOTE] You must have an HDInsight cluster to use the information in this article. For information on creating one, see [Get started using Hadoop in HDInsight][getstarted].
+
+> [WACOM.NOTE] Mahout is provided with HDInsight 3.1 clusters. If you are using an earlier version of HDInsight, see [Install Mahout](#install) before continuing.
+
+##<a name="learn"></a>What you will learn
+
+Mahout is a [machine learning][ml] library for Apache Hadoop. Mahout contains algorithms for processing data, such as filtering, classification, and clustering. In this article you will generate recommendations using a recommendation engine, as well as performing classifications with a decision forest. This will teach you the following.
+
+* How to run Mahout jobs from PowerShell
+
+* How to run Mahout jobs from the Hadoop command line
+
+* How to install Mahout on HDInsight 2.0 and 3.0 clusters
+
+##In this article
+
+* [Generate recommendations using PowerShell](#recommendations)
+* [Classify data using the Hadoop command line](#classify)
+* [Troubleshooting](#troubleshooting)
+
+
+##<a name="recommendations"></a>Generate recommendations using PowerShell
+
+> [WACOM.NOTE] While the job used in this section works with PowerShell, many of the classes provided with Mahout do not currently work with PowerShell and must be run using the Hadoop command line. For an listing of classes that do not work with PowerShell, see the [Troubleshooting](#troubleshooting) section.
+>
+> For an example of using the Hadoop command line to run Mahout jobs, see [Classify data using the Hadoop command line](#classify).
+
+One of the functions provided by Mahout is a recommendation engine. This accepts data in the format of `userID`, `itemId`, `prefValue` (the users preference for the item). Mahout can then perform co-occurance analysis to determine that _users that have a preference for an item also have a preference for these other items_. Mahout will then determine users with like item preferences, which can then be used to make recommendations.
+
+The following is an extremely simple example using movies:
+
+* __Co-occurance__ - Joe, Alice, and Bob all liked _Star Wars_, _The Empire Strikes Back_, and _Return of the Jedi_. Mahout would determine that users who like any one of these movies also like the other two.
+
+* __Co-occurance__ - Bob and Alice also liked _The Phantom Menace_, _Attack of the Clones_, and _Revenge of the Sith_. Mahout would determine that users who liked the previous three movies also like these three
+
+* __Similarity recommendation__ - Since Joe liked the first three, Mahout will look at movies that others with similar preferences have liked, but that Joe has not watched (liked/rated.) In this case, Mahout would recommend _The Phantom Menace_, _Attack of the Clones_, and _Revenge of the Sith_.
+
+###Load the data
+
+Conveniently, GroupLens Research provides [rating data for movies][movielens] in a Mahout compatible format.
+
+1. Download the [MovieLens 100k][100k] archive, which contains 100,000 ratings from 1000 users on 1700 movies.
+
+2. Extract the archive. It should contain an __ml-100k__ directory, which contains many data files prefixed with __u.__. The file that will be analyzed by Mahout is __u.data__. The data structure of this file is `userID`, `movieID`, `userRating`, and `timestamp`. Here is an example of the data.
+
+
+ 196 242 3 881250949
+ 186 302 3 891717742
+ 22 377 1 878887116
+ 244 51 2 880606923
+ 166 346 1 886397596
+
+
+3. Upload the __u.data__ file to __example/data/u.data__ on your HDInsight cluster. If you have [Azure PowerShell][aps], you can use the [HDInsight-Tools][tools] PowerShell module to upload the file. For other ways to upload files, see [Upload data for Hadoop Jobs in HDInsight][upload]. The following demonstrates using `Add-HDInsightFile` to upload the file
+
+ PS C:\> Add-HDInsightFile -LocalPath "path\to\u.data" -DestinationPath "example/data/u.data" -ClusterName "your cluster name"
+
+ This will upload the __u.data__ file to __example/data/u.data__ in the default storage your cluster. We can then access this data using the __wasb:///example/data/u.data__ URI from HDInsight jobs.
+
+###Run the job
+
+Use the following PowerShell script to run a job using the Mahout recommendation engine with the __u.data__ file uploaded previously.
+
+ # The HDInsight cluster name.
+ $clusterName = "the cluster name"
+
+ # The location of the Mahout jar file.
+ $jarFile = "C:\apps\dist\mahout-0.9.0.2.1.3.0-1887\examples\target\mahout-examples-0.9.0.2.1.3.0-1887-job.jar"
+ # NOTE: The version number portion of the file path
+ # may change in future versions of HDInsight.
+ # Use the following to find the location and name
+ # of the Mahout jar on HDInsight 3.1, and modify
+ # the $jarFile= line to point to it.
+ #
+ # Use-AzureHDInsightCluster -Name $clusterName
+ # $jarFile = Invoke-Hive -Query '!${env:COMSPEC} /c dir /b /s ${env:MAHOUT_HOME}\examples\target\*-job.jar'
+ #
+ # If you are using an earlier version of HDInsight,
+ # set $jarFile to the jar file you
+ # uploaded.
+ # For example,
+ # $jarFile = "wasb:///example/jars/mahout-core-0.9-job.jar"
+
+ # The arguments for this job
+ # * input - the path to the data uploaded to HDInsight
+ # * output - the path to store output data
+ # * tempDir - the directory for temp files
+ $jobArguments = "-s", "SIMILARITY_COOCCURRENCE",
+ "--input", "wasb:///example/data/u.data",
+ "--output", "wasb:///example/out",
+ "--tempDir", "wasb:///temp/mahout"
+
+ # Create the job definition
+ $jobDefinition = New-AzureHDInsightMapReduceJobDefinition `
+ -JarFile $jarFile `
+ -ClassName "org.apache.mahout.cf.taste.hadoop.item.RecommenderJob" `
+ -Arguments $jobArguments
+
+ # Start the job
+ $job = Start-AzureHDInsightJob -Cluster $clusterName -JobDefinition $jobDefinition
+
+ # Wait on the job to complete
+ Write-Host "Wait for the job to complete ..." -ForegroundColor Green
+ Wait-AzureHDInsightJob -Job $job
+
+ # Write out any error information
+ Write-Host "STDERR"
+ Get-AzureHDInsightJobOutput -Cluster $clusterName -JobId $job.JobId -StandardError
+
+> [WACOM.NOTE] Mahout jobs do not remove temporary data created while processing the job. This is why the `--tempDir` parameter is specified in the example job - to isolate the temp files into a specific path for easy deletion.
+>
+> To remove these files, you can use one of the utilities mentioned in the [Upload data for Hadoop jobs in HDInsight][upload]. Or use the `Remove-HDInsightFile` function in the [HDInsight-Tools][tools] PowerShell script.
+>
+> If you do not remove the temp files, or the output file, you will receive an error if you run the job again.
+
+The Mahout job does not return the output to STDOUT, but instead stores it in the specified output directory as __part-r-00000__. To download and view the file, use the `Get-HDInsightFile` function in the [HDInsight-Tools][tools] PowerShell module.
+
+The following is an example of the contents of the file:
+
+ 1 [234:5.0,347:5.0,237:5.0,47:5.0,282:5.0,275:5.0,88:5.0,515:5.0,514:5.0,121:5.0]
+ 2 [282:5.0,210:5.0,237:5.0,234:5.0,347:5.0,121:5.0,258:5.0,515:5.0,462:5.0,79:5.0]
+ 3 [284:5.0,285:4.828125,508:4.7543354,845:4.75,319:4.705128,124:4.7045455,150:4.6938777,311:4.6769233,248:4.65625,272:4.649266]
+ 4 [690:5.0,12:5.0,234:5.0,275:5.0,121:5.0,255:5.0,237:5.0,895:5.0,282:5.0,117:5.0]
+
+The first column is the `userID`. The values contained in '[' and ']' are the `movieId`:`recommendationScore`.
+
+###View the output
+
+While the generated output might be OK for use in an application, it's not very human readable. Some of the other files extracted to the __ml-100k__ folder earlier can be used to resolve the `movieId` to a movie name. While there is a Python script that will do this included in the __ml-100k__ folder (__show\_recommendations.py__,) you can also use the following PowerShell script.
+
+ <#
+ .SYNOPSIS
+ Displays recommendations for movies.
+ .DESCRIPTION
+ Displays recommendations generated by Mahout
+ with HDInsight example in a human readable format.
+ .EXAMPLE
+ .\Show-Recommendation -userId 4
+ -userDataFile "u.data"
+ -movieFile "u.item"
+ -recommendationFile "output.txt"
+ #>
+
+ [CmdletBinding(SupportsShouldProcess = $true)]
+ param(
+ #The user ID
+ [Parameter(Mandatory = $true)]
+ [String]$userId,
+
+ [Parameter(Mandatory = $true)]
+ [String]$userDataFile,
+
+ [Parameter(Mandatory = $true)]
+ [String]$movieFile,
+
+ [Parameter(Mandatory = $true)]
+ [String]$recommendationFile
+ )
+ # Read movie ID & description into hash table
+ Write-Host "Reading movies descriptions" -ForegroundColor Green
+ $movieById = @{}
+ foreach($line in Get-Content $movieFile)
+ {
+ $tokens = $line.Split("|")
+ $movieById[$tokens[0]] = $tokens[1]
+ }
+ # Load movies user has already seen (rated)
+ # into a hash table
+ Write-Host "Reading rated movies" -ForegroundColor Green
+ $ratedMovieIds = @{}
+ foreach($line in Get-Content $userDataFile)
+ {
+ $tokens = $line.Split("`t")
+ if($tokens[0] -eq $userId)
+ {
+ # Resolve the ID to the movie name
+ $ratedMovieIds[$movieById[$tokens[1]]] = $tokens[2]
+ }
+ }
+ # Read recommendations generated by Mahout
+ Write-Host "Reading recommendations" -ForegroundColor Green
+ $recommendations = @{}
+ foreach($line in get-content $recommendationFile)
+ {
+ $tokens = $line.Split("`t")
+ if($tokens[0] -eq $userId)
+ {
+ #Trim leading/treailing [] and split at ,
+ $movieIdAndScores = $tokens[1].TrimStart("[").TrimEnd("]").Split(",")
+ foreach($movieIdAndScore in $movieIdAndScores)
+ {
+ #Split at : and store title and score in a hash table
+ $idAndScore = $movieIdAndScore.Split(":")
+ $recommendations[$movieById[$idAndScore[0]]] = $idAndScore[1]
+ }
+ break
+ }
+ }
+
+ Write-Host "Rated movies" -ForegroundColor Green
+ Write-Host "---------------------------" -ForegroundColor Green
+ $ratedFormat = @{Expression={$_.Name};Label="Movie";Width=40}, `
+ @{Expression={$_.Value};Label="Rating"}
+ $ratedMovieIds | format-table $ratedFormat
+ Write-Host "---------------------------" -ForegroundColor Green
+
+ write-host "Recommended movies" -ForegroundColor Green
+ Write-Host "---------------------------" -ForegroundColor Green
+ $recommendationFormat = @{Expression={$_.Name};Label="Movie";Width=40}, `
+ @{Expression={$_.Value};Label="Score"}
+ $recommendations | format-table $recommendationFormat
+
+To use this script, you must have the __ml-100k__ folder extracted previously, as well as a local copy of the __part-r-00000__ output file generated by the Mahout job. The following is an example of running the script.
+
+ PS C:\> show-recommendation.ps1 -userId 4 -userDataFile .\ml-100k\u.data -movieFile .\ml-100k\u.item -recommendationFile .\output.txt
+
+
+> [WACOM.NOTE] The example Python script, __show\_recommendations.py__, takes the same parameters.
+
+The output should appear similar to the following.
+
+ Reading movies descriptions
+ Reading rated movies
+ Reading recommendations
+ Rated movies
+ ---------------------------
+ Movie Rating
+ ----- ------
+ Devil's Own, The (1997) 1
+ Alien: Resurrection (1997) 3
+ 187 (1997) 2
+ (lines ommitted)
+
+ ---------------------------
+ Recommended movies
+ ---------------------------
+
+ Movie Score
+ ----- -----
+ Good Will Hunting (1997) 4.6504064
+ Swingers (1996) 4.6862745
+ Wings of the Dove, The (1997) 4.6666665
+ People vs. Larry Flynt, The (1996) 4.834559
+ Everyone Says I Love You (1996) 4.707071
+ Secrets & Lies (1996) 4.818182
+ That Thing You Do! (1996) 4.75
+ Grosse Pointe Blank (1997) 4.8235292
+ Donnie Brasco (1997) 4.6792455
+ Lone Star (1996) 4.7099237
+
+##<a name="classify"></a>Classify data using the Hadoop command line
+
+One of the classification methods available with Mahout is to build a [random forest][forest]. This is a multi-step process that involves using training data to generate a decision trees, which are then be used to classify data. This uses the __org.apache.mahout.classifier.df.tools.Describe__ class provided by Mahout, and currently must be ran using the Hadoop command line.
+
+###Load the data
+
+The current Mahout implementation is compatible with the University of California, Irvine (UCI) repository format [why does this matter, what is this format]
+
+1. Download the following files from [http://nsl.cs.unb.ca/NSL-KDD/](http://nsl.cs.unb.ca/NSL-KDD/).
+
+ * [KDDTrain+.ARFF](http://nsl.cs.unb.ca/NSL-KDD/KDDTrain+.arff) - the training file
+
+ * [KDDTest+.ARFF](http://nsl.cs.unb.ca/NSL-KDD/KDDTest+.arff) - the test data
+
+2. Open each file and remove the lines at the top that begin with '@', and then save the files. If these are not removed, you will receive errors when using this data with Mahout.
+
+2. Upload the to __example/data__. You can do this using the `Add-HDInsightFile` function in the [HDInsight-Tools][tools] PowerShell module.
+
+###Run the job
+
+1. Since this job requires the Hadoop command line, you must first enable remote desktop through the [Azure Management Portal][management]. In the portal, select your HDInsight cluster, and then select __Enable Remote__ at the bottom of the __Configuration__ page.
+
+ ![enable remote][enableremote]
+
+ When prompted, enter a user name and password to use for remote sessions.
+
+2. Once remote access is enabled, select __Connect__ to begin the connection. This will download an __.rdp__ file, which can be used to start a Remote Desktop session.
+
+ ![connect][connect]
+
+3. After connecting, use the __Hadoop Command Line__ icon to open the Hadoop Command Line.
+
+ ![hadoop cli][hadoopcli]
+
+3. Use the following command to generate the file descriptor (__KDDTrain+.info__,) using Mahout.
+
+ hadoop jar "c:/apps/dist/mahout-0.9.0.2.1.3.0-1887/examples/target/mahout-examples-0.9.0.2.1.3.0-1887-job.jar" org.apache.mahout.classifier.df.tools.Describe -p "wasb:///example/data/KDDTrain+.arff" -f "wasb:///example/data/KDDTrain+.info" -d N 3 C 2 N C 4 N C 8 N 2 C 19 N L
+
+ The `N 3 C 2 N C 4 N C 8 N 2 C 19 N L` describes the attributes of the data in the file. One numerical attribute, 2 categorical, etc. L indicates a label.
+
+4. Build a forest of decision trees using the following command.
+
+ hadoop jar c:/apps/dist/mahout-0.9.0.2.1.3.0-1887/examples/target/mahout-examples-0.9.0.2.1.3.0-1887-job.jar org.apache.mahout.classifier.df.mapreduce.BuildForest -Dmapred.max.split.size=1874231 -d wasb:///example/data/KDDTrain+.arff -ds wasb:///example/data/KDDTrain+.info -sl 5 -p -t 100 -o nsl-forest
+
+ The output of this operation is stored in the __nsl-forest__ directory, which is located in storage for your HDInsight cluster at __wasb://user/&lt;username>/nsl-forest/nsl-forest.seq. The &lt;username> is the user name used for your remote desktop session. This file is not human readable.
+
+5. Test the forest by classifying the __KDDTest+.arff__ dataset using the following command.
+
+ hadoop jar c:/apps/dist/mahout-0.9.0.2.1.3.0-1887/examples/target/mahout-examples-0.9.0.2.1.3.0-1887-job.jar org.apache.mahout.classifier.df.mapreduce.TestForest -i wasb:///example/data/KDDTest+.arff -ds wasb:///example/data/KDDTrain+.info -m nsl-forest -a -mr -o wasb:///example/data/predictions
+
+ This command will return summary information on classification process similar to the following.
+
+ 14/07/02 14:29:28 INFO mapreduce.TestForest:
+
+ =======================================================
+ Summary
+ -------------------------------------------------------
+ Correctly Classified Instances : 17560 77.8921%
+ Incorrectly Classified Instances : 4984 22.1079%
+ Total Classified Instances : 22544
+
+ =======================================================
+ Confusion Matrix
+ -------------------------------------------------------
+ a b <--Classified as
+ 9437 274 | 9711 a = normal
+ 4710 8123 | 12833 b = anomaly
+
+ =======================================================
+ Statistics
+ -------------------------------------------------------
+ Kappa 0.5728
+ Accuracy 77.8921%
+ Reliability 53.4921%
+ Reliability (standard deviation) 0.4933
+
+ This job also produces a file located at __wasb:///example/data/predictions/KDDTest+.arff.out__, however this file is not human readable.
+
+> [WACOM.NOTE] Mahout jobs do not overwrite files. If you wish to run these jobs again, you must delete the files created by previous jobs.
+
+##<a name="troubleshooting"></a>Troubleshooting
+
+###<a name="install"></a>Install Mahout
+
+Mahout is installed on HDInsight 3.1 clusters, and can be installed manually on 3.0 or 2.1 clusters using the following steps.
+
+1. The version of Mahout to use depends on the HDInsight version of your cluster. You can find the cluster version by using the following with [Azure PowerShell][aps]:
+
+ PS C:\> Get-AzureHDInsightCluster -Name YourClusterName | Select version
+
+
+ * __For HDInsight 2.1__, you can download a jar file containing [Mahout 0.9](http://repo2.maven.org/maven2/org/apache/mahout/mahout-core/0.9/mahout-core-0.9-job.jar).
+
+ * __For HDInsight 3.0__,you must [build Mahout from source][build] and specify the Hadoop version provided by HDInsight. Install the prerequisits listed on the build page, download the source, and then use the following command to create the Mahout jar files.
+
+ mvn -Dhadoop2.version=2.2.0 -DskipTests clean package
+
+ Once the build completes, the jar file will be created at __mahout\mrlegacy\target\mahout-mrlegacy-1.0-SNAPSHOT-job.jar__.
+
+ > [WACOM.NOTE] Once Mahout 1.0 is released, you should be able to use the pre-built packages with HDInsight 3.0.
+
+2. Upload the jar file to __example/jars__ in the default storage for your cluster. The following example uses the [send-hdinsight][sendhdinsight] script to upload the file.
+
+ PS C:\> .\Send-HDInsight -LocalPath "path\to\mahout-core-0.9-job.jar" -DestinationPath "example/jars/mahout-core-0.9-job.jar" -ClusterName "your cluster name"
+
+###Cannot overwrite files
+
+Mahout jobs do not clean up temp files created during processing. In addition, the jobs will not overwrite an existing output file.
+
+To avoid errors when running Mahout jobs, either delete temp and output files between runs, or use unique temp and output directory names.
+
+###Cannot find the jar file
+
+While HDInsight 3.1 includes Mahout, the path and filename include the version number of Mahout installed on the cluster. The example PowerShell script in this tutorial uses a path that is valid as of July 2014, but the version number will change in future updates to HDInsight. To determine the current path to the Mahout jar file for your cluster, use the following PowerShell commands, then modify the script to reference the file path returned.
+
+ Use-AzureHDInsightCluster -Name $clusterName
+ $jarFile = Invoke-Hive -Query '!${env:COMSPEC} /c dir /b /s ${env:MAHOUT_HOME}\examples\target\*-job.jar'
+
+###<a name="nopowershell"></a>Classes that do not work with PowerShell
+
+Mahout jobs that use the following classes will return a variety of errors if used from PowerShell.
+
+* org.apache.mahout.utils.clustering.ClusterDumper
+* org.apache.mahout.utils.SequenceFileDumper
+* org.apache.mahout.utils.vectors.lucene.Driver
+* org.apache.mahout.utils.vectors.arff.Driver
+* org.apache.mahout.text.WikipediaToSequenceFile
+* org.apache.mahout.clustering.streaming.tools.ResplitSequenceFiles
+* org.apache.mahout.clustering.streaming.tools.ClusterQualitySummarizer
+* org.apache.mahout.classifier.sgd.TrainLogistic
+* org.apache.mahout.classifier.sgd.RunLogistic
+* org.apache.mahout.classifier.sgd.TrainAdaptiveLogistic
+* org.apache.mahout.classifier.sgd.ValidateAdaptiveLogistic
+* org.apache.mahout.classifier.sgd.RunAdaptiveLogistic
+* org.apache.mahout.classifier.sequencelearning.hmm.BaumWelchTrainer
+* org.apache.mahout.classifier.sequencelearning.hmm.ViterbiEvaluator
+* org.apache.mahout.classifier.sequencelearning.hmm.RandomSequenceGenerator
+* org.apache.mahout.classifier.df.tools.Describe
+
+To run jobs that use these classes, connect to the HDInsight cluster and run the jobs using the Hadoop command line. See [Classify data using the Hadoop command line](#classify) for an example.
+
+
+[build]: http://mahout.apache.org/developers/buildingmahout.html
+[aps]: http://azure.microsoft.com/en-us/documentation/articles/install-configure-powershell/
+[movielens]: http://grouplens.org/datasets/movielens/
+[100k]: http://files.grouplens.org/datasets/movielens/ml-100k.zip
+[getstarted]: http://azure.microsoft.com/en-us/documentation/articles/hdinsight-get-started/
+[upload]: http://azure.microsoft.com/en-us/documentation/articles/hdinsight-upload-data/
+[ml]: http://en.wikipedia.org/wiki/Machine_learning
+[forest]: http://en.wikipedia.org/wiki/Random_forest
+[management]: https://manage.windowsazure.com/
+[enableremote]: ./media/hdinsight-mahout/enableremote.png
+[connect]: ./media/hdinsight-mahout/connect.png
+[hadoopcli]: ./media/hdinsight-mahout/hadoopcli.png
+[tools]: https://github.com/Blackmist/hdinsight-tools
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-1-browser-access.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-2-home-page.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-5-memegenerator.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-6-addview.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-7-configureview.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-1-new-project.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-10-createcdn.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-11-disablequerya.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-12-disablequeryb.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-13-testcdn.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-2-select-role.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-3-mvc-template.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-4-publish-a.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-5-publish-signin.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-6-publish-signedin.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-7-publish-createserviceandstorage.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-8-publish-finalize.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-cloud-service-with-cdn/cdn-cs-9-published.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-mvc-1-accountkey.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-1.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-10.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-blob.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-11-cdn.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequerya.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2-enablequeryb.PNG
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-2.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-fail.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-3-succeed.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-4.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-5.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-6.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-7.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-8.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-static-9.PNG
View
Diff not rendered
BIN  articles/media/cdn-serve-content-from-cdn-in-your-web-application/cdn-updates-1.PNG
View
Diff not rendered
BIN  articles/media/hdinsight-mahout/connect.png
View
Diff not rendered
BIN  articles/media/hdinsight-mahout/enableremote.png
View
Diff not rendered
BIN  articles/media/hdinsight-mahout/hadoopcli.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/browse_vm_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/connect_vm_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/create_vm_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/image_gallery_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/new_button_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/vm_diagnostics_status_preview_portal.png
View
Diff not rendered
BIN  articles/media/virtual-machines-windows-tutorial-azure-preview/vm_startboard_preview_portal.png
View
Diff not rendered
64 articles/mobile-services-android-get-started-users.md
View
@@ -45,69 +45,7 @@ Next, you will update the app to authenticate users before requesting resources
<h2><a name="add-authentication"></a><span class="short-header">Add authentication</span>Add authentication to the app</h2>
-1. In the Package Explorer in Eclipse, open the ToDoActivity.java file and add the following import statements.
-
- import com.microsoft.windowsazure.mobileservices.MobileServiceUser;
- import com.microsoft.windowsazure.mobileservices.MobileServiceAuthenticationProvider;
- import com.microsoft.windowsazure.mobileservices.UserAuthenticationCallback;
-
-2. Add the following method to the **ToDoActivity** class:
-
- private void authenticate() {
-
- // Login using the Google provider.
- mClient.login(MobileServiceAuthenticationProvider.Google,
- new UserAuthenticationCallback() {
-
- @Override
- public void onCompleted(MobileServiceUser user,
- Exception exception, ServiceFilterResponse response) {
-
- if (exception == null) {
- createAndShowDialog(String.format(
- "You are now logged in - %1$2s",
- user.getUserId()), "Success");
- createTable();
- } else {
- createAndShowDialog("You must log in. Login Required", "Error");
- }
- }
- });
- }
-
- This creates a new method to handle the authentication process. The user is authenticated by using a Google login. A dialog is displayed which displays the ID of the authenticated user. You cannot proceed without a positive authentication.
-
- <div class="dev-callout"><b>Note</b>
- <p>If you are using an identity provider other than Google, change the value passed to the <strong>login</strong> method above to one of the following: <em>MicrosoftAccount</em>, <em>Facebook</em>, <em>Twitter</em>, or <em>windowsazureactivedirectory</em>.</p>
- </div>
-
-3. In the **onCreate** method, add the following line of code after the code that instantiates the `MobileServiceClient` object.
-
- authenticate();
-
- This call starts the authentication process.
-
-4. Move the remaining code after `authenticate();` in the **onCreate** method to a new **createTable** method, which looks like this:
-
- private void createTable() {
-
- // Get the Mobile Service Table instance to use
- mToDoTable = mClient.getTable(ToDoItem.class);
-
- mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
-
- // Create an adapter to bind the items with the view
- mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
- ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
- listViewToDo.setAdapter(mAdapter);
-
- // Load the items from the Mobile Service
- refreshItemsFromTable();
- }
-
-9. From the **Run** menu, then click **Run** to start the app and sign in with your chosen identity provider.
-
- When you are successfully logged-in, the app should run without errors, and you should be able to query Mobile Services and make updates to data.
+[WACOM.INCLUDE [mobile-services-android-authenticate-app](../includes/mobile-services-android-authenticate-app.md)]
## <a name="next-steps"></a>Next steps
78 articles/mobile-services-dotnet-backend-android-get-started-users.md
View
@@ -0,0 +1,78 @@
+<properties pageTitle="Get started with authentication (Android) | Mobile Dev Center" metaKeywords="authentication, Facebook, Google, Twitter, Microsoft Account, login" description="Learn how to use Mobile Services to authenticate users of your Windows Store app through a variety of identity providers, including Google, Facebook, Twitter, and Microsoft." metaCanonical="" services="mobile" documentationCenter="Mobile" title="Get started with authentication in Mobile Services" authors="mahender" solutions="" manager="" editor="" />
+
+# Get started with authentication in Mobile Services
+
+<div class="dev-center-tutorial-selector sublanding">
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS" >iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android" class="current">Android</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
+</div>
+
+<div class="dev-center-tutorial-subselector">
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users/" title=".NET backend" class="current">.NET backend</a> | <a href="/en-us/documentation/articles/mobile-services-android-get-started-users/" title="JavaScript backend">JavaScript backend</a></div>
+
+This topic shows you how to authenticate users in Azure Mobile Services from your app. In this tutorial, you add authentication to the quickstart project using an identity provider that is supported by Mobile Services. After being successfully authenticated and authorized by Mobile Services, the user ID value is displayed.
+
+This tutorial walks you through these basic steps to enable authentication in your app:
+
+1. [Register your app for authentication and configure Mobile Services]
+2. [Restrict table permissions to authenticated users]
+3. [Add authentication to the app]
+<!--4. [Storing authentication tokens in your app]-->
+
+This tutorial is based on the Mobile Services quickstart. You must also first complete the tutorial [Get started with Mobile Services].
+
+##<a name="register"></a>Register your app for authentication and configure Mobile Services
+
+[WACOM.INCLUDE [mobile-services-register-authentication](../includes/mobile-services-register-authentication.md)]
+
+[WACOM.INCLUDE [mobile-services-dotnet-backend-aad-server-extension](../includes/mobile-services-dotnet-backend-aad-server-extension.md)]
+
+##<a name="permissions"></a>Restrict permissions to authenticated users
+
+[WACOM.INCLUDE [mobile-services-restrict-permissions-dotnet-backend](../includes/mobile-services-restrict-permissions-dotnet-backend.md)]
+
+3. In Eclipse, open the project that you created when you completed the tutorial [Get started with Mobile Services].
+
+4. From the **Run** menu, then click **Run** to start the app; verify that an unhandled exception with a status code of 401 (Unauthorized) is raised after the app starts.
+
+ This happens because the app attempts to access Mobile Services as an unauthenticated user, but the _TodoItem_ table now requires authentication.
+
+Next, you will update the app to authenticate users before requesting resources from the mobile service.
+
+##<a name="add-authentication"></a>Add authentication to the app
+
+[WACOM.INCLUDE [mobile-services-android-authenticate-app](../includes/mobile-services-android-authenticate-app.md)]
+
+<!--
+##<a name="store-authentication"></a>Storing authentication tokens in your app
+
+[WACOM.INCLUDE [mobile-services-android-authenticate-app-with-token](../includes/mobile-services-android-authenticate-app-with-token.md)]
+-->
+
+##<a name="next-steps"></a>Next steps
+
+In the next tutorial, [Service-side authorization of Mobile Services users][Authorize users with scripts], you will take the user ID value provided by Mobile Services based on an authenticated user and use it to filter the data returned by Mobile Services.
+
+
+<!-- Anchors. -->
+[Register your app for authentication and configure Mobile Services]: #register
+[Restrict table permissions to authenticated users]: #permissions
+[Add authentication to the app]: #add-authentication
+[Next Steps]:#next-steps
+[Storing authentication tokens in your app]:#store-authentication
+
+<!-- URLs. -->
+[Get started with Mobile Services]: /en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started/
+[Get started with data]: /en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-data/
+[Get started with authentication]: /en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users/
+[Get started with push notifications]: /en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-push/
+[Authorize users with scripts]: /en-us/documentation/articles/mobile-services-dotnet-backend-android-authorize-users-in-scripts
+
+[Azure Management Portal]: https://manage.windowsazure.com/
+[Mobile Services .NET How-to Conceptual Reference]: /en-us/develop/mobile/how-to-guides/work-with-net-client-library
+[Register your Windows Store app package for Microsoft authentication]: /en-us/documentation/articles/mobile-services-how-to-register-store-app-package-microsoft-authentication
10 articles/mobile-services-dotnet-backend-calling-sharepoint-on-behalf-of-user.md
View
@@ -2,7 +2,15 @@
# Access SharePoint on behalf of the user
-This topic shows you how to access the SharePoint APIs on behalf of the currently logged-in user. In this tutorial, you will update the app from the Authenticate your app with Active Directory Authentication Library Single Sign-On tutorial to create a Word document in SharePoint Online when a new TodoItem is added.
+<div class="dev-onpage-video-clear clearfix">
+<div class="dev-onpage-left-content">
+<p>This topic shows you how to access the SharePoint APIs on behalf of the currently logged-in user.</p>
+<p>If you prefer to watch a video, the clip to the right follows the same steps as this tutorial. In the video, Mat Velloso walks you through updating a Windows Store app to interact with SharePoint Online.</p>
+</div>
+<div class="dev-onpage-video-wrapper"><a href="http://channel9.msdn.com/Series/Windows-Azure-Mobile-Services/Azure-Mobile-Services-AAD-O365-Authentication-identity-across-services" target="_blank" class="label">watch the tutorial</a> <a style="background-image: url('http://media.ch9.ms/ch9/f217/3f8cbf94-f36b-4162-b3da-1c00339ff217/AzureMobileServicesAADO365AuthenticationIdentityA_960.jpg') !important;" href="http://channel9.msdn.com/Series/Windows-Azure-Mobile-Services/Azure-Mobile-Services-AAD-O365-Authentication-identity-across-services" target="_blank" class="dev-onpage-video"><span class="icon">Play Video</span></a> <span class="time">12:51</span></div>
+</div>
+
+In this tutorial, you will update the app from the Authenticate your app with Active Directory Authentication Library Single Sign-On tutorial to create a Word document in SharePoint Online when a new TodoItem is added.
This tutorial walks you through these basic steps to enable on-behalf-of access to SharePoint:
6 articles/mobile-services-dotnet-backend-ios-get-started-users.md
View
@@ -2,7 +2,11 @@
# Get started with authentication in Mobile Services
-<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS" class="current">iOS</a><!--<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>-->
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS" class="current">iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
</div>
6 articles/mobile-services-dotnet-backend-windows-phone-get-started-users.md
View
@@ -2,7 +2,11 @@
# Get started with authentication in Mobile Services
-<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone" class="current">Windows Phone</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a><!--<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>-->
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone" class="current">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
</div>
11 articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users.md
View
@@ -2,8 +2,11 @@
# Get started with authentication in Mobile Services
-<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#" class="current">Windows Store C#</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a>
-<!--<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>-->
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#" class="current">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
</div>
@@ -55,7 +58,9 @@ Next, you will update the app to authenticate users before requesting resources
[WACOM.INCLUDE [mobile-services-windows-dotnet-authenticate-app](../includes/mobile-services-windows-dotnet-authenticate-app.md)]
->[WACOM.NOTE]If you registered your Windows Store app package information with Mobile Services, you should call the <a href="http://go.microsoft.com/fwlink/p/?LinkId=311594" target="_blank">LoginAsync</a> method by supplying a value of <strong>true</strong> for the <em>useSingleSignOn</em> parameter. If you do not do this, your users will still be presented with a login prompt every time that the login method is called.
+<!-- Currently not supported
+[WACOM.NOTE]If you registered your Windows Store app package information with Mobile Services, you should call the <a href="http://go.microsoft.com/fwlink/p/?LinkId=311594" target="_blank">LoginAsync</a> method by supplying a value of <strong>true</strong> for the <em>useSingleSignOn</em> parameter. If you do not do this, your users will still be presented with a login prompt every time that the login method is called.
+-->
##<a name="tokens"></a>Store the authorization tokens on the client
6 articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users.md
View
@@ -2,7 +2,11 @@
# Get started with authentication in Mobile Services
-<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript" class="current">Windows Store JavaScript</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a><!--<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>-->
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript" class="current">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
</div>
2  articles/mobile-services-dotnet-backend-xamarin-android-get-started-users.md
View
@@ -7,7 +7,7 @@
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="iOS">iOS</a>
- <!-- <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a> -->
+ <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS">Xamarin.iOS</a>
<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android" class="current">Xamarin.Android</a>
</div>
9 articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users.md
View
@@ -3,8 +3,13 @@
# Get started with authentication in Mobile Services
<div class="dev-center-tutorial-selector sublanding">
- <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a><!-- <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a> -->
- <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS" class="current">Xamarin.iOS</a><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
+ <a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-dotnet-get-started-users" title="Windows Store C#">Windows Store C#</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-store-javascript-get-started-users" title="Windows Store JavaScript">Windows Store JavaScript</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-windows-phone-get-started-users" title="Windows Phone">Windows Phone</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-ios-get-started-users" title="iOS">iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-android-get-started-users" title="Android">Android</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users" title="Xamarin.iOS" class="current">Xamarin.iOS</a>
+<a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-android-get-started-users" title="Xamarin.Android">Xamarin.Android</a>
</div>
<div class="dev-center-tutorial-subselector"><a href="/en-us/documentation/articles/mobile-services-dotnet-backend-xamarin-ios-get-started-users/" title=".NET backend" class="current">.NET backend</a> | <a href="/en-us/documentation/articles/partner-xamarin-mobile-services-ios-get-started-users/" title="JavaScript backend">JavaScript backend</a></div>
2  articles/mobile-services-windows-phone-handling-conflicts-offline-data.md
View
@@ -1,5 +1,3 @@
-
-
<properties linkid="develop-mobile-tutorials-handle-conflcits-offline-data-dotnet" urlDisplayName="Handle Conflicts with Offline Data" pageTitle="Handle Conflicts with offline data in Mobile Services (Windows Phone) | Mobile Dev Center" metaKeywords="" description="Learn how to handle conflicts with offline data in your Windows Phone application." metaCanonical="" disqusComments="1" umbracoNaviHide="1" documentationCenter="Mobile" title="Handling conflicts with offline data in Mobile Services" authors="wesmc" />
1  articles/mobile-services-windows-store-dotnet-adal-sso-authentication.md
View
@@ -1,4 +1,3 @@
-
<properties linkid="develop-mobile-tutorials-sso-with-adal" urlDisplayName="Active Directory SSO Authentication with ADAL" pageTitle="Authenticate your app with Active Directory Authentication Library Single Sign-On (Windows Store) | Mobile Dev Center" metaKeywords="" description="Learn how to authentication users for single sign-on with ADAL in your Windows Store application." metaCanonical="" disqusComments="1" umbracoNaviHide="1" documentationCenter="Mobile" title="Authenticate your app with Active Directory Authentication Library Single Sign-On" authors="wesmc" />
# Authenticate your app with Active Directory Authentication Library Single Sign-On
2  articles/mobile-services-windows-store-dotnet-handling-conflicts-offline-data.md
View
@@ -1,5 +1,3 @@
-
-
<properties linkid="develop-mobile-tutorials-handle-conflcits-offline-data-dotnet" urlDisplayName="Handle Conflicts with Offline Data" pageTitle="Handle Conflicts with offline data in Mobile Services (Windows Store) | Mobile Dev Center" metaKeywords="" description="Learn how to handle conflicts with offline data in your Windows Store application." metaCanonical="" disqusComments="1" umbracoNaviHide="1" documentationCenter="Mobile" title="Handling conflicts with offline data in Mobile Services" authors="wesmc" />
4 articles/virtual-machines-create-custom.md
View
@@ -1,4 +1,4 @@
-<properties linkid="manage-linux-howto-custom-create-vm" urlDisplayName="Custom create a VM" pageTitle="Custom create a virtual machine running Linux in Azure" metaKeywords="Azure custom vm, creating custom vm" description="Learn how to create a custom virtual machine in Azure." metaCanonical="http://www.windowsazure.com/en-us/manage/windows/how-to-guides/custom-create-a-vm/" services="virtual-machines" documentationCenter="" title="" authors="kathydav" solutions="" manager="dongill" editor="tysonn" />
+<properties linkid="manage-linux-howto-custom-create-vm" urlDisplayName="Create a custom VM" pageTitle=" Create a custom virtual machine running Linux in Azure" metaKeywords="Azure custom vm, creating custom vm" description="Learn how to create a custom virtual machine in Azure." metaCanonical="http://www.windowsazure.com/en-us/manage/windows/how-to-guides/custom-create-a-vm/" services="virtual-machines" documentationCenter="" title="" authors="kathydav" solutions="" manager="dongill" editor="tysonn" />
#How to Create a Custom Virtual Machine
@@ -10,7 +10,7 @@ A *custom* virtual machine refers to a virtual machine you create using the **Fr
- Adding the VM to an existing cloud service
- Adding the VM to an availability set
-**Important**: If you want your virtual machine to use a virtual network so you can connect to it directly by hostname or set up cross-premises connections, make sure you specify the virtual network when you create the virtual machine. A virtual machine can be configured to join a virtual network only when you create the virtual machine. For more information about virtual networks, see [Azure Virtual Network Overview](http://go.microsoft.com/fwlink/p/?LinkID=294063).
+**Important**: If you want your virtual machine to use a virtual network so you can connect to it directly by hostname or set up cross-premises connections, make sure you specify the virtual network when you create the virtual machine. A virtual machine can be configured to join a virtual network only when you create the virtual machine. For details on virtual networks, see [Azure Virtual Network Overview](http://go.microsoft.com/fwlink/p/?LinkID=294063).
[WACOM.INCLUDE [virtual-machines-create-WindowsVM](../includes/virtual-machines-create-WindowsVM.md)]
1  articles/virtual-machines-create-upload-vhd-windows-server.md
View
@@ -1,4 +1,3 @@
-
<properties linkid="manage-windows-common-task-upload-vhd" urlDisplayName="Upload a VHD" pageTitle="Create and upload a Windows Server VHD to Azure" metaKeywords="Azure VHD, uploading VHD" description="Learn how to create and upload a virtual hard disk (VHD) in Azure that has the Windows Server operating system." metaCanonical="" services="virtual-machines" documentationCenter="" title="Creating and Uploading a Virtual Hard Disk that Contains the Windows Server Operating System" authors="kathydav" solutions="" manager="dongill" editor="tysonn" />
4 articles/virtual-machines-install-symantec.md
View
@@ -40,12 +40,12 @@ Open an Azure PowerShell session and run the following commands. Be sure to subs
<p>`$name = MyVmName`
<p>`$vm = Get-AzureVM -ServiceName $servicename -Name $name`
- > [WACOM.NOTE] If you don't know the cloud service and VM name, run Get-AzureVM to display that information for all VMs in the current subscription.
+ > [WACOM.NOTE] If you don't know the cloud service and VM name, run Get-AzureVM to display that information for all VMs in the current subscription.
2. Add Symantec Endpoint Protection Agent to the virtual machine. To install the latest version, run:
<p>`Set-AzureVMExtension -Publisher Symantec -ExtensionName SymantecEndpointProtection -VM $vm.VM`
- > [WACOM.NOTE] If you want to install a specific version, run the following command to get a list of available versions: `Get-AzureVMAvailableExtension Publisher Symantec ExtensionName SymantecEndpointProtection`.
+ > [WACOM.NOTE] If you want to install a specific version, run the following command to get a list of available versions: `Get-AzureVMAvailableExtension -Publisher Symantec -ExtensionName SymantecEndpointProtection`.
Then, include the Version parameter when you run Set-AzureVMExtension.
3. Update the VM, which installs the Symantec Endpoint Protection Agent:
4 articles/virtual-machines-install-trend.md
View
@@ -37,12 +37,12 @@ Open an Azure PowerShell session and run the following commands. Be sure to subs
<p>`$name = MyVmName`
<p>`$vm = Get-AzureVM -ServiceName $servicename -Name $name`
- > [WACOM.NOTE] If you don't know the cloud service and VM name, run Get-AzureVM to display that information for all VMs in the current subscription.
+ > [WACOM.NOTE] If you don't know the cloud service and VM name, run Get-AzureVM to display that information for all VMs in the current subscription.
2. Add the Deep Security Agent to the virtual machine:
<p> `Set-AzureVMExtension -Publisher TrendMicro.DeepSecurity -ExtensionName TrendMicroDSA -VM $vm.VM`
- > [WACOM.NOTE] If you want to install a specific version, run the following command to get a list of available versions: `Get-AzureVMAvailableExtension TrendMicro.DeepSecurity -ExtensionName TrendMicroDSA`. Then, include the Version parameter when you run Set-AzureVMExtension.
+ > [WACOM.NOTE] If you want to install a specific version, run the following command to get a list of available versions: `Get-AzureVMAvailableExtension TrendMicro.DeepSecurity -ExtensionName TrendMicroDSA`. Then, include the Version parameter when you run Set-AzureVMExtension.
3. Update the VM, which installs the Deep Security Agent:
<p> `Update-AzureVM -ServiceName $servicename -Name $name -VM $vm.VM`
95 articles/virtual-machines-windows-tutorial-azure-preview.md
View
@@ -0,0 +1,95 @@
+<properties linkid="virtual-machines-windows-tutorial-azure-preview" urlDisplayName="Create a virtual machine in the Preview Portal" pageTitle="Create a virtual machine running Windows Server in the Azure Preview Portal" metaKeywords="Azure image gallery vm" description="Learn how to create an Azure virtual machine (VM) running Windows Server, using the VM Gallery in the Azure Preview Portal" metaCanonical="" services="virtual-machines" documentationCenter="" title="" authors="danlep,kathydav" solutions="" manager="dongill" editor="tysonn" />
+
+
+
+# Create a Virtual Machine Running Windows Server in the Azure Preview Portal#
+
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/virtual-machines-windows-tutorial/" title="Azure Portal">Azure Portal</a><a href="/en-us/documentation/articles/virtual-machines-windows-tutorial-azure-preview/" title="Azure Preview Portal" class="current">Azure Preview Portal</a></div>
+
+This tutorial shows you how easy it is to create an Azure virtual machine (VM) running Windows Server, using the VM Gallery in the Azure Preview Portal. The Gallery offers a variety of images, including Windows operating systems, Linux-based operating systems, and application images.
+
+> [WACOM.NOTE] You don't need any experience with Azure VMs to finish this tutorial. However, you do need an Azure account. You can create a free trial account in just a couple of minutes. For details, see [Create an Azure account](http://www.windowsazure.com/en-us/develop/php/tutorials/create-a-windows-azure-account/).
+
+This tutorial shows you:
+
+- [How to create the virtual machine](#createvirtualmachine)
+- [How to log on to the virtual machine after you create it](#logon)
+
+If you'd like to know more, see [Virtual Machines](http://go.microsoft.com/fwlink/p/?LinkID=271224).
+
+
+##<a id="createvirtualmachine"> </a>How to create the virtual machine##
+
+This section shows you how to use the Preview Portal to create a VM running Windows Server. You can use Azure's default settings for most of the configuration and create the VM in just a few minutes.
+
+
+1. Sign in to the [Azure Preview Portal](https://portal.azure.com). Check out the [Free Trial](http://www.windowsazure.com/en-us/pricing/free-trial/) offer if you do not have a subscription yet.
+
+2. On the Hub menu, click **New**.
+
+ ![Select New from the Command Bar](./media/virtual-machines-windows-tutorial-azure-preview/new_button_preview_portal.png)
+
+3. Under **New**, click **Everything**, and then under **Gallery**, click **Virtual machines**. Click **Windows Server 2012 R2 Datacenter**. From there, click **Create**.
+
+ ![Select a VM image from the Gallery](./media/virtual-machines-windows-tutorial-azure-preview/image_gallery_preview_portal.png)
+
+4. On the **Create VM** blade, fill in the **Host Name** you want for the VM, the administrative **User Name**, and a strong **Password**.
+
+ ![Configure host name and log on credentials](./media/virtual-machines-windows-tutorial-azure-preview/create_vm_preview_portal.png)
+
+ >[WACOM.NOTE] **User Name** refers to the administrative account that you use to manage the server. Create a unique password for this account and make sure to remember it. **You'll need the user name and password to log on to the virtual machine**.
+
+5. To use the default settings for the remaining VM options and start creating the VM, click **Create**. But if you want, before clicking **Create**, you can explore **Optional Configuration** settings. For example, you can configure optional diagnostics on the VM to track lots of metrics on your VM later on. Click **Optional Configuration**, click **Diagnostics**, and toggle the **Status** to **On**.
+
+ ![Turn on VM diagnostics](./media/virtual-machines-windows-tutorial-azure-preview/vm_diagnostics_status_preview_portal.png)
+
+ >[WACOM.NOTE] If you turn on Azure Diagnostics, Azure will store the diagnostics data in an Azure storage account, resulting in additional storage cost.
+
+6. While Azure creates the VM, you can keep track of the progress in **Notifications**, in the Hub menu. After Azure creates the VM, you will see it on your Startboard.
+
+ ![VM appears on the Startboard](./media/virtual-machines-windows-tutorial-azure-preview/vm_startboard_preview_portal.png)
+
+## <a id="logon"> </a>How to log on to the virtual machine after you create it ##
+
+This section shows you how to log on to the VM so you can manage its settings and the applications that you'll run on it.
+
+>[WACOM.NOTE] For requirements and troubleshooting tips, see [Connect to an Azure virtual machine with RDP or SSH](http://go.microsoft.com/fwlink/p/?LinkId=398294).
+
+1. If you have not already done so, sign in to the [Azure Preview Portal](https://portal.azure.com).
+
+2. Click your VM on the Startboard. If you need to find it, click **Browse** and then click **Virtual machines**.
+
+ ![Browse to find the VM](./media/virtual-machines-windows-tutorial-azure-preview/browse_vm_preview_portal.png)
+
+3. On the VM blade, click **Connect** at the top.
+
+ ![Log on to the virtual machine](./media/virtual-machines-windows-tutorial-azure-preview/connect_vm_preview_portal.png)
+
+4. Click **Open** to use the Remote Desktop Protocol file that was automatically created for the virtual machine.
+
+5. Click **Connect** to proceed with the connection process.
+
+ ![Continue with connecting](./media/virtual-machines-log-on-windows-server/connectpublisher.png)
+
+6. Type the user name and password of the administrative account on the virtual machine, and then click **OK**.
+
+7. Click **Yes** to verify the identity of the virtual machine.
+
+ ![Verify the identity of the machine](./media/virtual-machines-log-on-windows-server/connectverify.png)
+
+ You can now work with the virtual machine just as you would with any other server.
+
+##Next Steps
+
+To learn more about configuring Windows virtual machines on Azure, see the following articles:
+
+[How to Connect Virtual Machines in a Cloud Service](http://www.windowsazure.com/en-us/documentation/articles/cloud-services-connect-virtual-machine/)
+
+[How to Create and Upload your own Virtual Hard Disk containing the Windows Server Operating System](http://www.windowsazure.com/en-us/documentation/articles/virtual-machines-create-upload-vhd-windows-server/)
+
+[Attach Data Disks to a Virtual Machine](http://www.windowsazure.com/en-us/documentation/articles/storage-windows-attach-disk/)
+
+[Manage the Availability of Virtual Machines](http://www.windowsazure.com/en-us/documentation/articles/manage-availability-virtual-machines/)
+
+[How to create the virtual machine]: #custommachine
+[How to log on to the virtual machine after you create it]: #logon
6 articles/virtual-machines-windows-tutorial.md
View
@@ -4,6 +4,8 @@
# Create a Virtual Machine Running Windows Server #
+<div class="dev-center-tutorial-selector sublanding"><a href="/en-us/documentation/articles/virtual-machines-windows-tutorial/" title="Azure Portal" class="current">Azure Portal</a><a href="/en-us/documentation/articles/virtual-machines-windows-tutorial-azure-preview/" title="Azure Preview Portal">Azure Preview Portal</a></div>
+
This tutorial shows you how easy it is to create an Azure virtual machine (VM) running Windows Server, using the Image Gallery in the Azure Management Portal. The Image Gallery offers a variety of images, including Windows operating systems, Linux-based operating systems, and application images.
> [WACOM.NOTE] You don't need any experience with Azure VMs to finish this tutorial. However, you do need an Azure account. You can create a free trial account in just a couple of minutes. For details, see [Create an Azure account](http://www.windowsazure.com/en-us/develop/php/tutorials/create-a-windows-azure-account/).
@@ -21,6 +23,8 @@ If you'd like to know more, see [Virtual Machines](http://go.microsoft.com/fwlin
This section shows you how to use the **From Gallery** option in the Management Portal to create the virtual machine. This option provides more configuration choices than the **Quick Create** option. For example, if you want to join a virtual machine to a virtual network, you'll need to use the **From Gallery** option.
+> [WACOM.NOTE] You can also try the richer, customizable [Azure Preview Portal](https://portal.azure.com) to create a virtual machine, automate the deployment of multi-machine application templates, use enhanced VM monitoring and diagnostics features, and more. The available VM configuration options in the two Portals overlap substantially but are not identical.
+
[WACOM.INCLUDE [virtual-machines-create-WindowsVM](../includes/virtual-machines-create-WindowsVM.md)]
## <a id="logon"> </a>How to log on to the virtual machine after you create it ##
@@ -31,7 +35,7 @@ This section shows you how to log on to the virtual machine so you can manage it
## <a id="attachdisk"> </a>How to attach a data disk to the new virtual machine ##
-This section shows you how to attach an empty data disk to the virtual machine. See the [Attach a Data Disk Tutorial] (http://www.windowsazure.com/en-us/documentation/articles/storage-windows-attach-disk/) for more information on attaching empty disks as well as how to attach existing disks.
+This section shows you how to attach an empty data disk to the virtual machine. See the [Attach a Data Disk Tutorial](http://www.windowsazure.com/en-us/documentation/articles/storage-windows-attach-disk/) for more information on attaching empty disks as well as how to attach existing disks.
1. Sign in to the Azure [Management Portal](http://manage.windowsazure.com).
2  includes/CreateVirtualMachineWindowsTutorial.md
View
@@ -1,3 +1,5 @@
+<properties title="Create a Virtual Machine Running Windows Server" pageTitle="How to create a Virtual Machine Running Windows Server" description="Describes how to create a Windows virtual machine, add a data disk, and log on remotely" metaKeywords="" services="virtual machines" solutions="" documentationCenter="" authors="kathydav" videoId="" scriptId="" />
+
# Create a Virtual Machine Running Windows Server #
This tutorial shows you how easy it is to create an Azure virtual machine running Windows Server, using the Image Gallery in the Windows Azure Management Portal. The Image Gallery offers a variety of images, including Windows operating systems, Linux-based operating systems, and application images.
8 includes/free-trial-note.md
View
@@ -0,0 +1,8 @@
+<div class="wa-note">
+ <span class="wa-icon-bulb"></span>
+ <h5><a name="note"></a>You need an Azure account to complete this tutorial:</h5>
+ <ul>
+ <li>You can <a href="/en-us/pricing/free-trial/?WT.mc_id=A261C142F">open an Azure account for free</a> - You get credits you can use to try out paid Azure services, and even after they're used up you can keep the account and use free Azure services, such as Web Sites. Your credit card will never be charged, unless you explicitly change your settings and ask to be charged.</li>
+ <li>You can <a href="/en-us/pricing/member-offers/msdn-benefits-details/?WT.mc_id=A261C142F">activate MSDN subscriber benefits</a> - Your MSDN subscription gives you credits every month that you can use for paid Azure services.</li>
+ <ul>
+</div>
BIN  includes/media/virtual-machines-create-WindowsVM/agent-and-extensions.png
View
Diff not rendered
BIN  includes/media/virtual-machines-create-WindowsVM/chooseimage.png
View
Diff not rendered
BIN  includes/media/virtual-machines-create-WindowsVM/commandbarnew.png
View
Diff not rendered
BIN  includes/media/virtual-machines-create-WindowsVM/resourceconfiguration.png
View
Diff not rendered
BIN  includes/media/virtual-machines-create-WindowsVM/vmconfiguration.png
View
Diff not rendered
BIN  includes/media/virtual-machines-create-WindowsVM/vmcreated.png
View
Diff not rendered
64 includes/mobile-services-android-authenticate-app.md
View
@@ -0,0 +1,64 @@
+
+1. In the Package Explorer in Eclipse, open the ToDoActivity.java file and add the following import statements.
+
+ import com.microsoft.windowsazure.mobileservices.MobileServiceUser;
+ import com.microsoft.windowsazure.mobileservices.MobileServiceAuthenticationProvider;
+ import com.microsoft.windowsazure.mobileservices.UserAuthenticationCallback;
+
+2. Add the following method to the **ToDoActivity** class:
+
+ private void authenticate() {
+
+ // Login using the Google provider.
+ mClient.login(MobileServiceAuthenticationProvider.Google,
+ new UserAuthenticationCallback() {
+
+ @Override
+ public void onCompleted(MobileServiceUser user,
+ Exception exception, ServiceFilterResponse response) {
+
+ if (exception == null) {
+ createAndShowDialog(String.format(
+ "You are now logged in - %1$2s",
+ user.getUserId()), "Success");
+ createTable();
+ } else {
+ createAndShowDialog("You must log in. Login Required", "Error");
+ }
+ }
+ });
+ }
+
+ This creates a new method to handle the authentication process. The user is authenticated by using a Google login. A dialog is displayed which displays the ID of the authenticated user. You cannot proceed without a positive authentication.
+
+ <div class="dev-callout"><b>Note</b>
+ <p>If you are using an identity provider other than Google, change the value passed to the <strong>login</strong> method above to one of the following: <em>MicrosoftAccount</em>, <em>Facebook</em>, <em>Twitter</em>, or <em>windowsazureactivedirectory</em>.</p>
+ </div>
+
+3. In the **onCreate** method, add the following line of code after the code that instantiates the `MobileServiceClient` object.
+
+ authenticate();
+
+ This call starts the authentication process.
+
+4. Move the remaining code after `authenticate();` in the **onCreate** method to a new **createTable** method, which looks like this:
+
+ private void createTable() {
+
+ // Get the Mobile Service Table instance to use
+ mToDoTable = mClient.getTable(ToDoItem.class);
+
+ mTextNewToDo = (EditText) findViewById(R.id.textNewToDo);
+
+ // Create an adapter to bind the items with the view
+ mAdapter = new ToDoItemAdapter(this, R.layout.row_list_to_do);
+ ListView listViewToDo = (ListView) findViewById(R.id.listViewToDo);
+ listViewToDo.setAdapter(mAdapter);
+
+ // Load the items from the Mobile Service
+ refreshItemsFromTable();
+ }
+
+9. From the **Run** menu, then click **Run** to start the app and sign in with your chosen identity provider.
+
+ When you are successfully logged-in, the app should run without errors, and you should be able to query Mobile Services and make updates to data.
19 includes/virtual-machines-create-WindowsVM.md
View
@@ -1,8 +1,6 @@
1. Sign in to the Windows Azure [Management Portal](http://manage.windowsazure.com). Check out the [Free Trial](http://www.windowsazure.com/en-us/pricing/free-trial/) offer if you do not have a subscription yet.
-2. On the command bar at the bottom of the screen, click **New**.
-
- ![Select New from the Command Bar](./media/virtual-machines-create-WindowsVM/commandbarnew.png)
+2. On the command bar at the bottom of the window, click **New**.
3. Under **Compute**, click **Virtual Machine**, and then click **From Gallery**.
@@ -12,19 +10,20 @@
![Choose an image](./media/virtual-machines-create-WindowsVM/chooseimage.png)
-5. The second screen lets you pick a computer name, size, and administrative user name and password. For this tutorial, fill in the fields as shown in the image below. Then, click the arrow to continue.
+5. The second screen lets you pick a computer name, size, and administrative user name and password. For this tutorial, fill in the fields as shown in the image below. Then, click the arrow to continue. Here are some details to help you fill this out:
+
+ - **New User Name** refers to the administrative account that you use to manage the server. Create a unique password for this account and make sure to remember it. **You'll need the user name and password to log on to the virtual machine**.
- >[WACOM.NOTE] **New User Name** refers to the administrative account that you use to manage the server. Create a unique password for this account and make sure to remember it. **You'll need the user name and password to log on to the virtual machine**.
+ - A virtual machine's size affects the cost of using it, as well as configuration options such as the number of data disks you can attach. For details, see [Virtual Machine and Cloud Service Sizes for Azure](http://go.microsoft.com/fwlink/p/?LinkId=466520).
![Configure the properties of the virtual machine](./media/virtual-machines-create-WindowsVM/vmconfiguration.png)
-
-6. The third screen lets you configure resources such as the cloud service and the storage account. When this screen is complete, click the arrow to continue. Some tips to help you fill this out are:
+6. The third screen lets you configure resources such as the cloud service and the storage account. When this screen is complete, click the arrow to continue. Here are some details to help you fill this out:
- - The **Cloud Service DNS Name** is the global DNS name that becomes part of the URI that is used to contact the virtual machine. You'll need to come up with your own cloud service name since cloud service names must be unique in Azure. Cloud services are important for more complex scenarios using [multiple virtual machines](http://www.windowsazure.com/en-us/documentation/articles/cloud-services-connect-virtual-machine/).
+ - The **Cloud Service DNS Name** is the global DNS name that becomes part of the URI that's used to contact the virtual machine. You'll need to come up with your own cloud service name because it must be unique in Azure. Cloud services are important for scenarios using [multiple virtual machines](http://www.windowsazure.com/en-us/documentation/articles/cloud-services-connect-virtual-machine/).
- For **Region/Affinity Group/Virtual Network**, use a region that is appropriate to your location. You can also choose to specify a virtual network instead.
@@ -34,12 +33,12 @@
![Configure the connected resources of the virtual machine](./media/virtual-machines-create-WindowsVM/resourceconfiguration.png)
-7. The fourth configuration screen lets you configure the VM Agent and some of the available extensions. For this tutorial, do not make any changes to this screen. Click the check mark to create the virtual machine.
+7. The fourth configuration screen lets you configure the VM Agent and some of the available extensions. Click the check mark to create the virtual machine.
![Configure VM Agent and extensions for the virtual machine](./media/virtual-machines-create-WindowsVM/agent-and-extensions.png)
- >[WACOM.NOTE] The VM agent provides the environment for you to install extensions that can help you interact with the virtual machine. For details, see [Using Extensions](http://go.microsoft.com/FWLink/p/?LinkID=390493).
+ >[WACOM.NOTE] The VM agent provides the environment for you to install extensions that can help you interact with or manage the virtual machine. For details, see [Using Extensions](http://go.microsoft.com/FWLink/p/?LinkID=390493).
8. After the virtual machine is created, the Management Portal lists the new virtual machine under **Virtual Machines**. The corresponding cloud service and storage account are also created under their respective sections. Both the virtual machine and cloud service are started automatically and the Management Portal shows their status as **Running**.
Please sign in to comment.
Something went wrong with that request. Please try again.