<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">blog.smarx.com - cloud development blog</title><subtitle type="text">blog.smarx.com - cloud development blog</subtitle><id>uuid:6303822a-9a7b-4d15-82e0-61e878fbe0ca;id=11112</id><updated>2010-03-11T11:55:25Z</updated><link rel="alternate" href="http://blog.smarx.com/"/><link rel="next" href="?continuation=1!8!c21hcng-/1!84!MjUyMTUwNDMwNjg2NDY4NDM4NyBuby1tb3JlLXdhaXRpbmctdXNlLXdpbmRvd3MtYXp1cmUtcmlnaHQtbm93"/><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/using-other-web-servers-on-windows-azure</id><title type="text">Using Other Web Servers on Windows Azure</title><published>2010-03-05T00:47:54Z</published><updated>2010-03-05T00:47:54Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/using-other-web-servers-on-windows-azure"/><link rel="edit" href="using-other-web-servers-on-windows-azure"/><content type="html">&lt;p&gt;&lt;a href="http://dunnry.com"&gt;Ryan Dunn&lt;/a&gt; and I recently recorded the third episode of our new Channel 9 show, &lt;a href="http://channel9.msdn.com/shows/Cloud+Cover"&gt;Cloud Cover&lt;/a&gt;, which should go live on Channel 9 tomorrow (Friday). In this week’s episode, I do a demo of a worker role with an input endpoint. That’s a fancy way to say I use a non-IIS web server in Windows Azure.&lt;/p&gt;  &lt;p&gt;The technique I demonstrate is exactly the same as what’s used by our &lt;a href="http://code.msdn.microsoft.com/winazuretomcat"&gt;Tomcat Solution Accelerator&lt;/a&gt;, but it’s also been used to run Apache, Mongrel, and other web servers. In this post, I’ll show how to run &lt;a href="http://code.google.com/p/mongoose"&gt;Mongoose&lt;/a&gt;, a tiny web server, in the cloud.&lt;/p&gt;  &lt;h2&gt;Background: Endpoints in Windows Azure&lt;/h2&gt;  &lt;p&gt;In Windows Azure, all inbound communication happens via endpoints declared in &lt;code&gt;ServiceDefinition.csdef&lt;/code&gt;. There are two types of endpoints: input and internal. Input endpoints are those that are exposed to the internet, and internal endpoints are used for communication inside your application.&lt;/p&gt;  &lt;p&gt;Most of the time, you’ll use input endpoints with Windows Azure web roles, where IIS handles incoming requests and routes them to your web application. To use a web server other than IIS (or another kind of server, like SMTP or FTP), you’ll need to instead use a worker role.&lt;/p&gt;  &lt;h2&gt;Worker Roles with Input Endpoints&lt;/h2&gt;  &lt;p&gt;To use an input endpoint with a worker role, you need to do two things:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Define the input endpoint in your service definition. &lt;/li&gt;    &lt;li&gt;Listen for inbound traffic on the correct port. &lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Defining Your Input Endpoint&lt;/h3&gt;  &lt;p&gt;Defining an input endpoint is easy. If you’re using Visual Studio, you can simply double-click on your worker role and add a new input, like you see below.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="adding an endpoint - screenshot" border="0" alt="adding an endpoint - screenshot" src="http://smarxblog.blob.core.windows.net/images/image%5B27%5D" width="504" height="148" /&gt; &lt;/p&gt;  &lt;p&gt;Notice that I’ve chosen TCP as the protocol, not HTTP. If I were to choose HTTP, traffic would come through &lt;code&gt;http.sys&lt;/code&gt;, which I don’t want. TCP gives me the same kind of access as if I launched the web server locally and started listening on the port directly. I’m choosing port 80, because that’s the standard HTTP port.&lt;/p&gt;  &lt;p&gt;Under the covers, this is the same as adding the following bit of XML to &lt;code&gt;ServiceDefinition.csdef&lt;/code&gt;:&lt;/p&gt;  &lt;pre class="code"&gt;    &lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Endpoints&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
      &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;InputEndpoint &lt;/span&gt;&lt;span style="color: red"&gt;name&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;WorkerIn&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;protocol&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;tcp&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;port&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;80&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;/&amp;gt;
    &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Endpoints&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;
&lt;/span&gt;&lt;/pre&gt;

&lt;h3&gt;Listening for Traffic on the Right Port&lt;/h3&gt;

&lt;p&gt;When you specify a port in your endpoint definition, that’s the port that Windows Azure will expose to the internet via the load balancer. Traffic that comes through the load balancer is then routed to your application on a &lt;em&gt;different&lt;/em&gt; port, which is chosen at runtime by Windows Azure.&lt;/p&gt;

&lt;p&gt;That means you’ll need to call the Windows Azure runtime API to determine which port your application should listen on. The following line of code queries the API for our endpoint and determines the correct port:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;int &lt;/span&gt;port = &lt;span style="color: #2b91af"&gt;RoleEnvironment&lt;/span&gt;.CurrentRoleInstance.InstanceEndpoints[&lt;span style="color: #a31515"&gt;&amp;quot;WorkerIn&amp;quot;&lt;/span&gt;].IPEndpoint.Port;&lt;/pre&gt;

&lt;h2&gt;Launching a Web Server&lt;/h2&gt;

&lt;p&gt;At this point, we have an endpoint, and we know what port we need to listen on. From our code, we could now start listening for traffic via &lt;code&gt;WCF&lt;/code&gt;, &lt;code&gt;TCPListener&lt;/code&gt;, or anything else.&lt;/p&gt;

&lt;p&gt;In our case, however, we want to run an external process (our web server) to handle the traffic. The following is the full code for our worker role’s &lt;code&gt;Run()&lt;/code&gt; method, which launches a lightweight web server called &lt;a href="http://code.google.com/p/mongoose/"&gt;Mongoose&lt;/a&gt;.&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;public override void &lt;/span&gt;Run()
{
    &lt;span style="color: blue"&gt;string &lt;/span&gt;mongooseroot = &lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;.Combine(&lt;span style="color: #2b91af"&gt;Environment&lt;/span&gt;.GetEnvironmentVariable(&lt;span style="color: #a31515"&gt;&amp;quot;RoleRoot&amp;quot;&lt;/span&gt;) + &lt;span style="color: #a31515"&gt;@&amp;quot;\&amp;quot;&lt;/span&gt;, &lt;span style="color: #a31515"&gt;@&amp;quot;approot\mongoose&amp;quot;&lt;/span&gt;);
    &lt;span style="color: blue"&gt;int &lt;/span&gt;port = &lt;span style="color: #2b91af"&gt;RoleEnvironment&lt;/span&gt;.CurrentRoleInstance.InstanceEndpoints[&lt;span style="color: #a31515"&gt;&amp;quot;WorkerIn&amp;quot;&lt;/span&gt;].IPEndpoint.Port;

    &lt;span style="color: #2b91af"&gt;Process &lt;/span&gt;p = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Process&lt;/span&gt;()
    {
        StartInfo = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;ProcessStartInfo&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;Path&lt;/span&gt;.Combine(mongooseroot, &lt;span style="color: #a31515"&gt;@&amp;quot;mongoose-2.8.exe&amp;quot;&lt;/span&gt;), &lt;span style="color: #a31515"&gt;&amp;quot;-ports &amp;quot; &lt;/span&gt;+ port)
        {
            UseShellExecute = &lt;span style="color: blue"&gt;false&lt;/span&gt;,
            WorkingDirectory = mongooseroot
        }
    };

    p.Start();
    p.WaitForExit();
    &lt;span style="color: blue"&gt;throw new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="color: #a31515"&gt;&amp;quot;Mongoose quit on me!&amp;quot;&lt;/span&gt;);
}&lt;/pre&gt;

&lt;p&gt;The first line is probably the most difficult to get right if you try to write this code yourself. This line is responsible for finding the correct path to our Mongoose binary (and web content). It uses the path &lt;code&gt;%RoleRoot%\approot&lt;/code&gt;. This is where the code for your role sits on the virtual machine in the cloud.&lt;/p&gt;

&lt;p&gt;There’s a bit of a gotcha here, which is that you really need to add the backslash to &lt;code&gt;%RoleRoot%&lt;/code&gt; before using &lt;code&gt;Path.Combine()&lt;/code&gt;. If you don’t do this, your code will run fine on your local development machine, but &lt;strong&gt;it will fail in the cloud&lt;/strong&gt;. This is because the local path to your role root is a directory, while in the cloud, it’s a drive. In the cloud, you’ll get a value like &lt;code&gt;E:&lt;/code&gt; (note there’s no trailing backslash). When you add &lt;code&gt;approot&lt;/code&gt; to that, you’ll end up with &lt;code&gt;E:approot&lt;/code&gt;, which is not correct. (It should be &lt;code&gt;E:\approot&lt;/code&gt;.) To be safe in both locations, make sure to explicitly add the trailing backslash.&lt;/p&gt;

&lt;p&gt;The second line is one we saw above. This captures the correct port in a local variable.&lt;/p&gt;

&lt;p&gt;Next we launch a new Mongoose process, passing the correct port on the command-line, setting the correct working directory (so Mongoose can find our web content).&lt;/p&gt;

&lt;p&gt;Finally, we wait forever for the Mongoose process to exit. Mongoose, like your &lt;code&gt;Run()&lt;/code&gt; method, should never exit unless there’s an error, so when Mongoose exits, we raise an exception and exit ourselves. This will indicate to Windows Azure that something has gone wrong, and our role will get restarted.&lt;/p&gt;

&lt;h2&gt;Packaging the Web Server with Your Role&lt;/h2&gt;

&lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="VS file properties - screenshot" border="0" alt="VS file properties - screenshot" align="right" src="http://smarxblog.blob.core.windows.net/images/image_thumb%5B27%5D" width="229" height="498" /&gt;The above code assumes that Mongoose is part of my deployed worker role. To make sure that Mongoose and my web content are actually packaged as part of the role during my build process, I need to set them in Visual Studio to always copy to the output directory when built. See &lt;a href="http://blogs.msdn.com/jnak"&gt;Jim Nakashima&lt;/a&gt;’s blog post “&lt;a href="http://blogs.msdn.com/jnak/archive/2009/01/28/adding-files-to-your-windows-azure-service-package.aspx"&gt;Adding Files to your Windows Azure Service Package&lt;/a&gt;” for a full explanation.&lt;/p&gt;

&lt;h2&gt;Try It Out&lt;/h2&gt;

&lt;p&gt;I’ve &lt;a href="http://smarxlog.blob.core.windows.net/files/WorkerInputDemo_source.zip"&gt;zipped up everything (except the Mongoose binary)&lt;/a&gt; so you can try this sample yourself. To get the application working, just &lt;a href="http://code.google.com/p/mongoose/downloads/list"&gt;download Mongoose&lt;/a&gt; and place it in the Mongoose folder under the worker role.&lt;/p&gt;

&lt;p&gt;Note that because you don’t have an HTTP input endpoint, Visual Studio doesn’t know to launch the web browser. To view the application once it’s running, open up the Development Fabric UI and check what port you’re on (should be port 80, or often 81 or 82 if you’re running other things). Then just browse to &lt;code&gt;localhost&lt;/code&gt; on that port in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://smarxblog.blob.core.windows.net/files/WorkerInputDemo_source.zip"&gt;Download the full VS2010 RC solution here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s also running in the cloud (for a week or so until I pull it down) at &lt;a href="http://workerinput.cloudapp.net"&gt;http://workerinput.cloudapp.net&lt;/a&gt;.&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/i-didn-t-blog-for-a-while-so-have-some-sorbet</id><title type="text">I Didn’t Blog for a While, so Have Some Sorbet</title><published>2010-03-04T00:19:28Z</published><updated>2010-03-04T00:19:28Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/i-didn-t-blog-for-a-while-so-have-some-sorbet"/><link rel="edit" href="i-didn-t-blog-for-a-while-so-have-some-sorbet"/><content type="html">&lt;p&gt;It’s been a while since my last post. When that happens, there’s a sort of momentum that keeps me from posting, because I feel like after a break from blogging, my next entry should be something monumentally interesting and exciting. This blog post is the opposite. Think of it as sorbet, served between courses as a palate cleanser.&lt;/p&gt;  &lt;p&gt;While I’m &lt;a href="http://en.wiktionary.org/wiki/metablog"&gt;metablogging&lt;/a&gt;, I should point out that I’ve removed all comments from my blog. There was just too much spam, and I wasn’t reading and responding to legitimate comments very often. Instead, if you have thoughts about what I’m blogging, &lt;a href="http://twitter.com/smarx"&gt;reply on Twitter&lt;/a&gt; (my blog automatically tweets every time I post something), discuss something on the &lt;a href="http://social.msdn.microsoft.com/forums/en-us/windowsazure/threads"&gt;Windows Azure forum&lt;/a&gt;, or send me email. (My address is on the side of my blog.)&lt;/p&gt;  &lt;p&gt;(By the way, I’m going to keep referring to this as a blog, even though according to &lt;a href="http://www.codinghorror.com/blog/"&gt;Jeff Atwood&lt;/a&gt;, “&lt;a href="http://www.codinghorror.com/blog/2006/04/a-blog-without-comments-is-not-a-blog.html"&gt;a blog without comments is not a blog&lt;/a&gt;.”)&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/using-the-new-windows-azure-cdn-with-a-custom-domain</id><title type="text">Using the New Windows Azure CDN with a Custom Domain</title><published>2009-11-06T00:09:02Z</published><updated>2009-11-06T00:09:02Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/using-the-new-windows-azure-cdn-with-a-custom-domain"/><link rel="edit" href="using-the-new-windows-azure-cdn-with-a-custom-domain"/><content type="html">&lt;p&gt;Today we announced a new service in Windows Azure: the Windows Azure Content Delivery Network (CDN).&amp;#160; You can read about the details over &lt;a href="http://blogs.msdn.com/windowsazure/archive/2009/11/05/introducing-the-windows-azure-content-delivery-network.aspx"&gt;on the Windows Azure blog&lt;/a&gt;.&amp;#160; In short, you can now tap into our global CDN to cache your content close to your users.&amp;#160; The Windows Azure CDN is a free preview for now, and we’ll announce pricing information in the future.&lt;/p&gt;  &lt;p&gt;As we all know, my blog is an international sensation, and I sometimes include images in my posts.&amp;#160; Now I have the opportunity to boost the performance of my blog by serving those images from the Windows Azure CDN.&amp;#160; In this post, I’ll show you how I enabled the CDN under a custom domain name for images on my blog.&lt;/p&gt;  &lt;h2&gt;Step 1: Enable the CDN&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://smarxblog.blob.core.windows.net/images/step%201%20-%20enabling%20cdn%5B7%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="step 1 - enabling cdn" border="0" alt="step 1 - enabling cdn" align="right" src="http://smarxblog.blob.core.windows.net/images/step%201%20-%20enabling%20cdn_thumb%5B5%5D" width="400" height="74" /&gt;&lt;/a&gt; As of today, there’s a new section in the &lt;a href="https://windows.azure.com"&gt;Windows Azure portal&lt;/a&gt; when you view one of your storage accounts.&amp;#160; Click the “Enable CDN” button to turn on the CDN.&amp;#160; Note that even though you get immediate confirmation that the CDN is enabled, it may take quite some time (expect 60 minutes) for the change to propagate throughout the network.&lt;/p&gt;  &lt;p&gt;Once you’ve completed this step, you should see something like the following, which tells you the URL at which your blobs are now available via the CDN.&amp;#160; Note that only blobs in a public container will be cached and served by the CDN&lt;a href="http://smarxblog.blob.core.windows.net/images/step%201b%20-%20cdn%20enabled%5B5%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="step 1b - cdn enabled" border="0" alt="step 1b - cdn enabled" src="http://smarxblog.blob.core.windows.net/images/step%201b%20-%20cdn%20enabled_thumb%5B3%5D" width="660" height="120" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;That’s all you have to do to get the CDN functionality, but as you’ll notice, the URL for the CDN is a bit ugly.&amp;#160; In the next step, we’ll get a cleaner URL by mapping a custom domain.&lt;/p&gt;  &lt;h2&gt;Step 2: Map a Custom Domain&lt;/h2&gt;  &lt;p&gt;Along with the Windows Azure CDN, today we’ve introduced functionality to map custom domains to either CDN URLs or storage accounts directly.&amp;#160; I don’t want the image URLs on my blog to have the domain &lt;code&gt;az2386.vo.msecnd.net&lt;/code&gt; in them, so let’s map the custom domain &lt;code&gt;cdn.blog.smarx.com&lt;/code&gt; and use that instead.&lt;/p&gt;  &lt;p&gt;Below the CDN section in the portal, you should see another new section called “Custom Domains.”&amp;#160; It shows your normal blob endpoint as well as your CDN endpoint.&lt;a href="http://smarxblog.blob.core.windows.net/images/step%202%20-%20domain%20mappings%5B5%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="step 2 - domain mappings" border="0" alt="step 2 - domain mappings" src="http://smarxblog.blob.core.windows.net/images/step%202%20-%20domain%20mappings_thumb%5B3%5D" width="660" height="125" /&gt;&lt;/a&gt; When you click the “Manage” button, you get to choose the domain you’re going to map (via a CNAME record) to the endpoint.&amp;#160; In my case, I chose &lt;code&gt;cdn.blog.smarx.com&lt;/code&gt;.&lt;a href="http://smarxblog.blob.core.windows.net/images/step%202b%20-%20choosing%20a%20subdomain%5B5%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="step 2b - choosing a subdomain" border="0" alt="step 2b - choosing a subdomain" src="http://smarxblog.blob.core.windows.net/images/step%202b%20-%20choosing%20a%20subdomain_thumb%5B3%5D" width="660" height="388" /&gt;&lt;/a&gt; Before the CDN will start serving requests from this custom domain, you need to prove that you actually own it.&amp;#160; When you click the “Generate Key,” you’ll get instructions for what to change in your DNS settings to validate your ownership of the domain.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://smarxblog.blob.core.windows.net/images/step%202c%20-%20validating%20domain%20ownership%5B5%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="step 2c - validating domain ownership" border="0" alt="step 2c - validating domain ownership" src="http://smarxblog.blob.core.windows.net/images/step%202c%20-%20validating%20domain%20ownership_thumb%5B3%5D" width="660" height="493" /&gt;&lt;/a&gt; Follow the instructions to prove ownership of the domain.&amp;#160; If you’ve never set up a CNAME record before, you might want to read my previous blog post about &lt;a href="http://blog.smarx.com/posts/custom-domain-names-in-windows-azure"&gt;using custom domains in Windows Azure&lt;/a&gt;, which includes a screenshot of what it looks like to do this with GoDaddy.&lt;/p&gt;  &lt;p&gt;After mapping the GUID subdomain to &lt;code&gt;domainnameverification.windows.azure.com&lt;/code&gt;, you can click the “Validate” button.&amp;#160; Assuming your CNAME record was properly set up, you should be taken back to the storage account page.&lt;/p&gt;  &lt;p&gt;Now you’ll see that your custom domain is mapped to the CDN.&lt;a href="http://smarxblog.blob.core.windows.net/images/step%202d%20-%20success%5B5%5D"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="step 2d - success" border="0" alt="step 2d - success" src="http://smarxblog.blob.core.windows.net/images/step%202d%20-%20success_thumb%5B3%5D" width="660" height="228" /&gt;&lt;/a&gt; To finish the process, go back to your registrar and set up the real CNAME record (in my case, &lt;code&gt;cdn.blog&lt;/code&gt; mapping to &lt;code&gt;az2386.vo.msecnd.net&lt;/code&gt;).&amp;#160; Now you should be able to use your custom domain name and the domain provided by the CDN interchangeably.&lt;/p&gt;  &lt;p&gt;You can follow the same mapping and validation steps to use a custom domain to point directly to your blob storage endpoint.&lt;/p&gt;  &lt;h2&gt;Success (and proof)!&lt;/h2&gt;  &lt;p&gt;I did all the above steps, and now the blobs I use for my blog are available under:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;http://smarxblog.blob.core.windows.net/ &lt;/li&gt;    &lt;li&gt;http://az2386.vo.msecnd.net/ &lt;/li&gt;    &lt;li&gt;http://cdn.blog.smarx.com/ &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;As proof, check out the properties of any of the screenshots in this post.&amp;#160; They’re being served from the CDN, and if you click them, you can browse directly to a higher-resolution version.&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/windows-azure-at-pdc-2009</id><title type="text">Windows Azure at PDC 2009</title><published>2009-10-29T19:13:59Z</published><updated>2009-10-29T19:13:59Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/windows-azure-at-pdc-2009"/><link rel="edit" href="windows-azure-at-pdc-2009"/><content type="html">&lt;p&gt;&lt;strong&gt;[UPDATE 11/24]: &lt;/strong&gt;PDC is over!&amp;#160; I’ve updated the below to include the sessions that were previously kept secret.&amp;#160; Now all of the links point to videos of the sessions.&amp;#160; Enjoy!&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;a href="http://microsoftpdc.com"&gt;PDC 2009&lt;/a&gt; is just around the corner, and Windows Azure has a lot of coverage throughout the event.&amp;#160; Over the past two weeks, I’ve been lucky enough to see previews of every session presented by a Windows Azure team member.&amp;#160; I can tell you there’s a lot of great content you won’t want to miss.&lt;/p&gt;  &lt;p&gt;If you want to view all the published sessions relating to Windows Azure, you can &lt;a href="http://microsoftpdc.com/Sessions?term=windows%20azure"&gt;search for “Windows Azure” on microsoftpdc.com&lt;/a&gt;.&amp;#160; Below, I’ve listed only the sessions about Windows Azure presented by Windows Azure team members (and my commentary on them).&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC13"&gt;&lt;strong&gt;Windows Azure Present and Future (Manuvir Das)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Even if you’ve already seen Manuvir present an overview of the platform (at PDC08 or at MIX09), you’ll want to hear from him again.&amp;#160; He’s going to give an overview of the new features and a peak at what’s coming next year.&amp;#160; If you see only one Windows Azure talk at PDC, this is the one to see. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC37"&gt;Introduction to Building Applications with Windows Azure (David Lemphers)&lt;/a&gt;&lt;/strong&gt;      &lt;br /&gt;If you want to understand the developer perspective on Windows Azure, you should attend David’s talk.&amp;#160; You’ll get to learn the high-level concepts you need as well as see hands-on demos, all from someone with a cool Australian accent. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC16"&gt;&lt;strong&gt;Developing Advanced Applications with Windows Azure (Steve Marx)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;This is my session.&amp;#160; I’ve graduated from being the king of “Hello, World!” and will show you some advanced techniques using the new features we’re announcing at PDC.&amp;#160; This will be one of those build-up-an-app-throughout-the-session talks. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC50"&gt;Building Java Applications with Windows Azure (Steve Marx)&lt;/a&gt;&lt;/strong&gt;      &lt;br /&gt;&lt;strike&gt;I have another session which hasn’t been published yet, because it would spoil a bit of the news at PDC.&amp;#160; This will also be a code-heavy session, but you’ll have to wait until PDC to find out exactly what it’s all about.&lt;/strike&gt;&amp;#160; I dusted off my Java and Eclipse skills and wrote some Java code to run in the cloud, including using the new Java storage client library.&lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC08"&gt;&lt;strong&gt;Patterns for Building Scalable and Reliable Applications with Windows Azure (Brad Calder)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Come prepared to think, because Brad’s taking on some of the more complex topics in building scalable apps.&amp;#160; The content in this session is deep, but really important if you’re serious about designing for scale on Windows Azure. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC14"&gt;Windows Azure Blob and Drive Deep Dive (Brad Calder)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;Brad is &lt;em&gt;the &lt;/em&gt;storage guy.&amp;#160; He runs the storage team and knows every detail of the design and implementation.&amp;#160; If for no other reason than that, you should be at his session if you care about storage.&amp;#160; In addition, Brad will be covering a few new features that I can’t tell you about yet… &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC09"&gt;&lt;strong&gt;Windows Azure Tables and Queues Deep Dive (Jai Haridas)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Jai, who works on the storage team, eases you into this topic by giving a good overview of the features, but things get really interesting when he starts talking about common pitfalls and tips for getting the most out of the storage service. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC15"&gt;&lt;strong&gt;Windows Azure Monitoring, Logging, and Management APIs (Matthew Kerner)&lt;/strong&gt;&lt;/a&gt;       &lt;br /&gt;Matt works on the Fabric team, and he’s going to show you the new diagnostic APIs and what they can do.&amp;#160; Want to have a live view of what your servers are doing?&amp;#160; Matt will show you how to do it. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC25"&gt;&lt;strong&gt;Automating the Application Lifecycle with Windows Azure (Sriram Krishnan&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;)&lt;/strong&gt;&amp;#160; &lt;br /&gt;Sriram will cover the new Service Management API and upgrade options, including how you can automate things like deploying new bits to the cloud. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC51"&gt;Developing PHP and MySQL Applications with Windows Azure (Tushar Shanbhag and Mohit Srivastava)&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;strike&gt;This is another session that hasn’t been published yet.&amp;#160; It’s a talk that may surprise you, but you’ll have to wait until PDC to find out what it is.&lt;/strike&gt;&amp;#160; Tushar and Mohit showed cool things like running MediaWiki using PHP, MySQL, and memcached in Windows Azure!&amp;#160; A must-see for people interested in these technologies.&lt;/li&gt;    &lt;li&gt;&lt;strong&gt;&lt;a href="http://microsoftpdc.com/Sessions/SVC54"&gt;The Business of Windows Azure: What You Should Know About Windows Azure Platform Pricing and SLAs (Dianne O’Brien)&lt;/a&gt;&lt;/strong&gt;      &lt;br /&gt;If you’re interested in the business side of the platform, or if you’re a developer who wants to understand how pricing should influence your application design, this talk is for you.&amp;#160; Unlike the talks above, this talk is about the full Windows Azure platform (including SQL Azure and .NET Services too). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;There’s no real substitute for being at PDC in person, but if you’re unable to make it, all the sessions should be posted online a day or two after they’re presented.&lt;/p&gt;  &lt;p&gt;If you &lt;em&gt;are&lt;/em&gt; attending PDC, be sure to stop by and say hello.&amp;#160; Lots of Windows Azure team members will be around and are eager to talk to you, so don’t be shy!&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/windows-azure-tables-expect-continuation-tokens-seriously</id><title type="text">Windows Azure Tables: Expect Continuation Tokens, Seriously!</title><published>2009-10-28T16:37:11Z</published><updated>2009-10-28T16:37:11Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/windows-azure-tables-expect-continuation-tokens-seriously"/><link rel="edit" href="windows-azure-tables-expect-continuation-tokens-seriously"/><content type="html">&lt;p&gt;A few weeks ago, my blog appeared suddenly empty.&amp;#160; More recently, a customer reported that all of his data had seemingly disappeared.&amp;#160; In his case and in mine, we were forgetting an important part of using Windows Azure Tables: &lt;a href="http://msdn.microsoft.com/en-us/library/dd135718.aspx"&gt;continuation tokens&lt;/a&gt;.&amp;#160; Read on to understand why continuation tokens are so important to handle properly in your application.&lt;/p&gt;  &lt;h2&gt;What are continuation tokens?&lt;/h2&gt;  &lt;p&gt;I’ve talked before about continuation tokens in Windows Azure Tables, in the context of &lt;a href="http://blog.smarx.com/posts/paging-over-data-in-windows-azure-tables"&gt;paging over data&lt;/a&gt;.&amp;#160; Basically, continuation tokens are the way you can pick up a query where it left off.&amp;#160; In the paging example, you’re explicitly querying for a subset of the results (using the &lt;code&gt;$top&lt;/code&gt; parameter in the REST API, or &lt;code&gt;.Take(n)&lt;/code&gt; syntax in LINQ).&amp;#160; The storage service returns those results, along with a continuation token.&amp;#160; When you’re ready for the next page, you query again, passing in the continuation token you received from the first query.&amp;#160; This gives you the next set of results and the next continuation token.&lt;/p&gt;  &lt;p&gt;Another common place you’ll see continuation tokens is when the results of a query exceed 1000 entities.&amp;#160; Windows Azure Tables returns up to a maximum of 1000 entities in a single request and returns a continuation token when more results are available.&lt;/p&gt;  &lt;p&gt;The final place most people expect to see a continuation token is when the request to the server timed out.&amp;#160; In practice, I have yet to see a query exceed the 30-second timeout, but it could, particularly in the case of a scan (non-indexed query) over a large set of entities.&lt;/p&gt;  &lt;h2&gt;What if you’re not doing those things?&lt;/h2&gt;  &lt;p&gt;Well, you &lt;em&gt;still need to be ready for continuation tokens&lt;/em&gt;.&amp;#160; When my blog appeared empty, I was querying for the top five posts (or in some queries, &lt;em&gt;one&lt;/em&gt; post), and I was receiving no results at all.&amp;#160; And no, the query wasn’t timing out.&lt;/p&gt;  &lt;p&gt;The answer for what happened, and why you &lt;strong&gt;really do need to handle continuation tokens in your code&lt;/strong&gt; is a bit subtle in the &lt;a href="http://msdn.microsoft.com/en-us/library/dd135718.aspx"&gt;Query Timeout and Pagination MSDN documentation&lt;/a&gt; (emphasis added):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A query against the Table service may return a maximum of 1,000 items (tables or entities) for a single request. If there are additional items to be returned, the response to the query request includes custom headers containing a set of continuation tokens. The continuation token headers may be sent to the server with a subsequent request to resume the execution of the query.&lt;/p&gt;    &lt;p&gt;The Table service times out when a query operation does not complete within 60 seconds. If the query has returned results up to that point, these results are returned in the response. Continuation tokens are also returned in this case, so that the client may make another request for the remainder of the data.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;Continuation tokens may also be returned when a query crosses the partition boundary.&lt;/strong&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That last line is incredibly important, because whether or not a query crosses a partition boundary is not always in your control.&lt;/p&gt;  &lt;p&gt;(Note that the documentation quoted above is referring to an older version of storage… the query timeout is 30 seconds now.)&lt;/p&gt;  &lt;h2&gt;What’s a partition boundary?&lt;/h2&gt;  &lt;p&gt;A partition boundary is what it sounds like… it’s the logical barrier between two partitions in the storage service.&amp;#160; In Windows Azure Tables, it’s all about partitions.&amp;#160; Each of your tables is divided into partitions according to the partition key you chose.&amp;#160; Physically, in the data center, each partition might be on a separate server, or they may be on the same server (if they’re small or infrequently accessed).&amp;#160; Partitions are the way that tables scale, and they’re also the way the system responds to heavy load (by isolating “hot” partitions on dedicated servers).&lt;/p&gt;  &lt;p&gt;When you perform a query that doesn’t specify a partition key, this is a cross-partition query.&amp;#160; If all the partitions happen to be on the same server, you might get all the results at once.&amp;#160; If the partitions are physically separated in the data center, you’ll get partial results and a continuation token.&lt;/p&gt;  &lt;h2&gt;What happened on my blog?&lt;/h2&gt;  &lt;p&gt;In the case of my broken blog query, I was querying for the top five posts without specifying a partition key.&amp;#160; The entries table for my blog only has one partition, so this might seem reasonable.&lt;/p&gt;  &lt;p&gt;Without a partition key, though, my query could land on a server that didn’t have the right data.&amp;#160; This hadn’t happened for the entire lifetime of my blog, but a few weeks ago, things moved around in the storage service (which happens all the time as we balance for load or change hardware).&amp;#160; Now my query without a specified partition was initially landing on a server that didn’t actually have my data!&amp;#160; All that server could do was return an empty set of results and a continuation token that made sure my next query would land in my first (and only) partition.&lt;/p&gt;  &lt;p&gt;This “empty” server was there to handle additional partitions, if I chose to create them.&amp;#160; This can happen if there used to be more partitions but they’ve been deleted, or if the storage service has allocated future placement there as part of automatic load balancing.&amp;#160; In the future, we may be able to optimize this path to avoid the initial empty round trip.&lt;/p&gt;  &lt;p&gt;Because I wasn’t properly dealing with continuation tokens in my code, my blog happily showed an empty page, thinking there were no blog posts at all.&lt;/p&gt;  &lt;h2&gt;What can be done?&lt;/h2&gt;  &lt;p&gt;There are a few things you should do to deal with continuation tokens in your code:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;If you know it, always specify a partition key in your queries.&amp;#160; This is the primary way I fixed my blog code. &lt;/li&gt;    &lt;li&gt;Even if you do (1), your code should properly respond to a response that includes a continuation token. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The simplest way by far to do (2) is to make use of the &lt;code&gt;ExecuteAll(...)&lt;/code&gt; and &lt;code&gt;ExecuteAllWithRetries(...)&lt;/code&gt; on the &lt;code&gt;TableStorageDataServiceQuery&amp;lt;T&amp;gt;&lt;/code&gt; class in the sample storage client library in the SDK.&amp;#160; These methods automatically repeat the query as needed, following the chain of continuation tokens until all results have been retrieved.&amp;#160; From the code comments:&lt;/p&gt;  &lt;pre&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Returns all results of the query and hides the complexity of continuation if 
/// this is desired by a user. Users should be aware that this operation can return 
/// many objects. Uses no retries.
/// Important: this function does not call Execute immediately. Instead, it calls Execute() on 
/// the query only when the result is enumerated. This is a difference to the normal 
/// Execute() and Execute() with retry method.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;An IEnumerable representing the results of the query.&amp;lt;/returns&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;The bottom line&lt;/h2&gt;

&lt;p&gt;The bottom line is that &lt;em&gt;any&lt;/em&gt; query that doesn’t specify &lt;em&gt;both &lt;/em&gt;a partition key and a row key can return a continuation token.&amp;#160; [UPDATE 10/28: More precisely, to avoid continuation tokens, a query must address a single entity completely.]&amp;#160; Fortunately, it’s not hard to deal with this in your code.&amp;#160; You just need to understand it and &lt;em&gt;remember to do it&lt;/em&gt;, even if your code is running fine today.&lt;/p&gt;

&lt;p&gt;If you want to understand continuation tokens better, I’d recommend reading the &lt;a href="http://msdn.microsoft.com/en-us/library/dd135718.aspx"&gt;Query Timeout and Pagination MSDN documentation&lt;/a&gt; as well as my earlier blog post about &lt;a href="http://blog.smarx.com/posts/paging-over-data-in-windows-azure-tables"&gt;Paging Over Data in Windows Azure Tables&lt;/a&gt;.&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/manage-your-windows-azure-application-from-powershell</id><title type="text">Manage Your Windows Azure Application From PowerShell</title><published>2009-10-27T05:11:15Z</published><updated>2009-10-27T05:11:15Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/manage-your-windows-azure-application-from-powershell"/><link rel="edit" href="manage-your-windows-azure-application-from-powershell"/><content type="html">&lt;p&gt;Are you reading &lt;a href="http://dunnry.com"&gt;Ryan Dunn’s blog&lt;/a&gt;?&amp;#160; If not, go subscribe to his &lt;a href="http://dunnry.com/blog/syndicationservice.asmx/GetRss"&gt;RSS feed&lt;/a&gt; now.&amp;#160; Ryan’s the Technical Evangelist for Windows Azure.&amp;#160; Among other things, he’s constantly releasing useful tools for Windows Azure developers.&amp;#160; Last week it was &lt;a href="http://myazurestorage.com"&gt;myazurestorage.com&lt;/a&gt;, &lt;a href="http://dunnry.com/blog/LaunchingMyAzureStoragecom.aspx"&gt;a tool for viewing your tables in the browser&lt;/a&gt;.&amp;#160; This week, it’s &lt;a href="http://dunnry.com/blog/WindowsAzureServiceManagementCmdLets.aspx"&gt;PowerShell cmdlets for managing your Windows Azure applications&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="cmdlets screenshot" border="0" alt="cmdlets screenshot" align="right" src="http://code.msdn.microsoft.com/Project/Download/FileDownload.aspx?ProjectName=azurecmdlets&amp;amp;DownloadId=7916" width="320" height="159" /&gt;&lt;/p&gt;  &lt;p&gt;I haven’t gotten to play with them yet, but I’m eager to.&amp;#160; From Ryan’s post:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;As of today, you can &lt;a href="http://dunnry.com/blog/ct.ashx?id=a4c8084f-de9b-4074-b2e9-5137453466f1&amp;amp;url=http%3a%2f%2fcode.msdn.microsoft.com%2fazurecmdlets"&gt;download some Powershell cmdlets&lt;/a&gt; that wrap this API and make managing your Windows Azure applications simple from script.&amp;#160; With these cmdlets, you can script your deploys, upgrades, and scaling operations very easily.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;You can download the cmdlets from &lt;a href="http://code.msdn.microsoft.com/azurecmdlets"&gt;MSDN Code Gallery page&lt;/a&gt;.&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/what-makes-a-great-developer-website-help-me-improve-http-dev-windowsazure-com</id><title type="text">What Makes a Great Developer Website? Help Me Improve http://dev.windowsazure.com!</title><published>2009-10-22T18:35:55Z</published><updated>2009-10-22T18:35:55Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/what-makes-a-great-developer-website-help-me-improve-http-dev-windowsazure-com"/><link rel="edit" href="what-makes-a-great-developer-website-help-me-improve-http-dev-windowsazure-com"/><content type="html">&lt;p&gt;&lt;a href="http://dev.windowsazure.com"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="dev.windowsazure.com screenshot" border="0" alt="dev.windowsazure.com screenshot" align="right" src="http://smarxblog.blob.core.windows.net/images/dev.windowsazure.com%20screenshot%5B5%5D?timeout=30" width="292" height="278" /&gt;&lt;/a&gt; Did you see the new &lt;a href="http://windowsazure.com"&gt;http://windowsazure.com&lt;/a&gt;?&amp;#160; I think the site has a much cleaner look and makes it easier to find what you’re looking for.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://dev.windowsazure.com"&gt;http://dev.windowsazure.com&lt;/a&gt; takes you directly to the Windows Azure developer site, which is &lt;em&gt;the&lt;/em&gt; place developers go for information about Windows Azure.&lt;/p&gt;  &lt;p&gt;My responsibility is to play curator for that site.&amp;#160; I’m going to try to find the best content available and organize it in a way that developers can find the information they need as quickly and easily as possible.&amp;#160; I’d like your help doing that.&lt;/p&gt;  &lt;h2&gt;Three questions every product website should answer&lt;/h2&gt;  &lt;p&gt;When I’m investigating a new development technology, these are the questions I immediately ask (and the time I’m willing to spend answering each):&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;What is this? (30 seconds) &lt;/li&gt;    &lt;li&gt;Is it useful to me? (5 minutes) &lt;/li&gt;    &lt;li&gt;How can I get started? (15 minutes) &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;I’d like &lt;a href="http://dev.windowsazure.com"&gt;http://dev.windowsazure.com&lt;/a&gt; to deliver great answers to these questions for a &lt;em&gt;developer audience &lt;/em&gt;and then provide organized, deeper content for people who decide to invest their time learning the platform.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;I need your help!&lt;/h2&gt;  &lt;p&gt;I’ve set up a &lt;a href="http://123.writeboard.com/4b893890aa0ca3a65"&gt;Writeboard page&lt;/a&gt; (basically a one-page wiki) with the password “&lt;strong&gt;azure&lt;/strong&gt;” where you can contribute to this effort by helping me collect the right content and organize it.&amp;#160; There’s also a section on the page for you to tell me about the best developer websites you’ve seen and why you like them.&lt;/p&gt;  &lt;p&gt;Here’s a screenshot of the page at the time of this writing:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://123.writeboard.com/4b893890aa0ca3a65"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="writeboard screenshot" border="0" alt="writeboard screenshot" src="http://smarxblog.blob.core.windows.net/images/writeboard%20screenshot%5B5%5D?timeout=30" width="676" height="427" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;h2&gt;To contribute&lt;/h2&gt;  &lt;p&gt;Browse to &lt;a href="http://123.writeboard.com/4b893890aa0ca3a65"&gt;http://123.writeboard.com/4b893890aa0ca3a65&lt;/a&gt; and enter the password “&lt;strong&gt;azure&lt;/strong&gt;”.&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/transcript-from-today-s-windows-azure-lounge-chat</id><title type="text">Transcript from Today’s Windows Azure Lounge Chat</title><published>2009-09-05T00:44:57Z</published><updated>2009-09-05T00:44:57Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/transcript-from-today-s-windows-azure-lounge-chat"/><link rel="edit" href="transcript-from-today-s-windows-azure-lounge-chat"/><content type="html">&lt;p&gt;&lt;a href="http://smarxblog.blob.core.windows.net/images/image%5b19%5d?timeout=30"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="WAZL chat word cloud" border="0" alt="WAZL chat word cloud" align="right" src="http://smarxblog.blob.core.windows.net/images/image%5b16%5d?timeout=30" width="364" height="240" /&gt;&lt;/a&gt; This afternoon I spent three hours hanging out in the &lt;a href="http://wazl.cloudapp.net"&gt;Windows Azure Lounge&lt;/a&gt;.&amp;#160; With a longer period of time to chat and less hype, we had a more relaxed and social chat than &lt;a href="http://blog.smarx.com/posts/summary-and-transcript-first-windows-azure-lounge-chat"&gt;the first time&lt;/a&gt;.&amp;#160; I like that, and that’s part of the reason I want to do these more regularly.&lt;/p&gt;  &lt;p&gt;(Interesting stat: this chat had 530 messages over three hours.&amp;#160; &lt;a href="http://blog.smarx.com/posts/summary-and-transcript-first-windows-azure-lounge-chat"&gt;The first chat&lt;/a&gt; had 572 messages in just &lt;em&gt;one&lt;/em&gt; hour!)&lt;/p&gt;  &lt;p&gt;As came up again in this chat, time zones are a pain, so I vow to do one of these at night (for me) so the rest of the world has a chance to hang out during normal waking hours.&lt;/p&gt;  &lt;p&gt;For those who missed out on the fun (or were there and want to relive it!), the transcript is available:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://smarxblog.blob.core.windows.net/files/WAZL Transcript 2009-09-04.txt"&gt;as text&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://smarxblog.blob.core.windows.net/files/WAZL Transcript 2009-09-04.html"&gt;as html&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The word cloud on the right is courtesy of &lt;a href="http://wordle.net"&gt;wordle.net&lt;/a&gt; and accurately reflects the meandering nature of the conversation. :)&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/chat-about-windows-azure-tomorrow</id><title type="text">Chat About Windows Azure Tomorrow</title><published>2009-09-03T19:55:04Z</published><updated>2009-09-03T19:55:04Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/chat-about-windows-azure-tomorrow"/><link rel="edit" href="chat-about-windows-azure-tomorrow"/><content type="html">&lt;p&gt;Remember the &lt;a href="http://wazl.cloudapp.net"&gt;Windows Azure Lounge&lt;/a&gt;?&amp;#160; I’ll be hanging out there (maybe with a few coworkers) tomorrow, September 4th, from 12:00 PM to 3:00 PM PDT.&amp;#160; Feel free to stop by and chat about whatever’s on your mind.&amp;#160; Unlike &lt;a href="http://blog.smarx.com/posts/summary-and-transcript-first-windows-azure-lounge-chat"&gt;the first chat&lt;/a&gt;, this one will be a little less structured.&amp;#160; Just &lt;a href="http://wazl.cloudapp.net"&gt;show up and hang out&lt;/a&gt;, any time noon to three.&lt;/p&gt;  &lt;p&gt;I look forward to chatting with you tomorrow!&lt;/p&gt;  </content></entry><entry><id>http://blog.smarx.com/atompub.svc/blog/posts/simple-example-of-twilio-and-windows-azure</id><title type="text">Simple Example of Twilio and Windows Azure</title><published>2009-09-02T19:04:22Z</published><updated>2009-09-02T19:04:22Z</updated><author><name>Steve Marx</name><uri>http://smarx.com</uri><email>steve.marx@microsoft.com</email></author><link rel="alternate" href="http://blog.smarx.com/posts/simple-example-of-twilio-and-windows-azure"/><link rel="edit" href="simple-example-of-twilio-and-windows-azure"/><content type="html">&lt;p&gt;As you may have already seen, &lt;a href="http://blog.twilio.com/2009/08/announcing-this-weeks-netbook-contest-category-windows-azure-platform.html"&gt;Twilio chose Windows Azure as this week’s category&lt;/a&gt; for their &lt;a href="http://twilio.com/contest/netbook"&gt;developer contest&lt;/a&gt;.&amp;#160; (&lt;strong&gt;UPDATE&lt;/strong&gt;: Now &lt;a href="http://blog.twilio.com/2009/09/back-to-school-back-to-coding-with-windows-azure-extended-contest-category.html"&gt;more like two weeks&lt;/a&gt;!)&amp;#160; In addition to Twilio’s normal prize of a netbook, we’ve kicked in a couple additional prizes for this week: a copy of Windows 7 and $500 of free Windows Azure use after our commercial launch in November.&lt;/p&gt;  &lt;p&gt;To help give everyone a head start on getting their contest entry ready, I thought I’d put together a simple example of using Twilio from a Windows Azure application.&amp;#160; While not quite as cool as my &lt;a href="http://blog.smarx.com/posts/actually-i-m-a-cia-agent"&gt;earlier experiment with Twilio&lt;/a&gt; (&lt;a href="http://www.theciapickup.com"&gt;The CIA Pickup&lt;/a&gt;), this example should serve as a basic, how-to-make-it-work sample.&lt;/p&gt;  &lt;h2&gt;The Application&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://wazsong.cloudapp.net"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="wazsong screenshot" border="0" alt="wazsong screenshot" align="right" src="http://smarxblog.blob.core.windows.net/images/image_thumb6?timeout=30" width="388" height="184" /&gt;&lt;/a&gt;Early in the days of the Windows Azure CTP, &lt;a href="http://www.zimmergren.net/"&gt;Tobias Zimmergren&lt;/a&gt; recorded a song called “&lt;a href="http://www.zimmergren.net/archive/2008/11/28/i-can-windows-azure-you-%E2%80%93-song.aspx"&gt;I Can (Windows) Azure You&lt;/a&gt;.”&amp;#160; It’s kind of catchy.&lt;/p&gt;  &lt;p&gt;My sample Twilio + Windows Azure application calls you at a phone number you specify and plays the song to you over the phone.&amp;#160; Play with it at &lt;a href="http://wazsong.cloudapp.net"&gt;http://wazsong.cloudapp.net&lt;/a&gt; and &lt;a href="http://smarxblog.blob.core.windows.net/files/WindowsAzureSong_source.zip"&gt;download the full source&lt;/a&gt;.&lt;/p&gt;  &lt;h2&gt;What You’ll Need&lt;/h2&gt;  &lt;ol&gt;   &lt;li&gt;A Windows Azure account (&lt;a href="http://go.microsoft.com/fwlink/?LinkID=129453"&gt;Register for your invitation code&lt;/a&gt;, and get it instantly!) &lt;/li&gt;    &lt;li&gt;A &lt;strike&gt;paid&lt;/strike&gt; Twilio account with one Outgoing CallerID Number (This sample makes outbound phone calls, &lt;strike&gt;which &lt;/strike&gt;&lt;a href="https://www.twilio.com/try-twilio"&gt;&lt;strike&gt;free trial accounts&lt;/strike&gt;&lt;/a&gt;&lt;strike&gt; can’t do&lt;/strike&gt;.) &lt;strong&gt;UPDATE &lt;/strong&gt;[9/2/2009 @ 5:15PM]: I got this wrong initially.&amp;#160; Trial accounts &lt;em&gt;can &lt;/em&gt;do this as long as you put in a valid Caller ID Number of your own.&amp;#160; See Dennis’s comment below. &lt;/li&gt;    &lt;li&gt;The &lt;a href="http://go.microsoft.com/fwlink/?LinkId=128752"&gt;Windows Azure SDK and tools&lt;/a&gt; (These require Windows Server 2008, Vista, or Windows 7.) &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;The Code&lt;/h2&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;There’s exactly one page to this application.&amp;#160; The markup isn’t terribly interesting; it’s basically just a text box and a submit button.&amp;#160; The code-behind handles making the call to Twilio (using Twilio’s C# &lt;a href="http://www.twilio.com/docs/libraries/"&gt;helper library&lt;/a&gt;).&amp;#160; Here’s the full code-behind (&lt;code&gt;default.aspx.cs&lt;/code&gt;):&lt;/p&gt;  &lt;pre class="code"&gt;&lt;span style="color: blue"&gt;using &lt;/span&gt;System;
&lt;span style="color: blue"&gt;using &lt;/span&gt;System.Collections;
&lt;span style="color: blue"&gt;using &lt;/span&gt;Microsoft.ServiceHosting.ServiceRuntime;
&lt;span style="color: blue"&gt;using &lt;/span&gt;TwilioRest;

&lt;span style="color: blue"&gt;namespace &lt;/span&gt;WindowsAzureSong_WebRole
{
    &lt;span style="color: blue"&gt;public partial class &lt;/span&gt;&lt;span style="color: #2b91af"&gt;_Default &lt;/span&gt;: System.Web.UI.&lt;span style="color: #2b91af"&gt;Page
    &lt;/span&gt;{
        &lt;span style="color: blue"&gt;protected void &lt;/span&gt;singButton_Click(&lt;span style="color: blue"&gt;object &lt;/span&gt;sender, &lt;span style="color: #2b91af"&gt;EventArgs &lt;/span&gt;e)
        {
            &lt;span style="color: blue"&gt;var &lt;/span&gt;id = &lt;span style="color: #2b91af"&gt;RoleManager&lt;/span&gt;.GetConfigurationSetting(&lt;span style="color: #a31515"&gt;&amp;quot;TwilioID&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;var &lt;/span&gt;token = &lt;span style="color: #2b91af"&gt;RoleManager&lt;/span&gt;.GetConfigurationSetting(&lt;span style="color: #a31515"&gt;&amp;quot;TwilioToken&amp;quot;&lt;/span&gt;);
            &lt;span style="color: blue"&gt;var &lt;/span&gt;account = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Account&lt;/span&gt;(id, token);
            &lt;span style="color: blue"&gt;var &lt;/span&gt;vars = &lt;span style="color: blue"&gt;new &lt;/span&gt;&lt;span style="color: #2b91af"&gt;Hashtable&lt;/span&gt;();
            vars[&lt;span style="color: #a31515"&gt;&amp;quot;Caller&amp;quot;&lt;/span&gt;] = &lt;span style="color: #2b91af"&gt;RoleManager&lt;/span&gt;.GetConfigurationSetting(&lt;span style="color: #a31515"&gt;&amp;quot;OutboundNumber&amp;quot;&lt;/span&gt;);
            vars[&lt;span style="color: #a31515"&gt;&amp;quot;Called&amp;quot;&lt;/span&gt;] = phoneNumber.Text;
            vars[&lt;span style="color: #a31515"&gt;&amp;quot;Url&amp;quot;&lt;/span&gt;] = &lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;http://{0}{1}&amp;quot;&lt;/span&gt;, Request.Url.Host, ResolveUrl(&lt;span style="color: #a31515"&gt;&amp;quot;~/callscript.xml&amp;quot;&lt;/span&gt;));
            vars[&lt;span style="color: #a31515"&gt;&amp;quot;Method&amp;quot;&lt;/span&gt;] = &lt;span style="color: #a31515"&gt;&amp;quot;GET&amp;quot;&lt;/span&gt;;
            account.request(&lt;span style="color: blue"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #a31515"&gt;&amp;quot;2008-08-01/Accounts/{0}/Calls&amp;quot;&lt;/span&gt;, id), &lt;span style="color: #a31515"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;, vars);
            submittedLabel.Visible = &lt;span style="color: blue"&gt;true&lt;/span&gt;;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;As you can see, it generates a reference to &lt;code&gt;callscript.xml&lt;/code&gt;, which just looks like this:&lt;/p&gt;

&lt;pre class="code"&gt;&lt;span style="color: blue"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #a31515"&gt;xml &lt;/span&gt;&lt;span style="color: red"&gt;version&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;1.0&lt;/span&gt;&amp;quot; &lt;span style="color: red"&gt;encoding&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;&amp;quot;&lt;span style="color: blue"&gt;UTF-8&lt;/span&gt;&amp;quot; &lt;span style="color: blue"&gt;?&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Response&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
  &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Play&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;http://smarxblog.blob.core.windows.net/files/WindowsAzureYou.mp3&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Play&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;
&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Response&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;That URL is where I’ve stored the song (in a public container in Windows Azure blob storage), but you could put it anywhere (including in your app).&lt;/p&gt;

&lt;h2&gt;Links&lt;/h2&gt;

&lt;p&gt;Play with the sample at &lt;a href="http://wazsong.cloudapp.net"&gt;http://wazsong.cloudapp.net&lt;/a&gt; and &lt;a href="http://smarxblog.blob.core.windows.net/files/WindowsAzureSong_source.zip"&gt;download the full source code&lt;/a&gt;.&amp;#160; Enjoy, and good luck if you enter the contest!&lt;/p&gt;  </content></entry></feed>