<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Convective</title>
	<atom:link href="http://convective.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://convective.wordpress.com</link>
	<description>Heading up to the cloud</description>
	<lastBuildDate>Thu, 23 Feb 2012 04:16:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='convective.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/d27b7b32e8cd06e6f25f25b6913ec49b?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Convective</title>
		<link>http://convective.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://convective.wordpress.com/osd.xml" title="Convective" />
	<atom:link rel='hub' href='http://convective.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Node.js, Windows Azure (and socket.io)</title>
		<link>http://convective.wordpress.com/2012/02/21/node-js-windows-azure-and-socket-io/</link>
		<comments>http://convective.wordpress.com/2012/02/21/node-js-windows-azure-and-socket-io/#comments</comments>
		<pubDate>Tue, 21 Feb 2012 08:46:01 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[socket.io]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/?p=245</guid>
		<description><![CDATA[The Windows Azure Platform now supports various application-hosting environments including: .NET Java PHP Node.js .NET has always been the primary development environment for Windows Azure. Java and PHP have been around for many years and applications developed in these environments &#8230; <a href="http://convective.wordpress.com/2012/02/21/node-js-windows-azure-and-socket-io/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=245&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Windows Azure Platform now supports various application-hosting environments including:</p>
<ul>
<li><a href="http://www.windowsazure.com/en-us/develop/net/">.NET</a>
<li><a href="http://www.windowsazure.com/en-us/develop/java/">Java</a>
<li><a href="http://www.windowsazure.com/en-us/develop/php/">PHP</a>
<li><a href="http://www.windowsazure.com/en-us/develop/nodejs/">Node.js</a></li>
</ul>
<p>.NET has always been the primary development environment for Windows Azure. Java and PHP have been around for many years and applications developed in these environments have been deployable to Windows Azure for some time.</p>
<p><a href="http://nodejs.org/">Node.js</a> is a lightweight platform, developed by Ryan Dahl (@ryah), for building highly-scalable network applications written in JavaScript. In particular, it can be used to develop and deploy web servers. <a href="http://socket.io/">socket.io</a> is a Node.js package that provides a simple way to access HTML5 web sockets thereby facilitating the creation of applications supporting browser-to-browser conversation. The Node.js <a href="http://nodejs.org/docs/latest/api/index.html">documentation</a> is here.</p>
<p>This post is a brief introduction to Node.js and socket.io with that introduction being focused on the implementation of Node.js inside the Windows Azure environment.</p>
<h3>Node.js</h3>
<p>Node.js is an application hosting environment developed in C++ and using the <a href="http://code.google.com/p/v8/">Google V8&nbsp; JavaScript engine</a> to host applications written in JavaScript. An essential feature of applications written in Node.js is the heavy use of callbacks making support for an asynchronous programming model more natural. Node.js can be downloaded directly from the Node.js <a href="http://nodejs.org/">website</a>.</p>
<h4>Hello World in Node.js</h4>
<p>The following example demonstrates how easy it is to write a website serving a single <em>Hello World</em> web page.</p>
<p><font size="2" face="Courier New"><code>var port = 81;<br />var http = require('http');</font></p>
<p><font size="2" face="Courier New">var app = http.createServer(function (req, res) {<br />&nbsp; res.writeHead(200, {'Content-Type': 'text/plain'});<br />&nbsp; res.end('Hello World\n');<br />});</font></p>
<p><font size="2" face="Courier New">app.listen(port);<br />console.log('Server running on port ' + port);</code></font></p>
<p>When the above code is saved in a file named <em>server.js</em> the following command can be used to launch the web server:</p>
<p><font size="2" face="Courier New">node server.js</font></p>
<p>The <em>require()</em> statement imports the Node.js <em>http</em> module into the application where it is used to create an HTTP server. The parameter to the <em>createServer()</em> method is an anonymous callback function invoked each time the server receives a request. This callback is passed the <em>request</em> and <em>response</em> streams for the request. In the example, a response header is added before <em>res.end()</em> is invoked to write <em>Hello World</em> to the response and flush the response back to the client. <em>app.listen()</em> starts the server listening on port 81.</p>
<p>This simple program demonstrates several features common to Node.js applications:</p>
<ul>
<li>the use of <em>require()</em> to import modules into the application
<li>the creation of a server
<li>the use of <em>listen()</em> to start the listening process</li>
</ul>
<h4>Application Frameworks</h4>
<p>A web application can be coded directly in JavaScript and deployed as a website hosted in Node.js. As in other web-development environments it is common to use an application framework to structure the application and enforce a separation of concerns that aids the development of large-scale applications.
<p>Many Node.js samples use the <a href="http://expressjs.com/">Express</a> framework. This uses routes and views directories to store application routes and views. Express supports various view engines including <a href="http://jade-lang.com/">Jade</a> and <a href="https://github.com/visionmedia/ejs#readme">EJS</a> (embedded JavaScript). These provide different ways to specify the appearance of a web page.
<p>The following commands can be invoked to download the Express module and create a default Node.js web server using the Express framework and the Jade view engine:
<p><font size="2" face="Courier New">npm install express<br /></font><font size="2" face="Courier New">.\node_modules\.bin\express<br /></font><font size="2" face="Courier New">npm install</font>
<p><font size="2" face="Courier New">node app.js</font>
<p>This starts a web server, listening on port 3000, which responds with the web page defined in views\index.jade.<br />
<h4>Node Package Manager (NPM)</h4>
<p>The Node Package Manager (NPM) is an application that simplifies the local installation for the thousands of packages that have been created for Node.js. NPM stores downloaded packages in a node_modules folder under the invocation directory. It is possible to specify that downloaded packages be stored globally but, in general, they should be regarded as part of the application they are being used in and stored locally (which is the default).
<p>The <em>package.json</em> file associated with a downloaded package specifies dependencies on other packages that it may have. NPM recursively downloads these dependent packages into a node_modules directory associated with the initial package. The NPM is invoked as follows:
<p><font size="2" face="Courier New">npm install packageName</font><br />
<h3>Windows Azure</h3>
<p>Microsoft supports Node.js as a first-class development environment for Windows Azure. The Windows Azure developers portal has a <a href="http://www.windowsazure.com/en-us/develop/nodejs/">section</a> devoted to Node.js that contains various samples and a download link for the Windows Azure SDK for Node.js.</p>
<p>The SDK is installed in the following directory:</p>
<p><font size="2" face="Courier New">%ProgramFiles(x86)%\Microsoft SDKs\Windows Azure\Nodejs</font></p>
<p>The installation process creates a link on the Start menu for the <em>Windows Azure PowerShell for Node.js</em> which launches a PowerShell console with the Windows Azure Node.js cmdlets preloaded. These cmdlets can be used to manage the creation and deployment of hosted services both in the development and Windows Azure environment. As is typical with Windows Azure development environments, the PowerShell console should be launched using <em>Run as Administrator</em>.</p>
<p>The cmdlets include the following:</p>
<ul>
<li>New-AzureService serviceName
<li>Add-AzureNodeWorkerRole roleName
<li>Add-AzureNodeWebRole roleName
<li>Start-AzureEmulator
<li>Stop-AzureEmulator</li>
</ul>
<p>These can be used sequentially to create a Windows Azure hosted service with zero or more web and worker roles and then deploy them to the compute emulator before tearing down the service. The developer portal has a <a href="http://www.windowsazure.com/en-us/develop/nodejs/tutorials/getting-started/">sample</a> that does precisely this. Other cmdlets support the deployment of the hosted service to Windows Azure.</p>
<h4>Web Roles and Worker Roles</h4>
<p>The Windows Azure SDK for Node.js implements web and worker roles in different ways leading to differences in the supported functionality. Specifically, since <em>http.sys</em> does not support <a href="http://dev.w3.org/html5/websockets/">HTML5 web sockets</a> it is not possible to use them in a Node.js (or any) application deployed to a web role. Web sockets are supported for Node.js (or any) application deployed to a worker role. One benefit of using a web role is that, as shown by Aaron Stannard (@Aaronontheweb) in this <a href="http://www.aaronstannard.com/post/2012/01/17/How-to-Automatically-Utilize-Multicore-Servers-with-Node-on-Windows-Azure.aspx">post</a>, IIS can handle the launching of multiple node.exe instances automatically. Otherwise, Node.js would only be able to use a single core, even in a multi-core instance.</p>
<p>A web role is implemented using a special IISNode module which is loaded as additional ASP.NET module in IIS. When creating a Windows Azure package for deployment, the packager creates a startup task to perform various tasks including installing IISNode in the web role instance. In the development machine, IISNode is installed in:</p>
<p><font size="2" face="Courier New">%ProgramFiles(x86)%\Microsoft SDKs\iisnode</font></p>
<h1><font size="2" face="Courier New"></font></h1>
<p>A worker role is implemented using the new <a href="http://msdn.microsoft.com/en-us/library/windowsazure/gg557552.aspx#ProgramEntryPoint">ProgramEntryPoint</a> functionality exposed in <em>ServiceDefinition.csdef</em> which allows an arbitrary program to be specified as the role entry point. Specifically, on startup a worker role hosting a Node.js application invokes the following program entry point:</p>
<p><font size="2" face="Courier New">node.exe .\server.js</font></p>
<p>An obvious implication is that the Node.js application must be in a file named server.js – although it can import additional modules.</p>
<p>It is remarkably easy to port a Node.js application to Windows Azure. A particularly impressive sample on the Windows Azure developer portal takes a standard example from the socket.io website and ports it to Windows Azure by changing only two lines of code. One change is simply to the location of a module while the other is the specification of the port to listen on in a Windows Azure friendly manner. Specifically, when using Windows Azure SDK for Node.js it is necessary to specify the listening port using:</p>
<p><font size="2" face="Courier New">process.env.port</font></p>
<p>which allows the application to access the correct Windows Azure endpoint.</p>
<p>Furthermore, it can sometimes be helpful to test Node.js applications directly, using node.exe, without launching the Windows Azure development environment. This is feasible because of the simple manner with which Node.js applications are inserted into the development environment.</p>
<h4>Node.js Packages for Windows Azure </h4>
<p>The Windows Azure SDK for Node.js does not provide access to the various Windows Azure SDKs. In keeping with the style of Node.js applications, this SDK is instead deployed as a set of <a href="https://github.com/WindowsAzure/azure-sdk-for-node#readme">Node.js packages for Windows Azure</a> which are downloaded into a Node.js application using</p>
<p><font size="2" face="Courier New">npm install azure</font></p>
<p>The packages expose Node.js APIs for:</p>
<ul>
<li>Windows Azure Storage Service (blobs, tables and queues)
<li>Service Bus Brokered Messaging (queues, topics and subscriptions)</li>
</ul>
<p>The Windows Azure developer portal has a complete <a href="http://www.windowsazure.com/en-us/develop/nodejs/tutorials/web-app-with-storage/">example</a> showing how to access Windows Azure Table service from a Node.js application developed using Express/Jade. When the azure packages are installed, examples of all the supported functionality are installed in the node_modules\azure\examples directory for the application.</p>
<h4>Some Node.js on Windows Azure Links</h4>
<p>Glenn Block (@gblock) has an interesting Channel 9 <a href="http://channel9.msdn.com/Events/windowsazure/learn/Interview-with-Glenn-Block-Talking-About-Node-js-on-Windows-Azure">interview</a> in which he describes Node.js on Windows Azure. Matt Harrington (@mh415) has a <a href="http://blogs.msdn.com/b/matt-harrington/archive/2012/02/19/how-to-use-node-js-with-the-local-azure-storage-emulator.aspx">post</a> describing the environment variables available when using the Node.js azure packages as well as a <a href="http://blogs.msdn.com/b/matt-harrington/archive/2012/02/18/how-to-enable-logging-between-node-js-and-azure.aspx">post</a> showing how to log messages. Aaron Stannard has a <a href="http://www.aaronstannard.com/post/2012/02/06/How-to-Use-the-Azure-npm-Package-without-Windows-Azure.aspx">post</a> on using the Node.js packages for Windows Azure outside the compute emulator.</p>
<h3>socket.io</h3>
<p>Guillermo Rauch (@rauchg) developed<a href="http://socket.io/"> socket.io</a>, a Node.js package that simplifies the creation of web applications supporting real-time communication between browsers and devices. The github repository and documentation for socket.io is <a href="https://github.com/LearnBoost/socket.io#readme">here</a>. The canonical example of a socket.io application is a chat application supporting a conversation between clients.</p>
<p>socket.io supports various transports including:</p>
<ul>
<li>web socket
<li>html file
<li>xhr-polling
<li>jsonp – polling</li>
</ul>
<p>By default, the transports are used in that priority and socket.io automatically degrades a connection when the transport is not supported. Web sockets are not supported by IIS so, as mentioned earlier, a worker role must be used if web socket support is desired for a socket.io application hosted in Windows Azure. Similarly, IE9 does not support web sockets so IE9 use again leads to a degraded connection. (Hint: the Chrome browser provides a better development experience since it does not suffer any connection degradation delay.)</p>
<p>socket.io implements the Node.js <a href="http://nodejs.org/docs/latest/api/events.html">EventEmitter</a> interface and so provides a nice demonstration of idiomatic Node.js. The EventEmitter interface comprises:</p>
<ul>
<li>emitter.addListener(event, listener)
<li>emitter.on(event, listener)
<li>emitter.once(event, listener)
<li>emitter.removeListener(event, listener)
<li>emitter.removeAllListeners([event])
<li>emitter.setMaxListeners(n)
<li>emitter.listeners(event)
<li>emitter.emit(event, [arg1], [arg2], [...])
<li>Event: &#8216;newListener&#8217;</li>
</ul>
<h4>This interface supports the association of named events (or messages) with callbacks. Specifically, <em>emitter.emit()</em> sends a named event while <em>emitter.on()</em> listens for a named event and associates a callback with it. A socket.io application is created by the mutual exchange of named events between the client and the server.</h4>
<p>A core <em>sockets</em> object manages connections. It handles a connection event by creating a socket object and passing that to the callback associated with the <em>connection</em> event. The socket object handles individual connections and listens for the <em>disconnect</em> event.&nbsp; It also supports named events that contain the conversation messages providing the application functionality.</p>
<h3>Simple Windows Azure Application using socket.io</h3>
<p>A very basic socket.io application hosted in the Windows Azure development environment can be created as follows:</p>
<ul>
<li>Start the Windows Azure PowerShell for Node.js console (using Run as Administrator)
<li>cd to some directory
<li>Type New-AzureService chat
<li>Type Add-AzureNodeWorkerRole
<li>cd WorkerRole1
<li>Type npm install socket.io
<li>Open server.js in some editor (e.g., <a href="http://www.sublimetext.com/2">Sublime Text 2</a>) and replace the contents with the following:</li>
</ul>
<p><font size="2" face="Courier New"><code>// Import various modules and start listening for socket.io connections<br />var app = require('http').createServer(handler)<br />&nbsp; , io = require('socket.io').listen(app)<br />&nbsp; , fs = require('fs');</font></p>
<p><font size="2" face="Courier New">// Configure the port to run in the Windows Azure emulator<br />var port = process.env.port || 81;</font></p>
<p><font size="2" face="Courier New">// start listening for HTTP connections <br />app.listen(port);<br />&nbsp;<br />// The handler function returns index.html to the browser<br />function handler (req, res) {<br />&nbsp; fs.readFile(__dirname + '/index.html',&nbsp; function (err, data) {<br />&nbsp;&nbsp;&nbsp; if (err) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; res.writeHead(500);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return res.end('Error loading index.html');<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp; res.writeHead(200);<br />&nbsp;&nbsp;&nbsp; res.end(data);<br />&nbsp; });<br />}</font></p>
<p><font size="2" face="Courier New">// Handle 'connection' events<br />io.sockets.on('connection', function (socket) {<br />&nbsp; socket.emit('fromServer', { message: 'Connected' });</font></p>
<p><font size="2" face="Courier New">&nbsp; socket.on('message', function (data) {<br />&nbsp;&nbsp;&nbsp; socket.emit('message', { message: 'Message forwarded' });<br />&nbsp;&nbsp;&nbsp; socket.broadcast.emit('message', { message: data.message });<br />&nbsp; });<br />});</code></font></p>
<ul>
<li>Create a file named index.html (in the same directory) and copy the following into it:</li>
</ul>
<p><font size="2" face="Courier New"><code>&lt;html&gt;<br />&lt;head&gt;<br />&lt;script src="/socket.io/socket.io.js"&gt;&lt;/script&gt;<br />&lt;script src="</font><a href="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js&quot;"><font size="2" face="Courier New">http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"</font></a><font size="2" face="Courier New">&gt;&lt;/script&gt;<br />&lt;script&gt;<br />var socket = io.connect('</font><a href="http://localhost:81');"><font size="2" face="Courier New">http://localhost:81');</font></a></p>
<p><font size="2" face="Courier New">socket.on('fromServer', function (data) {<br />&nbsp;&nbsp;&nbsp; displayMessage(data.message);<br />});</font></p>
<p><font size="2" face="Courier New">socket.on('message', function (data) {<br />&nbsp;&nbsp;&nbsp; displayMessage(data.message);<br />});</font></p>
<p><font size="2" face="Courier New">function sendMessage()<br />{<br />&nbsp;&nbsp;&nbsp; socket.emit('message', { message: $('#MessageText').val() });<br />};</font></p>
<p><font size="2" face="Courier New">function displayMessage( message ) {<br />&nbsp;&nbsp;&nbsp; $('#Output').text(message);&nbsp;&nbsp;&nbsp; <br />};<br />&lt;/script&gt;<br />&lt;head&gt;<br />&lt;body&gt;<br />Message:&lt;input id="MessageText" type="text"/&gt;&amp;nbsp;<br />&lt;input type="button" value="Send message" onclick="sendMessage();"/&gt;<br />&lt;div id="Output"/&gt;<br />&lt;br/&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</font></p>
<p><font size="2" face="Courier New">io.sockets.on('connection', function (socket) {<br />&nbsp; socket.emit('fromServer', { message: 'Connected' });</font></p>
<p><font size="2" face="Courier New">&nbsp; socket.on('message', function (data) {<br />&nbsp;&nbsp;&nbsp; socket.emit('message', { message: 'Message forwarded' });<br />&nbsp;&nbsp;&nbsp; socket.broadcast.emit('message', { message: data.message });<br />&nbsp; });<br />});</code></font></p>
<ul>
<li>Type Start-AzureEmulator –launch</li>
</ul>
<p>Start multiple browser windows pointing to <a href="http://localhost:81">http://localhost:81</a>.</p>
<p>The UI is simple &#8211; with a message box, a <em>Send message</em> button and a status line below. After a few seconds, the status line should display Connected. When a message is typed in one of the message boxes and submitted, the status line in the current windows displays &#8220;Message forwarded&#8221; while the status line in the other windows displays the message text. Using the appropriate developer tools for the browser it is possible to find out the transport used for communication between the browser and the server.</p>
<ul>
<li>Type Stop-AzureEmulator to shutdown the compute emulator.</li>
</ul>
<p>This demonstration is very simple with the Node.js server serving up a simple web page to the browsers. The server listens for socket.io connections and on receiving one sends a <em>connected</em> message back to the client and sets up a socket listener for an event named <em>message</em>. On receiving such an event the socket responds by sending an event named <em>fromServer </em>with content <em>Message forwarded</em> back to the client and broadcasts an event named <em>message,</em> containing the message text, to all other clients. On loading, the browser connects to the server and, on connection, adds listeners for two events named <em>fromServer</em> and <em>message</em>. On receiving an event, the response is displayed in the status line. When the button is clicked, <em>socket.emit()</em> is invoked to send the message to the server.</p>
<p>This is a trivial demonstration that shows how easy it is to implement a Node.js application using socket.io inside Windows Azure. Mariano Vazquez uses an equally simple demonstration in a blog <a href="http://nodeblog.cloudapp.net/running-socket-io-on-windows-azure-web-and-worker-roles">post</a> in which he provides additional information about configuring the transport used by the connection.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/245/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=245&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2012/02/21/node-js-windows-azure-and-socket-io/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>MongoDB, Windows Azure (and Node.js)</title>
		<link>http://convective.wordpress.com/2012/02/05/mongodb-windows-azure-and-node-js/</link>
		<comments>http://convective.wordpress.com/2012/02/05/mongodb-windows-azure-and-node-js/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 20:07:00 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[MongoDB]]></category>
		<category><![CDATA[Node.js]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/?p=237</guid>
		<description><![CDATA[The Windows Azure ecosystem is being extended both by Microsoft and by third-party providers. This post focuses&#160; on one of these extensions – the MongoDB document database. It shows how MongoDB can be deployed in a Windows Azure hosted service &#8230; <a href="http://convective.wordpress.com/2012/02/05/mongodb-windows-azure-and-node-js/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=237&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Windows Azure ecosystem is being extended both by Microsoft and by third-party providers. This post focuses&nbsp; on one of these extensions – the MongoDB document database. It shows how MongoDB can be deployed in a Windows Azure hosted service and accessed from other roles in the hosted service using either traditional .NET or the recently released Node.js support.</p>
<h3>NoSQL</h3>
<p>During the last 30 years SQL databases have become the dominant data storage systems, with commercial offerings such as Oracle, Microsoft SQL Server and IBM DB2 achieving enormous commercial success. These data systems are characterized by their support for <a href="http://en.wikipedia.org/wiki/ACID">ACID</a> semantics &#8211; atomicity, consistency, isolation and durability. These properties impose a certainty that is essential for many business processes dealing with valuable data. However, supporting ACID semantics becomes increasingly expensive as the volume of data increases.</p>
<p>The advent of Web 2.0 has led to an increasing interest in long-tail data whose value comes not from the value of a single piece of data but from the magnitude of the aggregate data.&nbsp; Web logs provide a paradigmatic example of this type of data. Because of the low value of an individual data item this type of data can be managed by data systems which do not need to support full ACID semantics.</p>
<p>Over the last few years a new type of data storage semantics has become fashionable: <a href="http://queue.acm.org/detail.cfm?id=1394128">BASE</a> -basically available, soft state, eventually consistent. While the name may be a bit forced to make the pun, the general idea is that a system adhering to BASE semantics, when implemented as a distributed system, should be able to survive network partitioning of the individual components of the system at the cost of offering a lower level of consistency than available in traditional SQL systems.</p>
<p>In a strongly-consistent system, all reads following a write receive the written data. In an eventually-consistent system, reads immediately following a write are not guaranteed to return the newly written value. However, eventually all writes should return the written value.</p>
<p><a href="http://en.wikipedia.org/wiki/NoSQL">NoSQL</a> (not only SQL) is a name used to classify data systems that do not use SQL and which typically implement BASE semantics instead of ACID semantics. NoSQL systems have become very popular and many such systems have been created – most of them distributed in an open source model. Another important feature of NoSQL systems is that, unlike SQL systems, they do not impose a schema on stored entities.</p>
<p>NoSQL systems can be <a href="http://nosql-database.org/">classified</a> by how data is stored as:</p>
<ul>
<li>key-value
<li>document</li>
</ul>
<p>In a key-value store, an entity comprises a primary key and a set of properties with no associated schema so that each entity in a “table” can have a different set of properties. Apache <a href="http://en.wikipedia.org/wiki/Apache_Cassandra">Cassandra</a> is a popular key-value store. A document store provides for the storage of semantically richer entities with an internal structure. <a href="http://en.wikipedia.org/wiki/Mongodb">MongoDB</a> is a popular document store.</p>
<p>Windows Azure Tables is a key-value NoSQL store provided in the Windows Azure Platform. Unlike other NoSQL stores, it supports strong consistency with no eventually-consistent option. The Windows Azure Storage team recently published a <a href="http://blogs.msdn.com/b/windowsazurestorage/archive/2011/11/20/windows-azure-storage-a-highly-available-cloud-storage-service-with-strong-consistency.aspx">paper</a> describing the implementation of Windows Azure Tables.</p>
<p><a href="http://www.10gen.com/">10gen</a>, the company which maintains and supports MongoDB, has worked with Microsoft to make MongoDB available on Windows Azure. This provides Windows Azure with a document store NoSQL system to complement the key-value store provided by Windows Azure Tables.</p>
<h3>MongoDB</h3>
<p>MongoDB is a NoSQL document store in which individual entities are persisted as documents inside a collection hosted by a database. A single MongoDB installation can comprise many databases. MongoDB is schemaless so each document in a collection can have a different schema. Consistency is tunable from eventual consistency to strong consistency.</p>
<p>MongoDB uses memory-mapped files and performance is optimal when all the data and indexes fit in memory. It supports automated sharding allowing databases to scale past the limits of a single server. Data is stored in <a href="http://bsonspec.org/">BSON</a> format which can be thought of as a binary-encoded version of <a href="http://json.org/">JSON</a>.</p>
<p>High availability is supported in MongoDB through the concept of a replica set comprising one primary member and one or more secondary members, each of which contains a copy of all the data. Writes are performed against the primary member and are then copied asynchronously to the secondary members. A safe write can be invoked that returns only when the write is copied to a specified number of secondary members – thereby allowing the consistency level to be tuned as needed. Reads can be performed against secondary members to improve performance by reducing the load on the primary member.</p>
<p>MongoDB is open-source software maintained and supported by 10gen, the company which originally developed it. 10gen provides <a href="http://www.mongodb.org/downloads">downloads</a> for various platforms and versions. 10gen also provides <a href="http://www.mongodb.org/display/DOCS/Drivers">drivers</a> (or APIs) for many languages including C# and F#. MongoDB comes with a JavaScript shell which is useful for performing ad-hoc queries and testing a MongoDB deployment.</p>
<p>Kyle Banker, of 10gen, has written an excellent book called <a href="http://manning.com/banker/">MongoDB in Action</a>. I highly recommend it to anyone interested in MongoDB.</p>
<h3>MongoDB on Windows Azure</h3>
<p><a href="http://www.davidmakogon.com/">David Makogon</a> (@dmakogon) <a href="http://www.10gen.com/presentations/mongosv2010/azure">worked</a> out how to deploy MongoDB onto worker role instances on Windows Azure. 10gen then worked with him and the Microsoft Interoperability team to develop an officially supported preview release of the <a href="http://www.mongodb.org/display/DOCS/MongoDB+on+Azure">MongoDB on Windows Azure</a> wrapper which simplifies the task of deploying a MongoDB replica set onto worker role instances.</p>
<p>The wrapper deploys each member of the replica set to a separate instance of a worker role. The <em>mongod.exe</em> process for MongoDB is started in the OnStart() role entry point for the instance. The data for each member is persisted as a page blob in Windows Azure Blob storage that is mounted as an Azure Drive on the instance. </p>
<p>The MongoDB on Windows Azure wrapper can be <a href="https://github.com/mongodb/mongo-azure/">downloaded</a> from github. The download comprises two directory trees: <em>ReplicaSets</em> containing the core software as the <em>MongoDBReplicaSet</em> solution; and <em>SampleApplications</em> containing an MVC Movies sample application named <em>MongoDBReplicaSetMvcMovieSample</em>. The directory trees contain a PowerShell script, <em>solutionsetup.ps1</em>, that must be invoked to download the latest MongoDB binaries.</p>
<p>The <em>MongoDBReplicaSetMvcMovieSample</em> solution contains four projects:</p>
<ul>
<li>MongoDBAzureHelper – helper class to retrieve MongoDB configuration
<li>MongoDBReplicaSetSample – Windows Azure project
<li>MvcMovie – an ASP.NET MVC 3 application
<li>ReplicaSetRole – worker role to host the members of a MongoDB replica set.</li>
</ul>
<p>The <em>MVCMovie</em> project is based on the <a href="http://www.asp.net/mvc/tutorials/getting-started-with-aspnet-mvc3/getting-started-with-mvc3-part1-cs">Intro to ASP.NET MVC 3</a> sample on asp.net website. It displays movie information retrieved from the MongoDB replica set hosted in the <em>ReplicaSetRole</em> instances. The <em>ReplicaSetRole</em> is launched as 3 medium instances each if which hosts a replica set member. The MongoDBAzureHelper and ReplcaSetRole projects are from the <em>MongoDBReplicaSet</em> solution. </p>
<p>The <em>MongoDBReplicaSetMvcMovieSample</em> solution can be opened in Visual Studio, then built and deployed either to the local compute emulator or a Windows Azure hosted service. The application has two pages: an <em>About</em> page displaying the status of the replica set; and a <em>Movies</em> page allowing movie information to be captured and displayed. It may take a minute or two for the replica set to come fully online and the status to be made available on the <em>About</em> page. When a movie is added to the database via the <em>Movies</em> page, it may occasionally require a refresh for the updated information to become visible on the page. This is because MongoDB is an eventually consistent database and the Movies page may have received data from one of the secondary nodes.</p>
<p>This example provides a general demonstration of how a MongoDB installation with replica sets is added to a Windows Azure project: add the MongoDBAzureHelper and ReplicaSetRole projects from the <em>MongoDBReplicaSet</em> solution and add the appropriate configuration to the ServiceDefinition.csdef and ServiceConfiguration.cscfg files.</p>
<p>The ServiceDefinition.csdef entries for ReplicaSetRole are:</p>
<p><font size="2" face="Courier New">&lt;Endpoints&gt;<br />&nbsp;&nbsp;&nbsp; &lt;InternalEndpoint name=&#8221;MongodPort&#8221; protocol=&#8221;tcp&#8221; port=&#8221;27017&#8243; /&gt;<br />&lt;/Endpoints&gt;<br />&lt;ConfigurationSettings&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBDataDir&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;ReplicaSetName&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBDataDirSize&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBLogVerbosity&#8221; /&gt;<br />&lt;/ConfigurationSettings&gt;<br />&lt;LocalResources&gt;<br />&nbsp;&nbsp;&nbsp; &lt;LocalStorage name=&#8221;MongoDBLocalDataDir&#8221; cleanOnRoleRecycle=&#8221;false&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeInMB=&#8221;1024&#8243; /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;LocalStorage name=&#8221;MongodLogDir&#8221; cleanOnRoleRecycle=&#8221;false&#8221;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sizeInMB=&#8221;512&#8243; /&gt;<br />&lt;/LocalResources&gt;</font></p>
<p>Port 27017 is the standard port for a MongoDB installation. None of the settings need be changed for the sample project.</p>
<p>The ServiceDefinition.csdef entries for MvcMovie are:</p>
<p><font size="2" face="Courier New">&lt;ConfigurationSettings&gt;<br />&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;ReplicaSetName&#8221; /&gt;<br />&lt;/ConfigurationSettings&gt;</font>
<p>The ServiceConfiguration.cscfg settings for the ReplicaSetRole are:</p>
<p><font size="2" face="Courier New">&lt;ConfigurationSettings&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBDataDir&#8221; value=&#8221;UseDevelopmentStorage=true&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;ReplicaSetName&#8221; value=&#8221;rs&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBDataDirSize&#8221; value=&#8221;" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;MongoDBLogVerbosity&#8221; value=&#8221;-v&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString&#8221; value=&#8221;UseDevelopmentStorage=true&#8221; /&gt;<br />&lt;/ConfigurationSettings&gt;</font></p>
<p>The ServiceConfiguration.cscfg settings for the MvcMovie web role are:</p>
<p><font size="2" face="Courier New">&lt;ConfigurationSettings&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;ReplicaSetName&#8221; value=&#8221;rs&#8221; /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Setting name=&#8221;Microsoft.WindowsAzure.Plugins.Diagnostics.ConnectionString&#8221; value=&#8221;UseDevelopmentStorage=true&#8221; /&gt;<br />&lt;/ConfigurationSettings&gt;</font>
<p>It is critical that the value for the <em>ReplicaSetName</em> be the same in both the MvcMovie web role and the ReplicaSets worker role.</p>
<p>The replica set can also be accessed from the MongoDB shell, mongo, once it is running in the compute emulator. This is a useful way to ensure that everything is working since it provides a convenient way of accessing the data and managing the replica set. The application data is stored in the movies collection in the movies database. For example, the <em>rs.stepDown()</em> command can be invoked on the primary member to demote it to a secondary. MongoDB will automatically select one of the secondary members and promote it to primary. Note that in the compute emulator, the 3 replica set members are hosted at port numbers 27017, 27018 and 27019 respectively.</p>
<p>This sample demonstrates the process of adding support for MongoDB to a Windows Azure solution with a web role.</p>
<p>1) Add the following MongoDB projects to the solution;</p>
<ul>
<li>MongoDBAzureHelper
<li>ReplicaSetRole</li>
</ul>
<p>2) Add the MongoDB assemblies to the web role:</p>
<ul>
<li>Mongo.DB.Bson (copy local)
<li>Mongo.DB.Driver (copy local)
<li>MongoDBAzureHelper&nbsp; (from the added project)</li>
</ul>
<p>3) Add the MongoDB settings described earlier to the Windows Azure service configuration.</p>
<h3>MongoDB on Windows Azure with Node.js</h3>
<p><a href="http://nodejs.org/">Node.js</a> is a popular system for developing web servers using JavaScript and an asynchronous programming model. Microsoft recently released the <a href="http://www.windowsazure.com/en-us/develop/nodejs/">Windows Azure SDK for Node.js</a> which makes it easy to deploy Node.js web applications to Windows Azure.</p>
<p>The SDK provides an extensive set of PowerShell scripts &#8211; such as <em>Add-AzureNodeWebRole</em>, <em>Start-AzureEmulator</em>, and <em>Publish-AzureService</em> &#8211; which simplify the lifecycle management of developing and deploying a Node.js web application. It contains several introductory tutorials including a <a href="http://www.windowsazure.com/en-us/develop/nodejs/tutorials/web-app-with-mongodb/">Node.js Web Application with Storage on MongoDB</a>. This tutorial shows how to add a replica set implemented, as described earlier, to a web application developed in Node.js.</p>
<h3>Summary</h3>
<p>The MongoDB on Windows Azure wrapper and the Windows Azure SDK for Node.js tutorial have made it very easy to try MongoDB out in a Windows Azure hosted service.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/237/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/237/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/237/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=237&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2012/02/05/mongodb-windows-azure-and-node-js/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Presentation on Windows Azure Brokered Messaging</title>
		<link>http://convective.wordpress.com/2011/12/12/presentation-on-windows-azure-brokered-messaging/</link>
		<comments>http://convective.wordpress.com/2011/12/12/presentation-on-windows-azure-brokered-messaging/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 09:00:16 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Brokered Messaging]]></category>
		<category><![CDATA[Service Bus]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>
		<category><![CDATA[Service Bus Brokered Messaging]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/?p=234</guid>
		<description><![CDATA[I did a presentation on Windows Azure Brokered Messaging at the San Francisco Bay Area Azure Developers group – which meets monthly in Microsoft San Francisco. The presentation was based on a post I did on Brokered Messaging. The deck &#8230; <a href="http://convective.wordpress.com/2011/12/12/presentation-on-windows-azure-brokered-messaging/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=234&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I did a presentation on Windows Azure Brokered Messaging at the <a href="http://www.bayazure.org/">San Francisco Bay Area Azure Developers</a> group – which meets monthly in Microsoft San Francisco. The presentation was based on a <a href="http://bit.ly/oZdewm">post</a> I did on Brokered Messaging.</p>
<p>The deck can be <a href="http://slidesha.re/u4311f">viewed</a> (or downloaded) on SlideShare.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/234/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/234/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/234/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=234&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/12/12/presentation-on-windows-azure-brokered-messaging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>First Comes the Writing</title>
		<link>http://convective.wordpress.com/2011/10/18/first-comes-the-writing/</link>
		<comments>http://convective.wordpress.com/2011/10/18/first-comes-the-writing/#comments</comments>
		<pubDate>Tue, 18 Oct 2011 19:32:36 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[book]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/10/18/first-comes-the-writing/</guid>
		<description><![CDATA[… and then comes the marketing. When Packt Publishing first approached me about writing a book, I headed to Borders to look at a few books it published. I was impressed by the quality of the books, and signed up &#8230; <a href="http://convective.wordpress.com/2011/10/18/first-comes-the-writing/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=227&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>… and then comes the marketing.</p>
<p>When Packt Publishing first approached me about writing a book, I headed to Borders to look at a few books it published. I was impressed by the quality of the books, and signed up to write the <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">Microsoft Windows Azure Development Cookbook</a>. Packt has published a number of <a href="http://www.packtpub.com/books/cloud">cloud-related books</a>, and currently is offering an early release version of a book by David Burela (@DavidBurela) titled <a href="http://www.packtpub.com/microsoft-silverlight-4-enterprise-integration-on-windows-azure/book">Microsoft Silverlight 4 and Windows Azure Enterprise Integration</a>. Anyway, Borders no longer exists – but my book does.</p>
<p><img style="display:block;float:none;margin-left:auto;margin-right:auto;" src="http://convective.files.wordpress.com/2011/08/bookcoverlargenew.png?w=640"></p>
<p>Packt is offering a giveaway, through the end of October, in which it will give an eBook version of the <em>Microsoft Windows Azure Development Cookbook</em> to two people who visit the <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">webpage</a> for the book and leave a comment on this post with the one feature that makes them want to read the book. To participate in the giveaway, leave a comment and an email address. When November comes, Packt will give the eBook to two people chosen at random from the commenters.</p>
<p>Note that the <a href="http://www.packtpub.com/sites/default/files/2220-chapter-7-managing-hosted-services-with-the-service-management-api.pdf?utm_source=packtpub&amp;utm_medium=free&amp;utm_campaign=pdf">chapter</a> on <em>Managing Hosted Services with the Service Management API</em> can be downloaded for free.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/227/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/227/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/227/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=227&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/10/18/first-comes-the-writing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>

		<media:content url="http://convective.files.wordpress.com/2011/08/bookcoverlargenew.png" medium="image" />
	</item>
		<item>
		<title>On Not Using owner With the Azure AppFabric Service Bus</title>
		<link>http://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/</link>
		<comments>http://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 01:41:57 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[ACS]]></category>
		<category><![CDATA[Azure AppFabric]]></category>
		<category><![CDATA[Service Bus]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Windows Azure AppFabric]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/</guid>
		<description><![CDATA[The Windows Azure AppFabric Service Bus team has been good about providing sample code for the various features it develops. There are also a fair number of blog posts (and books) showing how to use these features. Pretty much all &#8230; <a href="http://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=195&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The Windows Azure AppFabric Service Bus team has been good about providing sample code for the various features it develops. There are also a fair number of blog posts (and books) showing how to use these features. Pretty much all the sample code authenticates operations on the Service Bus via a service identity/password combination where the service identity takes the special value of <em>owner</em>.</p>
<p>In this post, I am going to show how to create and configure a service identity other than <em>owner</em>, and specifically how to ensure that this service identity is less privileged than <em>owner</em>. The intent is to show that, notwithstanding the lack of examples, it is pretty easy to use an alternate service identity. As of mid-September, the Service Bus support ACS v2 – and that is what the material in this post was tested with.</p>
<h3>Service Bus Namespace</h3>
<p>The starting point for all work with the Service Bus is the service namespace which is created and configured on the Windows Azure Portal. In creating a namespace, a unique name must be provided as well as the location of the Windows Azure datacenter which will host the service endpoints for the namespace. The namespace name becomes the first part of the URI used for these service endpoints. For example, if the namespace name is <em>gress</em> then the service gateway for the <em>gress</em> namespace becomes:</p>
<blockquote><p>https://gress.servicebus.windows.net/</p></blockquote>
<p>The various <a href="http://msdn.microsoft.com/en-us/library/windowsazure/ee732537.aspx">services</a> supported by the Service Bus – including relayed and brokered messaging – are hosted at service paths under the service gateway:</p>
<blockquote><p>https://{namespace}.servicebus.windows.net/{path}</p></blockquote>
<p>For example, the following are valid service paths:</p>
<blockquote><p>https://gress.servicebus.windows.net/topics/interestingtopic</p>
<p>https://gress.servicebus.windows.net/boringtopic/subscriptions/somesubscription</p>
<p>https://gress.servicebus.windows.net/EchoService/</p></blockquote>
<p>Note that a service path must be specifically associated with a service for the path to have any meaning with regard to a service. For example, although the first service path above probably specifies a topic named <em>topic/interestingtopic</em> there is nothing to prevent it being used instead for a relayed service. The second probably specifies a subscription named <em>somesubscription</em> on a topic named <em>boringtopic</em>. The third likely specifies a relayed service named <em>EchoService.</em></p>
<p>The paths for a namespace nominally form an infinite tree with the / indicating a branch point. For example, the following shows a namespace with two branches, one for services and the other for topics:</p>
<ul>
<li>https://gress.servicebus.windows.net/services/EchoService</li>
<li>https://gress.servicebus.windows.net/services/OneWayService</li>
<li>https://gress.servicebus.windows.net/topics/interesting</li>
<li>https://gress.servicebus.windows.net/topics/boring</li>
</ul>
<h3>Service Bus Claims</h3>
<p>The Service Bus uses the Windows Azure Access Control Service (<a href="http://msdn.microsoft.com/en-us/library/gg429786.aspx">ACS</a>) for authentication and authorization. The ACS is a Security Token Service (STS) existing as part of claims-based infrastructure. Although it supports limited identity provider (IdP) capability, the primary function of the ACS is in transforming claims in support of federated identity.</p>
<p>This post assumes and requires only minimal understanding of claims-based authentication. The Microsoft <a href="http://msdn.microsoft.com/en-us/library/ff921345.aspx">Patterns and Practices</a> Team has recently published the second edition of its excellent <a href="http://msdn.microsoft.com/en-us/library/ff423674.aspx">Guide to Claims-Based Identity and Access Control</a>. This is a good resource for a much deeper understanding of the topic.</p>
<p>When a Service Bus namespace is created, it is associated with a default service identity named <em>owner</em> and a base64-encoded <em>key</em>. This service identity has absolute control of the namespace, including all service paths in it, so it is essential that the associated key be kept secure. This is made even more important by the fact that it is not possible to change the key on the Windows Azure Portal. The default service identity and key can be used to authenticate Service Bus API requests against services hosted by the namespace.</p>
<p>The Service Bus supports three claims which authorize specific operations on a service path. These claims are all of type <em>net.windows.servicebus.action</em> with values:</p>
<ul>
<li>Listen</li>
<li>Manage</li>
<li>Send</li>
</ul>
<p>The different values authorize the obvious sets of operations on service paths. For example, the <em>Send</em> claim is required to perform the following operations:</p>
<ul>
<li>Send messages to a listener at a service namespace (relay)</li>
<li>Get the queue description</li>
<li>Send into to the queue</li>
<li>Get the topic description</li>
<li>Send to the topic</li>
</ul>
<p>The complete list of operations and associated authorization requirements is provided in the MSDN <a href="http://msdn.microsoft.com/en-us/library/windowsazure/hh403962.aspx">documentation</a>, which provides an official take on the material in this post.</p>
<p>When the default service identity, <em>owner</em>, authenticates against the ACS a rule is invoked that assigns all three claims to <em>owner</em> thereby authorizing it to perform any operation on any service path in the namespace.  Note that this discussion elides a lot of claims-based identity plumbing that is, in practice, hidden from the user of the Service Bus API. Although possible, it is strongly recommended that none of the claims be removed from the authorization provided to <em>owner</em>. Doing so can cause significant problems with the namespace.</p>
<p>It is possible to create another service identity with limited privileges, e.g. without the <em>Manage</em> claim. Indeed, it is possible to create a service identity and associate it with only one of the claims. This allows, for example, a sending service identity to be created with only the <em>Send</em> claim and a listening service identity to be created with only the <em>Listen</em> claim. Doing so allows a sending application to be distributed without the possibility of a service identity with a <em>Manage</em> claim being compromised.</p>
<p>By default, <em>owner</em> has <em>Manage</em>, <em>Send</em> and <em>Listen</em> claims over the infinite path tree of the namespace. It is possible to restrict additional service identities to only part of the service path tree. For example, if a service identity is used only to send messages to a topic there is no need for that service identity to have any claims other than <em>Send</em> on the specific service path associated with the topic. The ACS supports this type of restriction, and evaluates whether a service identity has the required permission for an operation by doing a longest string match on the service path. Essentially, it works its way back along the service path seeking a portion of the path for which the service identity has the needed permission. The service identity is authorized to perform a specific operation only if somewhere on the service path it is configured with the required claim and that permission has not been removed later in the path. This permission inheritance is similar to that on a file system. Note that it can cause problems if <em>owner</em> has permissions removed for a service path.</p>
<h3>Best Practices</h3>
<p>Suggesting that something is a best practice is probably a fair bit above my pay grade. But here goes with some recommended practices:</p>
<ul>
<li>Do not use <em>owner</em> for an operation that does not require the full privileges and claims of <em>owner</em>.</li>
<li>Use a service identity with the minimum set of claims needed for a service path.</li>
<li>Associate a service identity with the longest service path possible.</li>
</ul>
<p>Consider the following two full service paths representing a topic and an associated subscription:</p>
<ul>
<li>https://gress.servicebus.windows.net/topics/interestingtopic</li>
<li>https://gress.servicebus.windows.net/topics/interestingtopic/subscriptions/mysubscription</li>
</ul>
<p>If the topic and subscription are created out of band, distinct service identities can be created to authorize sending messages to the topic and receiving messages from the subscription. The sending service identity can be given the <em>Send</em> claim for the <em>topics/interestingtopic</em> service path. The listening service identity can be given the <em>Listen</em> claim for the <em>topics/interestingtopic/subscriptions/mysubscription</em> service path. Separating the privileges like this minimizes the possible damage from a compromised service identity.</p>
<h3>SBAzTool</h3>
<p>Using an alternative service identity is a little bit more complicated than using <em>owner</em>. However, the Window Azure Service Bus team has provided a command-line utility, <em>SBAzTool</em>, that makes it very easy to add service identities and associate them with service paths.</p>
<p>The SBAzTool is one of the samples provided with the <a href="http://www.microsoft.com/download/en/details.aspx?id=27421">Windows Azure AppFabric SDK v1.5</a> (September 2011). It is in the <em>ServiceBus/ExploringFeatures/Authorization/ManagingAccessControl</em> directory of the samples. The source code is also supplied in case you want to roll your own service management utility.</p>
<p>The following commands create two new service identities, <em>topicSender</em> and <em>subscriptionListener</em>, and grants the <em>topicSender</em> the <em>Send</em> claim on the topic (from the previous section) and the <em>subscriptionListener</em> the <em>Listen</em> claim on the associated subscription.</p>
<p><span style="font-family:Verdana;font-size:x-small;">sbaztool -n gress -k xkx&#8230;6o= storeoptions</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">sbaztool makeid topicSender<br />
sbaztool grant Send /topics/interestingtopic topicSender</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">sbaztool makeid subscriptionListener<br />
sbaztool grant Listen /topics/interestingtopic/subscriptions/mysubscription subscriptionListener</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">sbaztool clearoptions</span></p>
<p>The <em>storeoptions</em> option is used to store the <em>namespace</em> and the <em>owner</em> key in isolated storage for the SVAzTool – and the <em>clearoptions</em> option removes the information from isolated storage. The SBAzTool can also be used to delete service identities and revoke permissions, as well as display information about service identities and service paths.</p>
<p>SBAzTool makes it really easy to configure service identities and service paths so that service identities other than <em>owner</em> can be used. Consequently, there is no real excuse for not doing so.</p>
<p>Having done all this, we can replace the following code:</p>
<p><span style="font-family:Verdana;font-size:x-small;">TokenProvider tokenProvider =<br />
   TokenProvider.CreateSharedSecretTokenProvider(&#8220;owner&#8221;, ownerKey);</span></p>
<p>with</p>
<p><span style="font-family:Verdana;font-size:x-small;">TokenProvider tokenProvider =<br />
   TokenProvider.CreateSharedSecretTokenProvider(&#8220;topicSender&#8221;, topicSenderKey);</span></p>
<h3>Windows Azure Portal – Access Control Service</h3>
<p>The configuration performed by SBAzTool can also be performed manually on the ACS section of the Windows Azure Portal. The UI for ACS configuration on the portal may appear overkill in terms of what has been discussed so far. However, ACS has a much broader use than authorization on the Service Bus.</p>
<p>Clemens Vasters recently made a <a href="http://channel9.msdn.com/posts/Securing-Service-Bus-with-ACS">video</a> of a presentation in which he steps carefully through the process of configuring an issuer and service path. Consequently, I will not repeat the steps here, and will merely put the configuration performed by SBAzTool into the context of the portal.</p>
<p>The <em>makeid</em> option with SBAzTool creates a Service Identity (visible on the portal) that can be authenticated with either a symmetric key or a password. Clemens suggests that the values of these should be the same, and that is what SBAzTool does.</p>
<p>The grant option with SBAzTool creates a Relying Party Application (visible on the portal) for the full service path, e.g.</p>
<blockquote><p>http://gress.servicebus.windows.net/topics/interestingtopic</p></blockquote>
<p>Note that the full service path is normalized to specify <em>http</em> rather than any other protocol. Additionally, the tool specifies a token format of SWT and sets the token lifetime to 1200s.</p>
<p>The tool also creates a Service Group (visible on the portal) and associates it with the relying party application configuration for the service path. It also associates the service group with each intermediate service path en route to the service path. This service group generates the appropriate <em>Manage</em>, <em>Send</em> and <em>Listen</em> claims configured by the <em>grant</em> (and <em>revoke</em>) option of SBAzTool. The tool also adds a default service group which generates the <em>Manage</em>, <em>Send</em> and <em>Listen</em> claims for <em>owner</em> on the service path and each intermediate service path. This is to prevent <em>owner</em> not having full rights on the namespace.</p>
<p>Note that currently there is a bug in the portal which causes a problem when following the instructions in the video. Specifically, when creating a relying party application on the portal it is not possible to save the configuration without generating a token signing key. However, doing so causes an error when accessing the service path from an application. The workaround is to go the Certificates and keys section of the ACS configuration on the portal and delete the created token-signing certificate. Everything works fine once that is done.</p>
<p>Summary</p>
<p>My intent in this post was not to give a deep explanation of how to use a claims-based identity framework to secure the Service Bus. Rather, my intent was to provide the minimum amount of information allowing the reader to replace the use of <em>owner</em> with that of a less-privileged service identity. Specifically, I wanted to show how easy it is to do so using the SBAzTool.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/195/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/195/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/195/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=195&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/10/13/on-not-using-owner-with-the-azure-appfabric-service-bus/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows Azure AppFabric Applications Presentation at SVCC</title>
		<link>http://convective.wordpress.com/2011/10/10/windows-azure-appfabric-applications-presentation-at-svcc/</link>
		<comments>http://convective.wordpress.com/2011/10/10/windows-azure-appfabric-applications-presentation-at-svcc/#comments</comments>
		<pubDate>Tue, 11 Oct 2011 00:57:12 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Azure AppFabric]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Azure]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/10/10/windows-azure-appfabric-applications-presentation-at-svcc/</guid>
		<description><![CDATA[I did a presentation on Windows Azure AppFabric Applications  CTP1 at the Silicon Valley Code Camp yesterday. This was based on the post I did several months ago. I uploaded the deck to SlideShare for the benefit of those who &#8230; <a href="http://convective.wordpress.com/2011/10/10/windows-azure-appfabric-applications-presentation-at-svcc/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=191&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I did a presentation on Windows Azure AppFabric Applications  CTP1 at the Silicon Valley Code Camp yesterday. This was based on the <a href="http://convective.wordpress.com/2011/07/01/windows-azure-appfabric-applications/">post</a> I did several months ago. I uploaded the <a href="http://www.slideshare.net/nmackenzie/azure-appfabric-applications">deck</a> to SlideShare for the benefit of those who were there.</p>
<p>During the talk, I pointed people in the direction of a number of posts on Windows Azure AppFabric Applications by <a href="http://geekswithblogs.net/asmith/Default.aspx">Alan Smith</a> (@alansmith):</p>
<ul>
<li><a href="http://geekswithblogs.net/asmith/archive/2011/06/22/145950.aspx">Introduction</a> to AppFabric Applications.</li>
<li><a href="http://geekswithblogs.net/asmith/archive/2011/07/18/146257.aspx">Create</a> Custom External Service in Azure AppFabric June CTP.</li>
</ul>
<p>The Windows Azure AppFabric Applications CTP can be accessed on the Windows Azure AppFabrics Labs <a href="https://portal.appfabriclabs.com/Default.aspx">portal</a>. The MSDN documentation is <a href="http://msdn.microsoft.com/en-us/library/hh239716.aspx">here</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/191/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=191&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/10/10/windows-azure-appfabric-applications-presentation-at-svcc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Handling Transient Connection Failures in SQL Azure</title>
		<link>http://convective.wordpress.com/2011/09/28/handling-transient-connection-failures-in-sql-azure/</link>
		<comments>http://convective.wordpress.com/2011/09/28/handling-transient-connection-failures-in-sql-azure/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 19:00:29 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Azure AppFabric]]></category>
		<category><![CDATA[Service Bus]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[Storage Service]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Windows Azure AppFabric]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/09/28/handling-transient-connection-failures-in-sql-azure/</guid>
		<description><![CDATA[This post is one of the recipes in my book Microsoft Windows Azure Development Cookbook. The recipe describes how to use the Transient Fault Handling Framework to handle transient connection failures when using SQL Azure. The Windows Azure Customer Advisory &#8230; <a href="http://convective.wordpress.com/2011/09/28/handling-transient-connection-failures-in-sql-azure/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=190&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is one of the recipes in my book <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">Microsoft Windows Azure Development Cookbook</a>. The recipe describes how to use the Transient Fault Handling Framework to handle transient connection failures when using SQL Azure.</p>
<p>The Windows Azure Customer Advisory Team, which supports the framework, describes it as <a href="http://code.msdn.microsoft.com/Transient-Fault-Handling-b209151f">follows</a>:</p>
<blockquote><p>The <strong>Transient Fault Handling Framework</strong> solution provides a reusable framework for building extensible retry policies capable of handling different types of transient conditions in applications leveraging SQL Azure, Windows Azure storage (queues, blobs, tables), Windows Azure AppFabric Service Bus and Windows Azure AppFabric Caching Service.</p>
</blockquote>
<p>Although the post is specifically concerned with SQL Azure, the general idea can be implemented when using the Windows Azure Storage service, the Windows Azure AppFabric Service Bus and the Windows Azure AppFabric Caching Service.</p>
<p>I highly recommend the Windows Azure Customer Advisory Team <a href="http://windowsazurecat.com/section/blog/">blog</a>. It has many posts showing real-world best practices for using the various features of the Windows Azure Platform.</p>
<h3><b>Handling connection failures to SQL Azure</b></h3>
<p>SQL Azure database is a distributed system in which each physical server hosts many databases. This sharing of resources leads to capacity constraints on operational throughput. SQL Azure handles these capacity constraints by throttling operations and closing connections that are using too many resources. SQL Azure also closes connections when it alleviates operational hot spots by switching from a primary SQL Azure database to one of its two backup copies. Furthermore, connectivity to a SQL Azure database is likely to be less reliable than connectivity to a Microsoft SQL Server database on a corporate LAN. It is imperative therefore that applications using SQL Azure be designed to withstand the connection failures that are far more likely to occur than with Microsoft SQL Server.
<p>One of the mantras of cloud development is design for failure. It is important that applications using SQL Azure be designed to handle failures appropriately. There are two kinds of error: permanent errors indicating a general failure of part of the system and transient errors existing only for a brief time. Permanent errors perhaps indicate a logical problem with the application—and handling them may require code changes. However, an application should handle transient errors gracefully by retrying the operation that led to the error in the hope that it does not recur. A dropped connection should be regarded as transient, and an application should respond to a dropped connection by opening a new connection and retrying the operation.
<p>There remains the problem of distinguishing permanent from transient errors. This can be done by comparing the error returned from a failed operation with a known list of transient errors. An application can therefore include a retry mechanism that checks the status of operations and retries any operations that experienced a transient error.
<p>The Windows Azure AppFabric Customer Advisory Team has made available on the MSDN Code Gallery the source code and pre-compiled assemblies for the Transient Fault Handling Framework for Azure Storage, Service Bus, and SQL Azure. This comprises a set of classes that can be used to detect transient failures and retry SQL operations. It contains an extensible way to identify transient failures, with various examples including one that compares an error with a list of known transient failures. The Transient Fault Handling Framework provides various built-in retry backoff techniques that specify how often and frequently an operation should be retried following a transient failure. These include both a fixed interval and an exponential delay between retries. The classes in the Transient Fault Handling Framework include various extension methods that simplify the use of the framework, thereby minimizing the work required to add the handling of dropped connections and other transient failures to an application using SQL Azure.
<p>In this recipe, we will learn how to use the Transient Fault Handling Framework for Azure Storage, Service Bus, and SQL Azure to handle dropped connections and other transient failures when using SQL Azure.<br />
<h4><b>Getting ready</b></h4>
<p>The recipe uses the Transient Fault Handling Framework for Azure Storage, Service Bus, and SQL Azure. It can be downloaded from the following URL:
<p><a title="http://code.msdn.microsoft.com/Transient-Fault-Handling-b209151f" href="http://code.msdn.microsoft.com/Transient-Fault-Handling-b209151f">http://code.msdn.microsoft.com/Transient-Fault-Handling-b209151f</a>&nbsp;
<p>This download is a Visual Studio solution with precompiled output assemblies that are referenced in the project used in the recipe.<br />
<h4><b>How to do it&#8230;</b></h4>
<p>We are going to connect to SQL Azure using ADO.NET and perform various DDL and DML operations taking advantage of the transient-error handling provided by the Transient Fault Handling library. We do this as follows:
<p>1. On the Project Properties dialog in Visual Studio, set the Target Framework to .NET Framework 4.
<p>2. Add the following assembly references to the project:
<p><font size="2" face="Verdana">Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling.dll<br />System.configuration.dll</font>
<p>3. Add a new class named <em>RetryConnectionExample</em> to the project.
<p>4. Add the following using statements to the top of the class file:
<p><font size="2" face="Verdana">using System.Data;<br /></font><font size="2" face="Verdana">using System.Data.SqlClient;<br /></font><font size="2" face="Verdana">using Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling;<br /></font><font size="2" face="Verdana">using Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling.SqlAzure;<br /></font><font size="2" face="Verdana">using Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling.Configuration;</font></p>
<p>5. Add the following private members to the class:
<p><font size="2" face="Verdana">String connectionString;<br /></font><font size="2" face="Verdana">RetryPolicy connectionRetryPolicy;<br /></font><font size="2" face="Verdana">RetryPolicy commandRetryPolicy;</font>
<p>6. Add the following constructor to the class:
<p><font size="2" face="Verdana">public RetryConnectionExample(String server, String database,<br />&nbsp;&nbsp; String login, String password)<br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; SqlConnectionStringBuilder connStringBuilder;<br /></font><font size="2" face="Verdana"></font><font size="2" face="Verdana"></font><font size="2" face="Verdana"></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder = new SqlConnectionStringBuilder();<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.DataSource = String.Format(&#8220;{0}.database.windows.net&#8221;, server);<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.InitialCatalog = database;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.Encrypt = true;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.TrustServerCertificate = false;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.UserID = String.Format(&#8220;{0}@{1}&#8221;, login, server);<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connStringBuilder.Password = password;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; connectionString = connStringBuilder.ToString();</font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp; connectionRetryPolicy = new RetryPolicy&lt;SqlAzureTransientErrorDetectionStrategy&gt;(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5, TimeSpan.FromMilliseconds(100));</font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; connectionRetryPolicy.RetryOccurred += RetryConnectionCallback;</font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; RetryPolicyConfigurationSettings retryPolicySettings =<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ApplicationConfiguration.Current.GetConfigurationSection&lt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RetryPolicyConfigurationSettings&gt;(RetryPolicyConfigurationSettings.SectionName);</font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; RetryPolicyInfo retryPolicyInfo = retryPolicySettings.Policies.Get(&#8220;FixedIntervalDefault&#8221;);<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; commandRetryPolicy =<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retryPolicyInfo.CreatePolicy&lt;SqlAzureTransientErrorDetectionStrategy&gt;();<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; commandRetryPolicy.RetryOccurred += RetryCallbackCommand;<br /></font><font size="2" face="Verdana">}</font>
<p>7. Add the following callback methods to the class:
<p><font size="2" face="Verdana">private void RetryConnectionCallback(<br />&nbsp;&nbsp; Int32 currentRetryCount, Exception lastException, TimeSpan delay) <br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; Int32 retryCount = currentRetryCount;<br /></font><font size="2" face="Verdana">} </font></p>
<p><font size="2" face="Verdana">private void RetryCallbackCommand(<br />&nbsp; Int32 currentRetryCount, Exception lastException, TimeSpan delay) <br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; Int32 retryCount = currentRetryCount;<br /></font><font size="2" face="Verdana">} </font>
<p>8. Add the following method, retrieving the session tracing Id, to the class:
<p><font size="2" face="Verdana">public String GetSessionTracingId()<br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp; String commandText = &#8220;SELECT CONVERT(NVARCHAR(36), CONTEXT_INFO())&#8221;; </font>
<p><font size="2" face="Verdana">&nbsp; String sessionTracingId; </font>
<p><font size="2" face="Verdana">&nbsp; using (ReliableSqlConnection connection = new ReliableSqlConnection(connectionString))<br />&nbsp; </font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp; connection.Open(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp; using (SqlCommand sqlCommand = connection.CreateCommand())<br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sqlCommand.CommandText = commandText; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sessionTracingId = sqlCommand.ExecuteScalarWithRetry() as String;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }</font><font size="2" face="Verdana">&nbsp;&nbsp; </font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp; return sessionTracingId;<br /></font><font size="2" face="Verdana">} </font></p>
<p>9. Add the following method, creating the <em>Writer</em> table, to the class:
<p><font size="2" face="Verdana">public void CreateTable() <br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp; String commandText = </font><font size="2" face="Verdana">@&#8221;CREATE TABLE Writer ( <br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Id int PRIMARY KEY NOT NULL, <br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Name nvarchar(20) NOT NULL, <br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">CountBooks int NULL)&#8221;; </font>
<p><font size="2" face="Verdana">&nbsp; using (ReliableSqlConnection connection =<br />&nbsp;&nbsp;&nbsp; new ReliableSqlConnection(connectionString, connectionRetryPolicy)) <br /></font><font size="2" face="Verdana">&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">connection.Open();</font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">using (SqlCommand sqlCommand = connection.CreateCommand()) <br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sqlCommand.CommandText = commandText; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sqlCommand.ExecuteNonQueryWithRetry(); <br />&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">}<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">} </font></p>
<p>10. Add the following method, dropping the <em>Writer</em> table, to the class:
<p><font size="2" face="Verdana">public void DropTable()<br /></font><font size="2" face="Verdana">{ <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; String commandText = &#8220;DROP TABLE Writer&#8221;; </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; using (ReliableSqlConnection connection = new ReliableSqlConnection(connectionString)) <br />&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">connection.Open(connectionRetryPolicy); </font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (SqlCommand sqlCommand = connection.CreateCommand()) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sqlCommand.CommandText = commandText;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">sqlCommand.ExecuteNonQueryWithRetry(commandRetryPolicy);<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">} </font></p>
<p>11. Add the following method, querying the <em>Writer</em> table, to the class:
<p><font size="2" face="Verdana">public void QueryTable()<br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; String commandText = &#8220;SELECT * FROM Writer&#8221;; </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; using (ReliableSqlConnection connection =<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new ReliableSqlConnection(connectionString, connectionRetryPolicy, commandRetryPolicy))<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; { <br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connection.Open(); </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (SqlCommand sqlCommand = new SqlCommand(commandText, connection.Current)) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{ <br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (IDataReader reader = connection.ExecuteCommand&lt;IDataReader&gt;(sqlCommand))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{ <br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Int32 idColumn = reader.GetOrdinal(&#8220;Id&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Int32 nameColumn = reader.GetOrdinal(&#8220;Name&#8221;); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Int32 countBooksColumn = reader.GetOrdinal(&#8220;CountBooks&#8221;);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">while (reader.Read()) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Int32 id = (Int32)reader[idColumn];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">String name = reader[nameColumn] as String;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Int32? countBooks = reader[countBooksColumn] as Int32?;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">}<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">}</font>
<p>12. Add the following method, inserting rows in the <em>Writer</em> table, to the class:
<p><font size="2" face="Verdana">public Int32 InsertRows() <br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; String commandText = </font><font size="2" face="Verdana">@&#8221;INSERT INTO Writer </font><font size="2" face="Verdana">(Id, Name, CountBooks)<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp; VALUES<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1, N&#8217;Cervantes&#8217;, 2),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">(2, N&#8217;Smollett&#8217;, null),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">(3, &#8216;Beyle&#8217;, 4)&#8221;; </font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp; Int32 rowsAffected;<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">using (SqlConnection connection = new SqlConnection(connectionString)) <br />&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">connection.OpenWithRetry(); </font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (SqlCommand sqlCommand = new SqlCommand(commandText, connection)) <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rowsAffected = sqlCommand.ExecuteNonQueryWithRetry();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">}<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }</font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp; return rowsAffected;<br /></font><font size="2" face="Verdana">} </font></p>
<p><font size="2" face="Verdana"><font size="3" face="Georgia">13. Add the following method, updating a row in the <em>Writer</em> table, to the class:</font> </font>
<p><font size="2" face="Verdana">public Int32 UpdateRow()<br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; RetryPolicy exponentialRetryPolicy = RetryPolicy.DefaultExponential; </font></p>
<p><font size="2" face="Verdana">&nbsp;&nbsp; String commandText = </font><font size="2" face="Verdana">@&#8221;UPDATE Writer<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">SET Name=@Name<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">WHERE Id=3&#8243;; </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; Int32 rowsAffected;<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">using (SqlConnection connection = new SqlConnection(connectionString))<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">connection.OpenWithRetry(exponentialRetryPolicy); </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; using (SqlCommand sqlCommand = new SqlCommand(commandText, connection))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">SqlParameter sqlParameter = new SqlParameter()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">ParameterName = &#8220;@Name&#8221;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Value = &#8220;Stendhal&#8221;,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">SqlDbType = SqlDbType.NVarChar,<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">Size = 20<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">}; </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sqlCommand.Parameters.Add(sqlParameter); </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rowsAffected = sqlCommand.ExecuteNonQueryWithRetry(exponentialRetryPolicy);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font><font size="2" face="Verdana">}<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; }<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; return rowsAffected;<br /></font><font size="2" face="Verdana">} </font></p>
<p><font size="2" face="Verdana"><font size="3" face="Georgia">14. Add the following method, using the methods added earlier, to the class:</font> </font>
<p><font size="2" face="Verdana">public static void UseRetryConnectionExample()<br /></font><font size="2" face="Verdana">{<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; String server = &#8220;SERVER_NAME&#8221;;<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">String database = &#8220;DATABASE_NAME&#8221;;<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">String login = &#8220;LOGIN&#8221;;<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">String password = &#8220;PASSWORD&#8221;; </font>
<p><font size="2" face="Verdana">&nbsp;&nbsp; RetryConnectionExample example = new RetryConnectionExample(<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; server, database, login, password);<br />&nbsp;&nbsp; </font><font size="2" face="Verdana">example.GetSessionTracingId();<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.CreateTable(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.InsertRows(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.QueryTable(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.UpdateRow(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.QueryTable(); <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; example.DropTable(); <br /></font><font size="2" face="Verdana">} </font>
<p>15. Add the following Transient Fault Handling Framework configuration to the <em>app.config</em> file for the project:
<p><font size="2" face="Verdana">&lt;configSections&gt;<br /></font><font size="2" face="Verdana">&nbsp;&nbsp; &lt;section name=&#8221;RetryPolicyConfiguration&#8221; <br />type=&#8221;Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling.Configuration.RetryPolicyConfigurationSettings,<br />Microsoft.AppFabricCAT.Samples.Azure.TransientFaultHandling&#8221;/&gt;<br /></font><font size="2" face="Verdana">&lt;/configSections&gt; </font>
<p><font size="2" face="Verdana">&lt;RetryPolicyConfiguration defaultPolicy=&#8221;FixedIntervalDefault&#8221;&gt; <br /></font><font size="2" face="Verdana">&nbsp;&nbsp; &lt;add name=&#8221;FixedIntervalDefault&#8221; maxRetryCount=&#8221;10&#8243; retryInterval=&#8221;100&#8243;/&gt;<br /></font><font size="2" face="Verdana">&lt;/RetryPolicyConfiguration&gt; </font><br />
<h4><b>How it works&#8230;</b></h4>
<p>In Step 1, we modify the output target of the project to make it consistent with the requirements of the Transient Fault Handling Framework. In Step 2, we add references to the Transient Fault Handling Framework assembly and to the System.configuration assembly used to access the Transient Fault Handling configuration in the <em>app.config</em> file.
<p>In Steps 3 and 4, we set up the class. In Step 5, we add private members for the connection string and two <em>RetryPolicy</em> instances. In the constructor, we add in Step 6, we initialize the connection string using a <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnectionstringbuilder.aspx">SqlConnectionStringBuilder</a> instance. Configuring a connection string for SQL Azure is precisely the same as for Microsoft SQL Server apart from the way in which the <em>DataSource</em> is specified—with the fully qualified host name. We turn encryption on, as this is required, and set <em>TrustServerCertificate</em> to false, so that the server certificate is validated. Instead of building the connection string like this, we could have loaded it from a configuration file.
<p>For demonstration purposes, we initialize the <em>RetryPolicy</em> private members using different techniques. We create the <em>connectionRetryPolicy</em> member directly by providing initialization values in its constructor. We associate the <em>RetryOccurred</em> callback method with the <em>connectionRetryPolicy</em> member. We create the <em>commandRetryPolicy</em> member by retrieving a <em>FixedIntervalDefault</em> policy from the <em>app.config</em> file. We associate the <em>RetryOccurred</em> callback method with the <em>commandRetryPolicy</em> member. In both cases, we use <em>SqlAzureTransientErrorDetectionStrategy</em> to identify transient errors. This compares an error with a list of pre-defined transient errors.
<p>In Step 7, we add two <em>RetryOccurred</em> callback methods the class. These have a trivial implementation that in a real application could be replaced by logging that a retry had occurred.
<p>In Step 8, we create and open a <em>ReliableSqlConnection</em> which we use to create a <a href="http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.aspx">SqlCommand</a>. The connection is closed automatically when we exit the using block. We use <em>SqlCommand</em> to retrieve the session tracing ID for the connection. This is a GUID, identifying a particular connection, which can be provided to SQL Azure Support when its help is sought in debugging a problem. We use the default <em>RetryPolicy</em> when we open the connection and when we invoke the <em>ExecuteScalarWithRetry()</em> extension method. Note that the default <em>RetryPolicy</em> identifies all errors as being transient.
<p>In Step 9, we invoke a CREATE TABLE operation on SQL Azure to create a table named <em>Writer</em>. The table has three columns: the Primary Key is the Id column; the remaining columns store the name of a writer and the number of books they wrote. We use the <em>connectionRetryPolicy</em>, configured in the constructor, when the connection is opened and the default <em>RetryPolicy</em> when we invoke the <em>ExecuteNonQueryWithRetry()</em> extension method.
<p>In Step 10, we invoke a DROP TABLE operation on SQL Azure to drop the Writer table. We use the default <em>RetryPolicy</em> when the connection is opened and the <em>commandRetryPolicy</em> when we invoke the <em>ExecuteNonQueryWithRetry()</em> extension method.
<p>In Step 11, we retrieve all rows from the <em>Writer</em> table and then iterate over them to examine the content of each column. We use the <em>connectionRetryPolicy</em> when the connection is opened and the <em>commandRetryPolicy</em> when we invoke the <em>ExecuteComman&lt;IDataReader&gt;()</em> extension method.
<p>We insert three rows in the <em>Writer</em> table in Step 12. We invoke the<em> OpenWithRetry()</em> and <em>ExecuteNonQueryWithRetry()</em> extension methods to use the default <em>RetryPolicy</em> when we open and use the connection respectively. In Step 13, we use the same extension methods when we update a row in the Writer table. In this case, however, we parameterize them, so that we use the <em>DefaultExponential</em> retry policy when we open and use the connection. This default policy identifies all errors as transient.
<p>In Step 14, we add a method that invokes the methods added earlier. We need to provide the server name, the database name, the login, and the password.
<p>In Step 15, we add the configuration used to configure a <em>RetryPolicy</em> instance in Step 6. In doing so, we need to add a <em>configSection</em> element specifying the assembly used to access the configuration and then we add a <em>RetryPolicyConfiguration</em> element in which we specify a configuration we name <em>FixedIntervalDefault</em>.
<p>Note that, with an appropriately configured connection string, all the code in this recipe can be run against Microsoft SQL Server—with the exception of the retrieval of the session tracing ID in Step 8.<br />
<h4><b>There&#8217;s more&#8230;</b></h4>
<p>The Transient Fault Handling Framework for Azure Storage, Service Bus, and SQL Azure can also be used for retrying operations against the Windows Azure Storage Service and the Windows Azure Service Bus.<br />
<h4><b>See also</b></h4>
<p>Valery Mizonov (@TheCATerminator) of the Windows Azure AppFabric Customer Advisory Team has written a blog post on <a href="http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/">Best practices for handling transient conditions in SQL Azure client applications</a>. He explains how to use the Transient Fault Handling Framework. The post is available at the following URL:
<p><a title="http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/" href="http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/">http://windowsazurecat.com/2010/10/best-practices-for-handling-transient-conditions-in-sql-azure-client-applications/</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/190/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/190/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/190/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=190&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/09/28/handling-transient-connection-failures-in-sql-azure/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Windows Azure AppFabric Service Bus Brokered Messaging</title>
		<link>http://convective.wordpress.com/2011/09/21/windows-azure-appfabric-service-bus-brokered-messaging/</link>
		<comments>http://convective.wordpress.com/2011/09/21/windows-azure-appfabric-service-bus-brokered-messaging/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 08:12:04 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Azure AppFabric]]></category>
		<category><![CDATA[Brokered Messaging]]></category>
		<category><![CDATA[Service Bus]]></category>
		<category><![CDATA[Service Bus Brokered Messaging]]></category>
		<category><![CDATA[Windows Azure AppFabric]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/09/21/windows-azure-appfabric-service-bus-brokered-messaging/</guid>
		<description><![CDATA[At Build 2011, Microsoft released the Windows Azure AppFabric Service Bus Brokered Messaging feature which has been previewed in the AppFabric Labs environment over the last few months. Service Bus Brokered Messaging provides a sophisticated publish/subscribe mechanism supporting disconnected communication &#8230; <a href="http://convective.wordpress.com/2011/09/21/windows-azure-appfabric-service-bus-brokered-messaging/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=187&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>At Build 2011, Microsoft released the Windows Azure AppFabric Service Bus Brokered Messaging feature which has been previewed in the AppFabric Labs environment over the last few months. Service Bus Brokered Messaging provides a sophisticated publish/subscribe mechanism supporting disconnected communication between many producers and many consumers. This capability can be used to support load leveling among one or more producers and load balancing among one or more consumers, thereby supporting increased scalability of a service.</p>
<p>Clemens Vasters (@clemensv) <a href="http://blogs.msdn.com/b/windowsazure/archive/2011/09/16/the-service-bus-september-2011-release.aspx">announced</a> the release on the Windows Azure Team <a href="http://blogs.msdn.com/b/windowsazure/">blog</a>. The MSDN documentation for Windows Azure AppFabric v1.5 release, including Brokered Messaging, is <a href="http://msdn.microsoft.com/en-us/library/hh394904.aspx">here</a>. Valery Mizonov (@TheCATerminator), of the Windows Azure <a href="http://windowsazurecat.com/index.php">Customer Advisory Team</a>, has a post on <a href="http://windowsazurecat.com/2011/09/best-practices-leveraging-windows-azure-service-bus-brokered-messaging-api/">Best Practices for Leveraging Windows Azure Service Bus Brokered Messaging API</a>. Rick Garibay (@rickggaribay) has a <a href="http://www.rickgaribay.net/archive/2011/09/14/azure-appfabric-service-bus-brokered-messaging-ga-amp-rude-ctp.aspx">post</a> describing the differences between the preview and release versions that includes links to additional resources. Alan Smith (@alansmith) has a post providing an AppFabric Walkthrough: <a href="http://geekswithblogs.net/asmith/archive/2011/09/16/146920.aspx">Simple Brokered Messaging</a> (1st in a series). He has recently posted an <a href="http://geekswithblogs.net/asmith/archive/2011/10/03/147150.aspx">eBook </a>on Brokered Messaging as well as an <a href="http://geekswithblogs.net/asmith/archive/2011/10/21/147398.aspx">update </a>on deadletter sub-queues. There is also a <a href="http://preps2.wordpress.com/2011/09/17/comparison-of-windows-azure-storage-queues-and-service-bus-queues/">post</a> comparing Windows Azure Storage Queues with AppFabric Service Bus Brokered Messaging.</p>
<p>This post does not cover the WCF bindings and the REST API for Brokered Messaging that are also contained in the release. The post is a replacement for an earlier <a href="http://convective.wordpress.com/2011/06/08/windows-azure-appfabric-service-bus-queues-and-topics/">post</a> describing the preview release of Service Bus Brokered Messaging.</p>
<h3>Intro to Brokered Messaging</h3>
<p>The name <em>brokered messaging</em> is used to distinguish the functionality from <em>direct messaging </em>in which a producer communicates directly with a consumer, and <em>relayed messaging</em> in which a producer communicates with a consumer through a relay. Both direct messaging and relayed messaging are subject to backpressure from the consumer being limited in how fast it can consume messages, and this causes the producer to throttle message production thereby limiting service scalability. By contrast, brokered messaging uses a high-capacity intermediate store to consume and durably store messages which can then be pulled by the consumer. The benefit of this is that the producer and consumer can scale independently of each other since the intermediate message broker buffers any difference in the real-time ability of the producer to send messages and the consumer to receive them.</p>
<p>The Windows Azure AppFabric Service Bus supports two distinct forms of brokered messages</p>
<ul>
<li>Queues</li>
<li>Topics &amp; Subscriptions</li>
</ul>
<p>Queues represent a persistent sequenced buffer into which one or more producers send messages to the tail and one or more consumers compete to receive messages from the head. A queue has a single cursor, pointing to the current message, that is shared among all consumers. This cursor is moved each time a consumer receives a message. Service Bus Queues provide various methods to modify that default handling – including the timed visibility of messages on the queue, the deferral of message processing, and the ability of messages to reappear on the queue.</p>
<p>Topics supports a persistent sequenced buffer into which one or more producers send messages to the tail of the buffer which has multiple heads referred to as subscriptions, each of which receives distinct copies of the messages. One or more consumers compete to receive messages from the head of a subscription. Each subscription has its own cursor that is moved each time a message is retrieved.  A subscription can be filtered so that only a subset of messages are available through it. This provides for functionality where geographically-focused subscriptions contain messages only for particular regions while an auditing subscription contains all the messages.</p>
<h3>TokenProvider Classes</h3>
<p>The AppFabric ServiceBus v1.5 release introduced the following classes, derived from <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.tokenprovider.aspx">TokenProvider</a>, to support authentication with Service Bus Brokered Messaging.</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.samltokenprovider.aspx">SamlTokenProvider</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.sharedsecrettokenprovider.aspx">SharedSecretTokenProvider</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.simplewebtokenprovider.aspx">SimpleWebTokenProvider</a></li>
</ul>
<p>The <em>TokenProvider</em> class creates factory methods to create instances of the various token providers. The factory methods for the <em>SharedSecretTokenProvider</em> supports the creation of a token from the issuer and shared secret for the service bus namespace.</p>
<p>These classes are all in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.aspx">Microsoft.ServiceBus</a> namespace in the Microsoft.ServiceBus.dll assembly.</p>
<h3>NamespaceManager Class</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.namespacemanager.aspx">NamespaceManager</a> and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.namespacemanagersettings.aspx">NamespaceManagerSettings</a> classes are used to manage the Windows Azure AppFabric Service Bus namespace and, more specifically, the rendezvous endpoints used in Brokered Messaging.  It exposes methods supporting the creation and deletion of queues, topics and subscriptions. The <em>NamespaceManagerSettings</em> class exposes the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.namespacemanagersettings.operationtimeout.aspx">OperationTimeout</a> and the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.namespacemanagersettings.tokenprovider.aspx">TokenProvider</a> used with operations performed by an associated <em>NamespaceManager.</em></p>
<p>The <em>NamespaceManager</em> class is declared (in truncated form):</p>
<p><span style="font-family:Verdana;font-size:x-small;">public sealed class NamespaceManager {<br />
    public NamespaceManager(String address, NamespaceManagerSettings settings);<br />
    public NamespaceManager(Uri address, NamespaceManagerSettings settings);<br />
    public NamespaceManager(String address, TokenProvider tokenProvider);<br />
    public NamespaceManager(Uri address, TokenProvider tokenProvider);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public Uri Address { get; }<br />
    public NamespaceManagerSettings Settings { get; }</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public QueueDescription CreateQueue(String path);<br />
    public QueueDescription CreateQueue(QueueDescription description);<br />
    public SubscriptionDescription CreateSubscription(String topicPath, String name, Filter filter);<br />
    public SubscriptionDescription CreateSubscription(String topicPath, String name,<br />
       RuleDescription ruleDescription);<br />
    public SubscriptionDescription CreateSubscription(SubscriptionDescription description,<br />
       RuleDescription ruleDescription);<br />
    public SubscriptionDescription CreateSubscription(String topicPath, String name);<br />
    public SubscriptionDescription CreateSubscription(SubscriptionDescription description,<br />
       Filter filter);<br />
    public SubscriptionDescription CreateSubscription(SubscriptionDescription description);<br />
    public TopicDescription CreateTopic(String path);<br />
    public TopicDescription CreateTopic(TopicDescription description);<br />
    public void DeleteQueue(String path);<br />
    public void DeleteSubscription(String topicPath, String name);<br />
    public void DeleteTopic(String path);<br />
    public QueueDescription GetQueue(String path);<br />
    public IEnumerable&lt;QueueDescription&gt; GetQueues();<br />
    public IEnumerable&lt;RuleDescription&gt; GetRules(String topicPath, String subscriptionName);<br />
    public SubscriptionDescription GetSubscription(String topicPath, String name);<br />
    public IEnumerable&lt;SubscriptionDescription&gt; GetSubscriptions(String topicPath);<br />
    public TopicDescription GetTopic(String path);<br />
    public IEnumerable&lt;TopicDescription&gt; GetTopics();<br />
    public Boolean QueueExists(String path);<br />
    public Boolean SubscriptionExists(String topicPath, String name);<br />
    public Boolean TopicExists(String path);<br />
}</span></p>
<p>The constructors provide various ways of creating a <em>NamespaceManager</em> from a full namespace URI and a token provider, either directly or through a <em>NamespaceManagerSettings</em> instance. There are also asynchronous versions of all the methods.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.servicebusenvironment.aspx">ServiceBusEnvironment</a> class contains some helper methods to create the appropriate namespace URI. For example, the following code creates a shared secret token provider and a service URI &#8211; and uses them to create a <em>NamespaceManager</em> instance:</p>
<p><span style="font-family:Verdana;font-size:x-small;">String serviceNamespace = &#8220;mynamespace&#8221;;<br />
String issuer = &#8220;owner&#8221;;<br />
String issuerKey = &#8220;base64-encoded key&#8221;;</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(<br />
   issuer, issuerKey);<br />
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri(&#8220;sb&#8221;, serviceNamespace,<br />
   String.Empty);<br />
NamespaceManager namespaceManager = new NamespaceManager(serviceUri, tokenProvider);</span></p>
<p>The <em>NamespaceManager</em> class provides an extensive set of methods supporting the management of queues, topics and subscriptions – including the creation, deletion and existence checking of them. It also provides methods allowing for the retrieval of the properties of either a specific queue, topic and subscription, or all of each type. Each of these methods is available in both synchronous and asynchronous versions.</p>
<p>The following example uses a <em>NamespaceManager</em> instance to create a queue asynchronously, and then synchronously a topic and an associated subscription.</p>
<p><span style="font-family:Verdana;font-size:x-small;">IAsyncResult iAsyncResult = namespaceManager.BeginCreateQueue(<br />
    &#8220;myqueue&#8221;,<br />
    (result) =&gt;<br />
    {<br />
        namespaceManager.EndCreateQueue(result);<br />
    },<br />
    null);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">TopicDescription topicDescription = namespaceManager.CreateTopic(&#8220;mytopic&#8221;);<br />
SubscriptionDescription subscriptionDescription =<br />
   namespaceManager.CreateSubscription(topicDescription.Path, &#8220;mysubscription&#8221;);<br />
</span></p>
<p>The delete and existence-checking methods are invoked similarly to the create methods.</p>
<p>Note that service scalability can be significantly improved by using asynchronous calls rather than blocking synchronous calls. This is particularly true when receiving messages from queues and subscriptions. For clarity, this post primarily uses synchronous calls because it is easier to understand what is going on. However, the Valery Mizonov post on <a href="http://windowsazurecat.com/2011/09/best-practices-leveraging-windows-azure-service-bus-brokered-messaging-api/">Best Practices for Leveraging Windows Azure Service Bus Brokered Messaging API</a> has an extensive discussion on the robust use of asynchronous calls.</p>
<p>Note that other than to avoid namespace collisions no knowledge of how the namespace is allocated to queues, topics and subscriptions is needed when using the Brokered Messaging API. However, for completeness with a service named <em>myservice</em>, a queue named <em>myqueue</em>, a topic named <em>mytopic</em> and a subscription named <em>mysubscription</em> the following show <a href="http://msdn.microsoft.com/en-us/library/hh367521.aspx">examples</a> of the full address for a queue, a topic and a subscription respectively:</p>
<ul>
<li>https://myservice.windows.net/myqueue</li>
<li>https://myservice.windows.net/mytopic</li>
<li>https://myservice.windows.net/mytopic/subscriptions/mysubscription</li>
</ul>
<h3>QueueDescription, TopicDescription and SubscriptionDescription</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.aspx">QueueDescription</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicdescription.aspx">TopicDescription</a>  and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptiondescription.aspx">SubscriptionDescription</a> classes are used with the <em>NamespaceManager</em> factory methods to parameterize the creation of queues, topics and subscriptions. It is interesting to look at the properties of these classes since they provide a direct way of understanding the functionality exposed through queues, topics and subscriptions. In particular, when displayed in tabular form it becomes immediately apparent which properties affect message sending and which affect message retrieval.</p>
<table width="400" border="1" cellspacing="0" cellpadding="2">
<tbody>
<tr>
<td valign="top" width="100"><strong>Property</strong></td>
<td valign="top" width="100"><strong>Queue</strong></td>
<td valign="top" width="100"><strong>Topic</strong></td>
<td valign="top" width="100"><strong>Subscription</strong></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">DefaultMessageTimeToLive</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">DuplicateDetectionHistoryTimeWindow</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">EnableBatchedOperations</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">EnableDeadLetteringOnFilterEvaluationExceptions</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">EnableDeadLetteringOnMessageExpiration</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">LockDuration</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">MaxDeliveryCount</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">MaxSizeInMegabytes</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">MessageCount</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">Name</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">Path</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">RequiresDuplicateDetection</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">RequiresSession</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">SizeInBytes</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get</span></td>
<td valign="top" width="100"><span style="font-size:x-small;">get</span></td>
<td valign="top" width="100"> </td>
</tr>
<tr>
<td valign="top" width="100"><span style="font-size:x-small;">TopicPath</span></td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"> </td>
<td valign="top" width="100"><span style="font-size:x-small;">get/set</span></td>
</tr>
</tbody>
</table>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.defaultmessagetimetolive.aspx">DefaultMessageTimeToLive</a> specifies the default time to live for a message. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.duplicatedetectionhistorytimewindow.aspx">DuplicateDetectionHistoryTimeWindow</a> specifies the default time window for duplicate message detection. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.enablebatchedoperations.aspx">EnableBatchOperations</a> specifies whether server-side batch operations are enabled. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptiondescription.enabledeadletteringonfilterevaluationexceptions.aspx">EnableDeadLetteringOnFilterEvaluationExceptions</a> specifies whether messages encountering filter-evaluation exceptions on a subscription are sent to the dead letter subqueue. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.enabledeadletteringonmessageexpiration.aspx">EnableDeadLetteringOnMessageExpiration</a> specifies whether messages which have reached their time-to-live are sent to the dead letter subqueue. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.lockduration.aspx">LockDuration</a> specifies the default value for the lock duration when a message is retrieved using the <em>PeekLock</em> receive mode.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.maxdeliverycount.aspx">MaxDeliveryCount</a> specifies the maximum number of<br />
delivery attempts before a message is sent to the dead letter subqueue. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.maxsizeinmegabytes.aspx">MaxSizeInMegabytes</a> specifies the maximum size in megabytes of the queue. Note that the current quotas allow for queues up to 5 GB. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.messagecount.aspx">MessageCount</a> returns the number of messages in the queue or subscription. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.name.aspx">Name</a> specifies the name of a subscription. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.path.aspx">Path</a> specifies the name of a queue or topic. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.requiresduplicatedetection.aspx">RequiresDuplicateDetection</a> specifies whether the queue or topic implements duplicate detection. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.requiressession.aspx">RequiresSession</a> specifies whether a <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesession.aspx">MessageSession</a> receiver must be used to retrieve messages from the queue or subscription. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.sizeinbytes.aspx">SizeInBytes</a> returns the size of the queue or topic. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptiondescription.topicpath.aspx">TopicPath</a> specifies the topic path for a subscription.</p>
<h3>BrokeredMessage</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.aspx">BrokeredMessage</a> class represents a brokered message to be sent to a queue or topic or retrieved from a queue or subscription. It is declared:</p>
<p><span style="font-family:Verdana;font-size:x-small;">public sealed class BrokeredMessage : IXmlSerializable, IDisposable {<br />
public BrokeredMessage(Object serializableObject, XmlObjectSerializer serializer);<br />
public BrokeredMessage(Stream messageBodyStream, Boolean ownsStream);<br />
public BrokeredMessage();<br />
public BrokeredMessage(Object serializableObject);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">public String ContentType { get; set; }<br />
public String CorrelationId { get; set; }<br />
public Int32 DeliveryCount { get; }<br />
public DateTime EnqueuedTimeUtc { get; }<br />
public DateTime ExpiresAtUtc { get; }<br />
public String Label { get; set; }<br />
public DateTime LockedUntilUtc { get; }<br />
public Guid LockToken { get; }<br />
public String MessageId { get; set; }<br />
public IDictionary&lt;String,Object&gt; Properties { get; }<br />
public String ReplyTo { get; set; }<br />
public String ReplyToSessionId { get; set; }<br />
public DateTime ScheduledEnqueueTimeUtc { get; set; }<br />
public Int64 SequenceNumber { get; }<br />
public String SessionId { get; set; }<br />
public Int64 Size { get; }<br />
public TimeSpan TimeToLive { get; set; }<br />
public String To { get; set; }</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">public void Abandon();<br />
public IAsyncResult BeginAbandon(AsyncCallback callback, Object state);<br />
public IAsyncResult BeginComplete(AsyncCallback callback, Object state);<br />
public IAsyncResult BeginDeadLetter(AsyncCallback callback, Object state);<br />
public IAsyncResult BeginDeadLetter(String deadLetterReason,<br />
String deadLetterErrorDescription, AsyncCallback callback, Object state);<br />
public IAsyncResult BeginDefer(AsyncCallback callback, Object state);<br />
public void Complete();<br />
public void DeadLetter();<br />
public void DeadLetter(String deadLetterReason, String deadLetterErrorDescription);<br />
public void Defer();<br />
public void EndAbandon(IAsyncResult result);<br />
public void EndComplete(IAsyncResult result);<br />
public void EndDeadLetter(IAsyncResult result);<br />
public void EndDefer(IAsyncResult result);<br />
public T GetBody&lt;T&gt;();<br />
public T GetBody&lt;T&gt;(XmlObjectSerializer serializer);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">public void Dispose();<br />
public override String ToString();<br />
XmlSchema IXmlSerializable.GetSchema();<br />
void IXmlSerializable.ReadXml(XmlReader reader);<br />
void IXmlSerializable.WriteXml(XmlWriter writer);<br />
}</span></p>
<p>The <em>BrokeredMessage</em> class exposes several constructors as well as various methods to manage methods received using the <em>PeekLock</em> receive mode:</p>
<ul>
<li><span style="font-family:Verdana;font-size:x-small;">Abandon() to have the queue or subscription unlock the message and make it visible to consumers.</span> </li>
<li><span style="font-family:Verdana;font-size:x-small;">Complete() to have the queue or subscription delete the message</span></li>
<li><span style="font-family:Verdana;font-size:x-small;">DeadLetter() to have the queue or subscription transfer the message to the dead letter subqueue.</span></li>
<li><span style="font-family:Verdana;font-size:x-small;">Defer() to have the queue or subscription defer the message for subsequent processing.</span></li>
</ul>
<p>The dead letter subqueue is used as a store where messages can be stored for out-of-band processing. This is typically used when there is a problem with the message which needs to be investigated outside normal processing. Note that a deferred message can only be received by the explicit provision of the sequence number for the message. Consequently, it is essential to save the sequence number for later use before invoking Defer().</p>
<p>These methods exist in both synchronous and asynchronous form. The <em>BrokeredMessage</em> class also exposes various accessor methods to the message body. The <em>BrokeredMessage</em> class has several properties which help describe some of the features of brokered messaging.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.contenttype.aspx">ContentType</a> is an application-specific value that can be used to specify the type of data in the message. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.correlationid.aspx">CorrelationId</a> is used with the <em>CorrelationFilter</em> to correlate two-way messaging between the producer and consumer. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.deliverycount.aspx">DeliveryCount</a> specifies the number of times the message has been delivered to a consumer. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.enqueuedtimeutc.aspx">EnqueuedTimeUtc</a> specifies when the message was sent to the queue or topic. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.expiresatutc.aspx">ExpiresAtUtc</a> specifies when the message expires on the queue or subscription. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.label.aspx">Label</a> is an application-specific label for the message. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.lockeduntilutc.aspx">LockedUntilUtc</a> specifies the unlock time for a message received using the <em>PeekLock</em> receive mode. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.lockeduntilutc.aspx">LockToken</a> specifies the lock token of the message received using the <em>PeekLock</em> receive mode. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.messageid.aspx">MessageId</a> is an application-specific identifier for a message.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.properties.aspx">Properties</a> collection contains a set of application-specific properties which can be used, instead of the message body, to pass message content. The <em>Properties</em> collection is also accessible during the rule processing for message retrieval from a subscription. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.replyto.aspx">ReplyTo</a> contains the name of a queue to which any reply should be sent. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.replytosessionid.aspx">ReplyToSessionId</a> specifies a session the message should be replied to. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.scheduledenqueuetimeutc.aspx">ScheduledEnqueueTimeUtc</a> specifies a future time when a new message will become visible on the queue or topic. By default, a message becomes visible immediately. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.sequencenumber.aspx">SequenceNumber</a> is a Service Bus provided unique identifier for the message.<br />
The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.sessionid.aspx">SessionId</a> identifies a session, if any, that the message belongs to.<br />
<a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.size.aspx">Size</a> specifies the size of the message in bytes. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.timetolive.aspx">TimeToLive</a> specifies the time-to-live of the message after which it is either deleted or moved to the dead letter subqueue. With regard to <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.to.aspx">To</a>, your guess is as good as mine.</p>
<h3>ReceiveMode</h3>
<p>A consumer can receive a message in one of two <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.receivemode.aspx">receive modes</a>: <em>PeekLock</em> (the default) and <em>ReceiveAndDelete</em>. In <em>PeekLock</em> receive mode, a consumer receives the message which remains invisible on the queue until the consumer either abandons the message (physically or through a timeout) and the message once again becomes visible or deletes the message on successful completion of processing. This mode supports <em>at least once</em> processing, since each message is consumed one or more times. In <em>ReceiveAndDelete</em> mode, a consumer receives the message and it is immediately deleted from the queue. This mode provides for <em>at most once</em> processing since each message is consumed at most once. A message can be lost in <em>ReceiveAndDelete</em> mode if the consumer fails while processing a message.</p>
<h3>MessagingFactory and MessagingClientEntity</h3>
<p>Messages are sent and received using instances of classes in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagecliententity.aspx">MessagingClientEntity</a> hierarchy:</p>
<p><span style="font-family:Verdana;font-size:x-small;"><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagecliententity.aspx">MessagingClientEntity</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagereceiver.aspx">MessageReceiver</a><br />
      </span><span style="font-family:Verdana;font-size:x-small;"><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesession.aspx">MessageSession</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesender.aspx">MessageSender</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagingfactory.aspx">MessagingFactory</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.aspx">QueueClient</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.aspx">SubscriptionClient</a><br />
</span><span style="font-family:Verdana;font-size:x-small;">   <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicclient.aspx">TopicClient</a><br />
</span></p>
<p>The <em>MessagingFactory</em> class contains factory methods that can be used to create a <em>MessagingFactory</em> instance which can then be used to create instances of the <em>MessageReceiver</em>, <em>MessageSender</em>, <em>QueueClient</em>, <em>SubscriptionClient</em> and <em>TopicClient</em> classes. The <em>QueueClient</em> and <em>SubscriptionClient</em> classes expose methods to create <em>MessageSession</em> intances.</p>
<p>The <em>QueueClient</em> class is used to send and receive messages to a queue. The <em>TopicClient</em> class is used to send messages to a topic while the <em>SubscriptionClient</em> class is used to receive messages from a subscription to a topic. The <em>MessageSender</em> class and <em>MessageReceiver</em> classes abstract the sending and receiving functionality so that they can be used against either queues or topics and subscriptions. The <em>MessageSession</em> class exposes functionality allowing queue and subscription receivers to receive related messages as a &#8220;session.&#8221; After some receiver receives a message in a session, all messages in that session are reserved for that receiver.</p>
<h3>QueueClient</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.aspx">QueueClient</a> class is to some extent a superset of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicclient.aspx">TopicClient</a> and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.aspx">SubscriptionClient</a> classes. This is because it has to handle both the sending and receiving of messages. It lacks the functionality related to rules, filters and actions that the <em>SubscriptionClient</em> exposes but sending to a topic is pretty much the same as sending to a queue.</p>
<p>The following is a severely truncated class declaration for the <em>QueueClient</em> class:</p>
<p><span style="font-family:Verdana;font-size:x-small;">public abstract class QueueClient : MessageClientEntity {<br />
    public MessagingFactory MessagingFactory { get; }<br />
    public String Path { get; }<br />
    public Int32 PrefetchCount { get; set; }</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public static String FormatDeadLetterPath(String queuePath);<br />
</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public MessageSession AcceptMessageSession();<br />
    public void Abandon(Guid lockToken);<br />
    public void Complete(Guid lockToken);<br />
    public void Defer(Guid lockToken);<br />
    public void DeadLetter(Guid lockToken);<br />
    public BrokeredMessage Receive();<br />
    public void Send(BrokeredMessage message);<br />
    public ReceiveMode Mode { get; }<br />
}</span></p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.prefetchcount.aspx">PrefetchCount</a> property is a performance enhancement that specifies how many messages should be retrieved BEFORE the first call to Receive(). Note that this can lead to message loss if the consumer fails before completely processing the messages.</p>
<p>The instance methods of the class exist have several overloads, each of which has an associated asynchronous version. <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.acceptmessagesession.aspx">AcceptMessageSession()</a> is used to request the next session (with an overload allowing a specific session to be requested). The returned <em>MessageSession</em> instance can then be used to retrieve sequentially the messages in that session.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.abandon.aspx">Abandon()</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.complete.aspx">Complete()</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.deadletter.aspx">DeadLetter()</a>and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.defer.aspx">Defer()</a> methods have the same meaning as the equivalent methods in the BrokeredMessage class. The difference is that in this case the lock token contained in the message must be provided as a parameter.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.formatdeadletterpath.aspx">FormatDeadLetterPath()</a> method is invoked to get the path for the dead letter subqueue. This path can then be used to create a <em>QueueClient</em> to retrieve messages from the dead letter subqueue.</p>
<p>A produces invokes <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.send.aspx">Send()</a> to send a message to the queue while a consumer invokes <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queueclient.receive.aspx">Receive()</a> to receive a message from the queue. Note that a message received using the <em>ReceiveAndDelete</em> receive mode is deleted immediately from the queue. None of the <em>Abandon()</em>, <em>Complete()</em>, <em>Defer()</em> and <em>DeadLetter()</em> functionality, just described, applies to such a message.</p>
<p>The following code fragment shows messages being sent to two separate queues:</p>
<p><span style="font-family:Verdana;font-size:x-small;">MessagingFactory messagingFactory = MessagingFactory.Create(serviceUri, tokenProvider);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient bodySender = messagingFactory.CreateQueueClient(&#8220;BodyQueue&#8221;);<br />
BrokeredMessage brokeredMessage1 = new BrokeredMessage(&#8220;serializable message body&#8221;);<br />
bodySender.Send(brokeredMessage1);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient propertySender = messagingFactory.CreateQueueClient(&#8220;PropertyQueue&#8221;);<br />
BrokeredMessage brokeredMessage2 = new BrokeredMessage()<br />
{<br />
    Properties = {<br />
        {&#8220;Month&#8221;, &#8220;July&#8221;},<br />
        {&#8220;NumberOfDays&#8221;, 31}<br />
    }<br />
};<br />
propertySender.Send(brokeredMessage2);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">messagingFactory.Close();<br />
messagingFactory = null;</span></p>
<p>These show two different ways of inserting information in a message &#8211; either as serializable content in the message body or as message properties. In the first case, a message containing body text is sent to a queue. In the second case, a message containing a pair of properties is sent to a different queue. These show distinct ways of using messages. Other than being convenient when a message contains only a few properties, the latter becomes essential when using subscriptions since the Service Bus messaging broker can modify message handling based on the value of the message properties. Indeed, it can even modify the values of the properties. This functionality is not available when the actionable content is stored in the message body.</p>
<p>The fragment also shows the closing of the <em>MessagingFactory</em> instance. Each <em>MessagingClientEntity</em> (<em>QueueClient</em>, <em>TopicClient</em>, etc.) gets its own connection and the resources consumed by the connection should be released when no longer needed. This can be done either by invoking <em>Close()</em> on the individual <em>MessagingClientEntity</em> or by invoking close on the <em>MessagingFactory</em> instance, which releases all resources created through the factory instance including any <em>MessagingClientEntity</em> instances created by it.</p>
<p>The following code fragment shows messages being retrieved from two separate queues:</p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient bodyReceiver = messagingFactory.CreateQueueClient(&#8220;BodyQueue&#8221;,<br />
   ReceiveMode.ReceiveAndDelete);<br />
BrokeredMessage brokeredMessage3 = bodyReceiver.Receive();<br />
String messageBody = brokeredMessage3.GetBody&lt;String&gt;();<br />
bodyReceiver.Close();</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient propertyReceiver = messagingFactory.CreateQueueClient(&#8220;PropertyQueue&#8221;);<br />
propertyReceiver.BeginReceive(ReceiveDone, propertyReceiver);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">public static void ReceiveDone(IAsyncResult result)<br />
{<br />
    QueueClient queueClient = result.AsyncState as QueueClient;<br />
    BrokeredMessage brokeredMessage = queueClient.EndReceive(result);<br />
    String messageId = brokeredMessage.MessageId;<br />
    String month = brokeredMessage.Properties["Month"] as String;<br />
    Int32 numberOfDays = (Int32)brokeredMessage.Properties["NumberOfDays"];</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    switch (numberOfDays)<br />
    {<br />
        case 28:<br />
            brokeredMessage.Defer();<br />
            break;<br />
        case 30:<br />
            brokeredMessage.Complete();<br />
            break;<br />
        case 31:<br />
            brokeredMessage.Abandon();<br />
            break;<br />
    }<br />
    queueClient.Close();<br />
}<br />
</span></p>
<p>This sample shows both the synchronous and asynchronous retrieval of messages. In the synchronous case, the actionable content is retrieved from the message body. In the asynchronous case, the actionable content is retrieved from message properties. The property values are then used to select the disposition of the message as deferred, completed or abandoned. Note that this depends on the message receive mode being the default <em>PeekLock</em>. The <em>MessageId</em> needs to be retained for a deferred message since such a message can be retrieved only by <em>MessageId</em>.</p>
<h3>TopicClient</h3>
<p>A <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicclient.aspx">TopicClient</a> is the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagecliententity.aspx">MessageClientEntity</a> used to send messages to a topic. It exposes synchronous and asynchronous versions of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.topicclient.send.aspx">Send()</a> method.</p>
<h3>SubscriptionClient</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.aspx">SubscriptionClient</a> class us used to handle messages received from a subscription. <em>SubscriptionClient</em> is declared (in truncated form):</p>
<p><span style="font-family:Verdana;font-size:x-small;">public abstract class SubscriptionClient : MessageClientEntity {<br />
    public MessagingFactory MessagingFactory { get; }<br />
    public String Name { get; }<br />
    public Int32 PrefetchCount { get; set; }<br />
    public String TopicPath { get; }</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public IAsyncResult BeginAddRule(String ruleName, Filter filter, AsyncCallback callback,<br />
       Object state);<br />
    public IAsyncResult BeginAddRule(RuleDescription description, AsyncCallback callback,<br />
       Object state);<br />
    public IAsyncResult BeginRemoveRule(String ruleName, AsyncCallback callback,<br />
       Object state);<br />
    public void EndAddRule(IAsyncResult result);<br />
    public void EndRemoveRule(IAsyncResult result);<br />
    public static String FormatDeadLetterPath(String topicPath, String subscriptionName);<br />
    public static String FormatSubscriptionPath(String topicPath, String subscriptionName);<br />
    public void RemoveRule(String ruleName);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">    public IAsyncResult BeginAcceptMessageSession(AsyncCallback callback,<br />
       Object state);<br />
    public IAsyncResult BeginAcceptMessageSession(String sessionId, AsyncCallback callback,<br />
       Object state);<br />
    public IAsyncResult BeginAcceptMessageSession(TimeSpan serverWaitTime,<br />
       AsyncCallback callback, Object state);<br />
    public IAsyncResult BeginAcceptMessageSession(String sessionId, TimeSpan serverWaitTime,<br />
       AsyncCallback callback, Object state);<br />
    public MessageSession EndAcceptMessageSession(IAsyncResult result);<br />
    public IAsyncResult BeginAbandon(Guid lockToken, AsyncCallback callback, Object state);<br />
    public void EndAbandon(IAsyncResult result);<br />
    public IAsyncResult BeginComplete(Guid lockToken, AsyncCallback callback, Object state);<br />
    public void EndComplete(IAsyncResult result);<br />
    public IAsyncResult BeginDefer(Guid lockToken, AsyncCallback callback, Object state);<br />
    public void EndDefer(IAsyncResult result);<br />
    public IAsyncResult BeginDeadLetter(Guid lockToken, AsyncCallback callback, Object state);<br />
    public IAsyncResult BeginDeadLetter(Guid lockToken, String deadLetterReason,<br />
       String deadLetterErrorDescription, AsyncCallback callback, Object state);<br />
    public void EndDeadLetter(IAsyncResult result);<br />
    public IAsyncResult BeginReceive(AsyncCallback callback, Object state);<br />
    public IAsyncResult BeginReceive(TimeSpan serverWaitTime, AsyncCallback callback,<br />
       Object state);<br />
    public IAsyncResult BeginReceive(Int64 sequenceNumber, AsyncCallback callback,<br />
       Object state);<br />
    public BrokeredMessage EndReceive(IAsyncResult result);<br />
    public ReceiveMode Mode { get; }<br />
}</span></p>
<p>The Begin/End asynchronous pairs of methods have equivalent synchronous methods. The Windows Azure AppFabric Service Bus team is serious about wanting us to do everything asynchronously. Much of the exposed functionality is familiar from the receive capability of a <em>QueueClient</em> – <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.acceptmessagesession.aspx">AcceptMessageSession(),</a> <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.abandon.aspx">Abandon()</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.complete.aspx">Complete(),</a> <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.deadletter.aspx">DeadLetter()</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.defer.aspx">Defer()</a> and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptionclient.receive.aspx">Receive()</a>.</p>
<p>The novel functionality exposed by a <em>SubscriptionClient</em> is that related to rules used to modify the behavior of a subscription. Note that this affects the subscription NOT the subscription receiver. Any modification to the rules using these methods affect only those messages sent to the associated topic after the change. I&#8217;m not convinced that this functionality should be in SubscriptionClient as well as the NamespaceManager since the methods affect the subscription not the SubscriptionClient. As it is care must be taken when there is more than one rule for a subscription since a message can be received more than once if it satisfies more than one rule on the subscription.</p>
<h3>Rules, Filters and Actions</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.ruledescription.aspx">RuleDescription</a> class associates a rule name with a <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.filter.aspx">Filter</a> and an optional <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.ruleaction.aspx">RuleAction</a>. The default Filter for a <em>RuleDescription</em> is the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.truefilter.aspx">TrueFilter</a> which always evaluates to true. A <em>Filter</em> is used to filter the messages, based on the values of the message properties, that a subscription handles for a topic. A message passes the filter when it evaluates to true. <em>RuleAction</em> is used to modify the properties of a message when it is received through the subscription. Rules significantly enhance the power of a subscription over a simple queue in that different filter and rule actions can be used for different subscriptions against the same topic. This allows different consumers to have very different views of the messages sent to the topic. Note that a rule does not need to have an associated <em>RuleAction</em>.</p>
<p>There are several <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.filter.aspx">Filter</a> classes in the following hierarchy:</p>
<p><span style="font-family:Verdana;font-size:x-small;">Filter<br />
    CorrelationFilter<br />
    FalseFilter<br />
    SqlFilter<br />
    TrueFilter</span></p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.correlationfilter.aspx">CorrelationFilter</a> provides a filter on the value of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.correlationid.aspx">CorrelationId</a> of a message. This filter is intended to be used when correlating a reply message from a consumer to a producer. A reply message is put on a reply queue with the associated <em>CorrelationId</em>, and the original producer can use a <em>CorrelationFilter</em> on this queue to receive a response to a message it sent. The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.falsefilter.aspx">FalseFilter</a> always fails so that no message is received through a subscription with a <em>FalseFilter</em>. A <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.truefilter.aspx">TrueFilter</a> always succeeds so that all messages are received through a subscription with a <em>TrueFilter</em>. A <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.sqlfilter.aspx">SqlFilter</a> supports a simple <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.sqlfilter.sqlexpression.aspx">SQL-92 style syntax</a> that can be used to filter messages depending on the property values.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.ruleaction.aspx">RuleAction</a> classes have the following hierarchy:</p>
<p><span style="font-family:Verdana;font-size:x-small;">RuleAction<br />
    SqlRuleAction</span></p>
<p><a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.sqlruleaction.aspx">SqlRuleAction</a> supports a simple <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.sqlruleaction.sqlexpression.aspx">SQL-92 style syntax</a> allowing message properties to be modified as they are received through the subscription.</p>
<p>The following code fragment shows the creation of a topic and two subscriptions and the sending of some messages to the topic. Note that a subscription handles only those messages submitted to the topic after the subscription is created. Similarly, a rule only affects messages submitted after the rule is added.</p>
<p><span style="font-family:Verdana;font-size:x-small;">TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(<br />
   issuer, issuerKey);<br />
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri(&#8220;sb&#8221;, serviceNamespace,<br />
   String.Empty);<br />
NamespaceManager namespaceManager = new NamespaceManager(serviceUri, tokenProvider);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">RuleDescription summerRule = new RuleDescription()<br />
{<br />
    Action = new SqlRuleAction(&#8220;SET HavingFun = &#8216;Yes&#8217;&#8221;),<br />
    Filter = new SqlFilter(&#8220;Month = &#8216;June&#8217; OR Month = &#8216;July&#8217; OR [Month] = &#8216;August&#8217;&#8221;),<br />
    Name = &#8220;SummerRule&#8221;<br />
};</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">TopicDescription topicDescription = namespaceManager.CreateTopic(&#8220;WeatherTopic&#8221;);<br />
SubscriptionDescription summerSubscriptionDescription =<br />
   namespaceManager.CreateSubscription(&#8220;WeatherTopic&#8221;, &#8220;WeatherSubscription&#8221;, summerRule);<br />
SubscriptionDescription allSubscriptionDescription =<br />
   namespaceManager.CreateSubscription(&#8220;WeatherTopic&#8221;, &#8220;AllSubscription&#8221;);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">IEnumerable&lt;RuleDescription&gt; rules = namespaceManager.GetRules(<br />
   &#8220;WeatherTopic&#8221;, &#8220;WeatherSubscription&#8221;);<br />
List&lt;RuleDescription&gt; listRules = rules.ToList();</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">MessagingFactory messagingFactory = MessagingFactory.Create(serviceUri, tokenProvider);<br />
TopicClient weatherSender = messagingFactory.CreateTopicClient(&#8220;WeatherTopic&#8221;);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">BrokeredMessage augustMessage = new BrokeredMessage()<br />
{<br />
    Properties = {<br />
        {&#8220;HavingFun&#8221;, &#8220;No&#8221;},<br />
        {&#8220;Month&#8221;, &#8220;August&#8221;},<br />
        {&#8220;NumberOfDays&#8221;, 31}<br />
    }<br />
};<br />
weatherSender.Send(augustMessage);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">BrokeredMessage aprilMessage = new BrokeredMessage()<br />
{<br />
    Properties = {<br />
        {&#8220;HavingFun&#8221;, &#8220;No&#8221;},<br />
        {&#8220;Month&#8221;, &#8220;April&#8221;},<br />
        {&#8220;NumberOfDays&#8221;, 30}<br />
    }<br />
};<br />
weatherSender.Send(aprilMessage);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">BrokeredMessage septemberMessage = new BrokeredMessage()<br />
{<br />
    Properties = {<br />
        {&#8220;HavingFun&#8221;, &#8220;No&#8221;},<br />
        {&#8220;Month&#8221;, &#8220;September&#8221;},<br />
        {&#8220;NumberOfDays&#8221;, 30}<br />
    }<br />
};<br />
weatherSender.Send(septemberMessage);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">weatherSender.Close();<br />
weatherSender = null;</span></p>
<p>This fragment creates a <em>RuleDescription</em> with an action that sets the <em>HavingFun</em> property of a message to <em>Yes</em> if the <em>Month</em> property is <em>June</em>, <em>July</em> or <em>August</em>. A topic and two associated subscriptions are created, one of which is assigned this rule while the other has no filter (and consequently passes all messages). A MessagingFactory is then created which, in turn, creates a TopicClient used to send to the topic three messages with different property values.</p>
<p>The following code fragment shows the retrieval of messages from two different subscriptions to the same topic. The first subscription has a rule that filters the messages and transforms the message properties while the second has rule that passes through all the message and performs no transformations.</p>
<p><span style="font-family:Verdana;font-size:x-small;">SubscriptionClient summerReceiver = messagingFactory.CreateSubscriptionClient(&#8220;WeatherTopic&#8221;, &#8220;WeatherSubscription&#8221;, ReceiveMode.ReceiveAndDelete);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">while (true)<br />
{<br />
    BrokeredMessage brokeredMessage = summerReceiver.Receive(TimeSpan.FromSeconds(1));<br />
    if (brokeredMessage != null)<br />
    {<br />
        String havingFun = brokeredMessage.Properties["HavingFun"] as String;<br />
        String month = brokeredMessage.Properties["Month"] as String;<br />
        brokeredMessage.Dispose();<br />
    }<br />
    else<br />
    {<br />
        break;<br />
    }<br />
}</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">SubscriptionClient allReceiver = messagingFactory.CreateSubscriptionClient(&#8220;WeatherTopic&#8221;, &#8220;AllSubscription&#8221;, ReceiveMode.ReceiveAndDelete);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">while (true)<br />
{<br />
    BrokeredMessage brokeredMessage = allReceiver.Receive(TimeSpan.FromSeconds(1));<br />
    if (brokeredMessage != null)<br />
    {<br />
        String havingFun = brokeredMessage.Properties["HavingFun"] as String;<br />
        String month = brokeredMessage.Properties["Month"] as String;<br />
        brokeredMessage.Dispose();<br />
    }<br />
    else<br />
    {<br />
        break;<br />
    }<br />
}</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">messagingFactory.Close();<br />
messagingFactory = null;</span></p>
<h3>MessageSender and MessageReceiver</h3>
<p>The <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesender.aspx">MessageSender</a> and <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagereceiver.aspx">MessageReceiver</a> classes abstract out the sending and receiving functionality of queues, topics and subscriptions, and can be used instead of the <em>QueueClient</em>, <em>TopicClient</em> and <em>SubscriptionClient</em> classes. The <em>MessageSender</em> class exposes synchronous and asynchronous <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesender.send.aspx">Send()</a> methods while the <em>MessageReceiver</em> class exposes the usual synchronous and asynchronous <a href="http://msdn.microsoft.com/en-us/library/hh181791.aspx">Abandon()</a>, <a href="http://msdn.microsoft.com/en-us/library/hh125074.aspx">Complete()</a>, <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagereceiver.deadletter.aspx">DeadLetter()</a> and <a href="http://msdn.microsoft.com/en-us/library/hh181729.aspx">Defer()</a> methods.</p>
<p>The earlier example using a <em>SubscriptionClient</em> to receive messages can be converted to use a <em>MessageReceiver</em> by replacing the following line:</p>
<p><span style="font-family:Verdana;font-size:x-small;">SubscriptionClient summerReceiver = messagingFactory.CreateSubscriptionClient(<br />
   &#8220;WeatherTopic&#8221;, &#8220;WeatherSubscription&#8221;, ReceiveMode.ReceiveAndDelete);</span></p>
<p>with</p>
<p><span style="font-family:Verdana;font-size:x-small;">MessageReceiver summerReceiver = messagingFactory.CreateMessageReceiver(<br />
   &#8220;WeatherTopic/subscriptions/WeatherSubscription&#8221;, ReceiveMode.ReceiveAndDelete);</span></p>
<p>with <em>WeatherTopic/subscriptions/WeatherSubscription</em> being the full entity path to the <em>WeatherSubscription</em> on <em>WeatherTopic</em>.</p>
<p>UPDATE 10.11.2011</p>
<p>A <em>MessageReceiver</em> can be used to receive messages from a dead letter subqueue for a subscription. For example, the following code fragment changes the earlier example to one that accesses the dead letter subqueue:</p>
<p><span style="font-family:Verdana;font-size:x-small;">SubscriptionClient allReceiver =<br />
   messagingFactory.CreateSubscriptionClient(&#8220;WeatherTopic&#8221;, &#8220;AllSubscription&#8221;,<br />
   ReceiveMode.PeekLock);<br />
String deadLetterPath =<br />
   SubscriptionClient.FormatDeadLetterPath(&#8220;WeatherTopic&#8221;, allReceiver.Name);<br />
MessageReceiver deadLetterReceiver =<br />
   messagingFactory.CreateMessageReceiver(deadLetterPath);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">while (true)<br />
{<br />
    BrokeredMessage brokeredMessage =<br />
       deadLetterReceiver.Receive(TimeSpan.FromSeconds(1));<br />
    if (brokeredMessage != null)<br />
    {<br />
        String havingFun = brokeredMessage.Properties["HavingFun"] as String;<br />
        String month = brokeredMessage.Properties["Month"] as String;<br />
        brokeredMessage.Dispose();<br />
    }<br />
    else<br />
    {<br />
        break;<br />
    }<br />
}</span></p>
<p>In the example, the value of <em>deadLetterPath</em> is:</p>
<p><span style="font-size:x-small;"><span style="font-family:Verdana;">WeatherTopic/Subscriptions/AllSubscription/$DeadLetterQueue</span><br />
</span></p>
<h3>MessageSession</h3>
<p>Service Bus Brokered Messaging supports sessions and session state. A queue or subscription must be set up to support sessions through the use of the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.requiressession.aspx">RequiresSession</a> property in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.aspx">QueueDescription</a> or <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.subscriptiondescription.aspx">SubscriptionDescription</a>. Subsequently, each message may have a SessionId associated with it. The intent is that related messages share a <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.sessionid.aspx">SessionId</a> and comprise a session. A <a href="http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.messagesession.aspx">MessageSession</a> receiver can then be created on the queue or subscription to receive messages with the same <em>SessionId</em>. A persistent session state can be associated with the session. This can be used along with the <em>PeekLock</em> receive mode to implement exactly once processing of messages since the session state can be used to store the current state of processing regardless of any failure in the session consumer.</p>
<p>The <em>MessageSession</em> class is derived from the <em>MessageReceiver</em> class and adds synchronous and asynchronous versions of the following methods to maintain session state:</p>
<p><span style="font-family:Verdana;font-size:x-small;">public Stream GetState();<br />
public void SetState(Stream stream);</span></p>
<p>The following code fragment shows the creation of a session-aware queue and the sending of some messages to it:</p>
<p><span style="font-family:Verdana;font-size:x-small;">TokenProvider tokenProvider = TokenProvider.CreateSharedSecretTokenProvider(<br />
   issuer, issuerKey);<br />
Uri serviceUri = ServiceBusEnvironment.CreateServiceUri(<br />
   &#8220;sb&#8221;, serviceNamespace, String.Empty);<br />
NamespaceManager namespaceManager = new NamespaceManager(serviceUri, tokenProvider);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueDescription queueDescription = new QueueDescription(&#8220;SessionQueue&#8221;)<br />
{<br />
    RequiresSession = true<br />
};<br />
namespaceManager.CreateQueue(queueDescription);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">MessagingFactory messagingFactory = MessagingFactory.Create(serviceUri, tokenProvider);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient sender = messagingFactory.CreateQueueClient(&#8220;SessionQueue&#8221;);</span></p>
<p><span style="font-family:Verdana;font-size:x-small;">for (Int32 i = 1; i &lt; 10; i++)<br />
{<br />
    BrokeredMessage brokeredMessage = new BrokeredMessage()<br />
    {<br />
        MessageId = i.ToString(),<br />
        SessionId = (i % 3).ToString(),<br />
    };<br />
    sender.Send(brokeredMessage);<br />
}<br />
sender.Close();<br />
</span></p>
<p>The novelty in this fragment is in the <em>RequiresSession</em> property for the <em>QueueDescription</em> and the setting of the <em>SessionId</em> on each message.</p>
<p>The following code fragment shows the use of a MessageSession to receive messages in a single session:</p>
<p><span style="font-family:Verdana;font-size:x-small;">QueueClient receiver = messagingFactory.CreateQueueClient(<br />
   &#8220;SessionQueue&#8221;, ReceiveMode.ReceiveAndDelete);<br />
MessageSession sessionReceiver = receiver.AcceptMessageSession();<br />
while ( true )<br />
{<br />
    BrokeredMessage message = sessionReceiver.Receive(TimeSpan.FromSeconds(1));<br />
    if (message == null)<br />
    {<br />
        break;<br />
    }<br />
    String messageId = message.MessageId;<br />
    String sessionId = message.SessionId;<br />
}<br />
messagingFactory.Close();</span></p>
<p>The <em>MessageSession</em> receiver is created by invoking <em>AcceptMessageSession()</em> on the <em>QueueClient</em> receiver. The session receiver receives the first message and then all subsequent messages with the same <em>SessionId</em> as the first one.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/187/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/187/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/187/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=187&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/09/21/windows-azure-appfabric-service-bus-brokered-messaging/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating a Windows Azure hosted service</title>
		<link>http://convective.wordpress.com/2011/08/29/creating-a-windows-azure-hosted-service/</link>
		<comments>http://convective.wordpress.com/2011/08/29/creating-a-windows-azure-hosted-service/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 20:36:58 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Service Management]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Windows Azure Service Management]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/08/29/creating-a-windows-azure-hosted-service/</guid>
		<description><![CDATA[In December 2009, I did a post on the Service Management API in Windows Azure. Over time I became unhappy with part of the post – specifically the use of XML serialization – and was looking for an opportunity to &#8230; <a href="http://convective.wordpress.com/2011/08/29/creating-a-windows-azure-hosted-service/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=186&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In December 2009, I did a post on the <a href="http://convective.wordpress.com/2009/12/19/service-management-api-in-windows-azure/">Service Management API in Windows Azure</a>. Over time I became unhappy with part of the post – specifically the use of XML serialization – and was looking for an opportunity to redo it. I showed an alternate usage pattern in a May 2011 post on the <a href="http://convective.wordpress.com/2011/05/17/sql-azure-management-rest-api/">SQL Azure Management REST API</a>.</p>
<p>I was finally able to revisit the topic in my book, <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">Microsoft Windows Azure Development Cookbook</a>, in which I provide a pretty comprehensive overview of how to use the <a href="http://msdn.microsoft.com/en-us/library/ee460799.aspx">Windows Azure Service Management REST API</a>. There is an entire chapter devoted to the topic – and the publisher, <a href="http://www.packtpub.com/">Packt Publishing</a>, have made the chapter available as a free <a href="http://www.packtpub.com/sites/default/files/2220-chapter-7-managing-hosted-services-with-the-service-management-api.pdf?utm_source=packtpub&amp;utm_medium=free&amp;utm_campaign=pdf">download</a>. It covers the use of the Service Management API for:</p>
<ul>
<li>creating a Windows Azure hosted service
<li>deploying an application into a hosted service
<li>upgrading an application deployed to a hosted service
<li>retrieving the properties of a hosted service
<li>autoscaling with the Windows Azure Service Management REST API
<li>using the Windows Azure Platform PowerShell cmdlets</li>
</ul>
<p>The rest of this post is the section of the book on creating a Windows Azure hosted service. (Apologies for the code formatting here – some day I will learn how to get that right on the blog.)</p>
<h3>Creating a Windows Azure hosted service</h3>
<p>A hosted service is the administrative and security boundary for an application deployed to Windows Azure. The hosted service specifies the service name, a label, and either the Windows Azure datacenter location or the affinity group into which the application is to be deployed. These cannot be changed once the hosted service is created. The service name is the subdomain under cloudapp.net used by the application, and the label is a human-readable name used to identify the hosted service on the Windows Azure Portal.
<p>The Windows Azure Service Management REST API exposes a create hosted service operation. The REST endpoint for the create hosted service operation specifies the subscription ID under which the hosted service is to be created. The request requires a payload comprising an XML document containing the properties needed to define the hosted service, as well as various optional properties. The service name provided must be unique across all hosted services in Windows Azure, so there is a possibility that a valid create hosted service operation will fail with a 409 Conflict error if the provided service name is already in use. As the create hosted service operation is asynchronous, the response contains a request ID that can be passed into a get operation status operation to check the current status of the operation.
<p>In this recipe, we will learn how to use the Service Management API to create a Windows Azure hosted service.<br />
<h4>Getting ready</h4>
<p>The recipes in this chapter use the <em>ServiceManagementOperation</em> utility class to invoke operations against the Windows Azure Service Management REST API. We implement this class as follows:
<p>1. Add a class named <em>ServiceManagementOperation</em> to the project.
<p>2. Add the following assembly reference to the project:
<p>System.Xml.Linq.dll
<p>3. Add the following <em>using</em> statements to the top of the class file: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8a797d72-7ac3-4839-8f38-ca47c7f71ad1" class="wlWriterEditableSmartContent">
<pre style="width:602px;height:96px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">using</span><span style="color:#000000;"> System.Security.Cryptography.X509Certificates;
</span><span style="color:#0000FF;">using</span><span style="color:#000000;"> System.Net;
</span><span style="color:#0000FF;">using</span><span style="color:#000000;"> System.Xml.Linq;
</span><span style="color:#0000FF;">using</span><span style="color:#000000;"> System.IO;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>4. Add the following private members to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6cfdb7c0-388f-4bb4-934a-4ea3ef26ac2c" class="wlWriterEditableSmartContent">
<pre style="width:779px;height:112px;background-color:White;overflow:auto;">
<div><span style="color:#000000;">String thumbprint;
String versionId </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">2011-02-25</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>5. Add the following constructor to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:5a88ed56-fcb8-433f-9107-1c8d0d9b8c67" class="wlWriterEditableSmartContent">
<pre style="width:768px;height:161px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">public</span><span style="color:#000000;"> ServiceManagementOperation(String thumbprint)
{
   </span><span style="color:#0000FF;">this</span><span style="color:#000000;">.thumbprint </span><span style="color:#000000;">=</span><span style="color:#000000;"> thumbprint;
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>6. Add the following method, retrieving an X.509 certificate from the certificate store, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:a6395c8f-f928-4e98-9a33-bd8b5f9e050b" class="wlWriterEditableSmartContent">
<pre style="width:898px;height:464px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">private</span><span style="color:#000000;"> X509Certificate2 GetX509Certificate2( String thumbprint)
{
    X509Certificate2 x509Certificate2 </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">null</span><span style="color:#000000;">; 

    X509Store store </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> X509Store(</span><span style="color:#800000;">&quot;</span><span style="color:#800000;">My</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, StoreLocation.LocalMachine); 

    </span><span style="color:#0000FF;">try</span><span style="color:#000000;">
    {
        store.Open(OpenFlags.ReadOnly); 

        X509Certificate2Collection x509Certificate2Collection </span><span style="color:#000000;">=</span><span style="color:#000000;">
            store.Certificates.Find(
        X509FindType.FindByThumbprint, thumbprint, </span><span style="color:#0000FF;">false</span><span style="color:#000000;">); 

        x509Certificate2 </span><span style="color:#000000;">=</span><span style="color:#000000;"> x509Certificate2Collection[</span><span style="color:#800080;">0</span><span style="color:#000000;">];
    } 

    </span><span style="color:#0000FF;">finally</span><span style="color:#000000;">
    {
        store.Close();
    } 

    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> x509Certificate2;
}
</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>7. Add the following method, creating an <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx">HttpWebRequest</a>, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:1f606314-7775-4918-bf44-8814bed20507" class="wlWriterEditableSmartContent">
<pre style="width:871px;height:236px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">private</span><span style="color:#000000;"> HttpWebRequest CreateHttpWebRequest( Uri uri, String httpWebRequestMethod)
{
    X509Certificate2 x509Certificate2 </span><span style="color:#000000;">=</span><span style="color:#000000;"> GetX509Certificate2(thumbprint);
    HttpWebRequest httpWebRequest </span><span style="color:#000000;">=</span><span style="color:#000000;"> (HttpWebRequest)HttpWebRequest.Create(uri);
    httpWebRequest.Method </span><span style="color:#000000;">=</span><span style="color:#000000;"> httpWebRequestMethod;
    httpWebRequest.Headers.Add(</span><span style="color:#800000;">&quot;</span><span style="color:#800000;">x-ms-version</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, versionId);
    httpWebRequest.ClientCertificates.Add(x509Certificate2);
    httpWebRequest.ContentType </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">application/xml</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> httpWebRequest;
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>8. Add the following method, invoking a GET operation on the Service Management API, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:6f1a2bc0-b865-40d4-8430-7a221ba9c19a" class="wlWriterEditableSmartContent">
<pre style="width:932px;height:338px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">public</span><span style="color:#000000;"> XDocument Invoke(String uri)
{
    XDocument responsePayload;
    Uri operationUri </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> Uri(uri); 

    HttpWebRequest httpWebRequest </span><span style="color:#000000;">=</span><span style="color:#000000;"> CreateHttpWebRequest(operationUri, </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">GET</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">);
    </span><span style="color:#0000FF;">using</span><span style="color:#000000;"> (HttpWebResponse response </span><span style="color:#000000;">=</span><span style="color:#000000;"> (HttpWebResponse)httpWebRequest.GetResponse())
    {
        Stream responseStream </span><span style="color:#000000;">=</span><span style="color:#000000;"> response.GetResponseStream();
        responsePayload </span><span style="color:#000000;">=</span><span style="color:#000000;"> XDocument.Load(responseStream);
    } 

    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> responsePayload; 

}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>9. Add the following method, invoking a POST operation on the Service Management API, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:d5a4ba17-b113-42a0-8c31-39fb01246c8e" class="wlWriterEditableSmartContent">
<pre style="width:907px;height:550px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">public</span><span style="color:#000000;"> String Invoke(String uri, XDocument payload)
{
    Uri operationUri </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> Uri(uri); 

    HttpWebRequest httpWebRequest </span><span style="color:#000000;">=</span><span style="color:#000000;"> CreateHttpWebRequest(operationUri, </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">POST</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">); 

    </span><span style="color:#0000FF;">using</span><span style="color:#000000;"> (Stream requestStream </span><span style="color:#000000;">=</span><span style="color:#000000;"> httpWebRequest.GetRequestStream())
    {
        </span><span style="color:#0000FF;">using</span><span style="color:#000000;"> (StreamWriter streamWriter </span><span style="color:#000000;">=</span><span style="color:#000000;">
        </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> StreamWriter(requestStream,
        System.Text.UTF8Encoding.UTF8))
        {
            payload.Save(streamWriter,
            SaveOptions.DisableFormatting);
        }
    } 

    String requestId;
    </span><span style="color:#0000FF;">using</span><span style="color:#000000;"> (HttpWebResponse response </span><span style="color:#000000;">=</span><span style="color:#000000;"> (HttpWebResponse)httpWebRequest.GetResponse())
    {
        requestId </span><span style="color:#000000;">=</span><span style="color:#000000;"> response.Headers[</span><span style="color:#800000;">&quot;</span><span style="color:#800000;">x-ms-request-id</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">];
    } 

    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> requestId;
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>How it works&#8230; </p>
<p>In steps 1 through 3, we set up the class. In step 4, we add a version ID for service management operations. Note that Microsoft periodically releases new operations for which it provides a new <a href="http://msdn.microsoft.com/en-us/library/gg592580.aspx">version ID</a>, which is usually applicable for operations added earlier. In step 4, we also add a private member for the X.509 certificate thumbprint that we initialize in the constructor we add in step 5. </p>
<p>In step 6, we open the Personal (My) certificate store on the local machine level and retrieve an X.509 certificate identified by thumbprint. If necessary, we can specify the current user level, instead of the local machine level, by using <em>StoreLocation.CurrentUser</em> instead of <em>StoreLocation.LocalMachine</em>. </p>
<p>In step 7, we create an <em>HttpWebRequest</em> with the desired HTTP method type, and add the X.509 certificate to it. We also add various headers including the required <em>x-ms-version</em>. </p>
<p>In step 8, we invoke a GET request against the Service Management API and load the response into an XML document which we then return. In step 9, we write an XML document, containing the payload, into the request stream for an <em>HttpWebRequest</em> and then invoke a POST request against the Service Management API. We extract the request ID from the response and return it. </p>
<h4>How to do it&#8230;</h4>
<p>We are now going to construct the payload required for the create hosted service operation, and then use it when we invoke the operation against the Windows Azure Service Management REST API. We do this as follows: </p>
<p>1. Add a new class named <em>CreateHostedServiceExample</em> to the WPF project. </p>
<p>2. If necessary, add the following assembly reference to the project: </p>
<p>System.Xml.Linq.dll </p>
<p>3. Add the following using statement to the top of the class file: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:0fbda7d9-7946-4081-91d0-368605841e52" class="wlWriterEditableSmartContent">
<pre style="width:392px;height:85px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">using</span><span style="color:#000000;"> System.Xml.Linq;</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>4. Add the following private members to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:37862af1-6fa9-4ec4-a62e-68abd3b7f5c9" class="wlWriterEditableSmartContent">
<pre style="width:815px;height:104px;background-color:White;overflow:auto;">
<div><span style="color:#000000;">XNamespace wa </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">http://schemas.microsoft.com/windowsazure</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
String createHostedServiceFormat </span><span style="color:#000000;">=</span><span style="color:#000000;">
    </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">https://management.core.windows.net/{0}/services/hostedservices</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>5. Add the following method, creating a base-64 encoded string, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:f965666e-88b4-4e22-8782-754c199ffa54" class="wlWriterEditableSmartContent">
<pre style="width:953px;height:110px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">private</span><span style="color:#000000;"> String ConvertToBase64String(String value)
{
    Byte[] bytes </span><span style="color:#000000;">=</span><span style="color:#000000;"> System.Text.Encoding.UTF8.GetBytes(value);
    String base64String </span><span style="color:#000000;">=</span><span style="color:#000000;"> Convert.ToBase64String(bytes);
    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> base64String;
} </span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>6. Add the following method, creating the payload, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:81deb4f0-2b81-419e-824b-374729d3c8cc" class="wlWriterEditableSmartContent">
<pre style="width:1091px;height:478px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">private</span><span style="color:#000000;"> XDocument CreatePayload( String serviceName, String label,
    String description, String location, String affinityGroup)
{
    String base64LabelName </span><span style="color:#000000;">=</span><span style="color:#000000;"> ConvertToBase64String(label); 

    XElement xServiceName </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">ServiceName</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, serviceName);
    XElement xLabel </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">Label</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, base64LabelName);
    XElement xDescription </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">Description</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, description);
    XElement xLocation </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">Location</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, location);
    XElement xAffinityGroup </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">AffinityGroup</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, affinityGroup); 

    XElement createHostedService </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XElement(wa </span><span style="color:#000000;">+</span><span style="color:#800000;">&quot;</span><span style="color:#800000;">CreateHostedService</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">);
    createHostedService.Add(xServiceName);
    createHostedService.Add(xLabel);
    createHostedService.Add(xDescription);
    createHostedService.Add(xLocation);
    </span><span style="color:#008000;">//</span><span style="color:#008000;">createHostedService.Add(xAffinityGroup); </span><span style="color:#008000;">
</span><span style="color:#000000;">
    XDocument payload </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XDocument();
    payload.Add(createHostedService);
    payload.Declaration </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> XDeclaration(</span><span style="color:#800000;">&quot;</span><span style="color:#800000;">1.0</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">UTF-8</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">, </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">no</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">); 

    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> payload;
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>7. Add the following method, invoking the create hosted service operation, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:8bf140fc-7726-417c-884e-5ad003acd962" class="wlWriterEditableSmartContent">
<pre style="width:1229px;height:283px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">private</span><span style="color:#000000;"> String CreateHostedService(String subscriptionId, String thumbprint,
    String serviceName, String label, String description, String location, String affinityGroup)
{
    String uri </span><span style="color:#000000;">=</span><span style="color:#000000;"> String.Format(createHostedServiceFormat, subscriptionId); 

    XDocument payload </span><span style="color:#000000;">=</span><span style="color:#000000;"> CreatePayload(serviceName, label, description, location, affinityGroup); 

    ServiceManagementOperation operation </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> ServiceManagementOperation(thumbprint); 

    String requestId </span><span style="color:#000000;">=</span><span style="color:#000000;"> operation.Invoke(uri, payload); 

    </span><span style="color:#0000FF;">return</span><span style="color:#000000;"> requestId;
}</span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<p>8. Add the following method, invoking the methods added earlier, to the class: </p>
<div style="display:inline;float:none;margin:0;padding:0;" id="scid:9D7513F9-C04C-4721-824A-2B34F0212519:201266d9-013f-49ed-9bc4-88a110a40821" class="wlWriterEditableSmartContent">
<pre style="width:1183px;height:277px;background-color:White;overflow:auto;">
<div><span style="color:#0000FF;">public</span><span style="color:#000000;"> </span><span style="color:#0000FF;">static</span><span style="color:#000000;"> </span><span style="color:#0000FF;">void</span><span style="color:#000000;"> UseCreateHostedServiceExample()
{
    String subscriptionId </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{SUBSCRIPTION_ID}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String thumbprint </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{THUMBPRINT}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String serviceName </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{SERVICE_NAME}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String label </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{LABEL}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String description </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">Newly created service</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String location </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{LOCATION}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">;
    String affinityGroup </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#800000;">&quot;</span><span style="color:#800000;">{AFFINITY_GROUP}</span><span style="color:#800000;">&quot;</span><span style="color:#000000;">; 

    CreateHostedServiceExample example </span><span style="color:#000000;">=</span><span style="color:#000000;"> </span><span style="color:#0000FF;">new</span><span style="color:#000000;"> CreateHostedServiceExample(); 

    String requestId </span><span style="color:#000000;">=</span><span style="color:#000000;"> example.CreateHostedService(
        subscriptionId, thumbprint, serviceName, label,
        description, location, affinityGroup);
} </span></div>
</pre>
<p><!-- Code inserted with Steve Dunn's Windows Live Writer Code Formatter Plugin.  http://dunnhq.com --></div>
<h4>How it works&#8230;</h4>
<p>In steps 1 through 3, we set up the class. In step 4, we add private members to define the XML namespace used in creating the payload and the <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx">String</a> format used in generating the endpoint for the create hosted service operation. In step 5, we add a helper method to create a base-64 encoded copy of a <em>String</em>. </p>
<p>We create the payload in step 6 by creating an <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xelement.aspx">XElement</a> instance for each of the required and optional properties, as well as the root element. We add each of these elements to the root element and then add this to an XML document. Note that we do not add an <em>AffinityGroup</em> element because we provide a <em>Location</em> element and only one of them should be provided. </p>
<p>In step 7, we use the <em>ServiceManagementOperation</em> utility class, described in the Getting ready section, to invoke the create hosted service operation on the Service Management API. The <em>Invoke()</em> method creates an <em>HttpWebRequest</em>, adds the required X.509 certificate and the payload, and then sends the request to the create hosted services endpoint. It then parses the response to retrieve the request ID which can be used to check the status of the asynchronous create hosted services operation. </p>
<p>In step 8, we add a method that invokes the methods added earlier. We need to provide the subscription ID for the Windows Azure subscription, a globally unique service name for the hosted service, and a label used to identify the hosted service in the Windows Azure Portal. The location must be one of the official location names for a Windows Azure datacenter, such as <em>North Central US</em>. Alternatively, we can provide the GUID identifier of an existing affinity group and swap the commenting out in the code adding the <em>Location</em> and <em>AffinityGroup</em> elements in step 6. We see how to retrieve the list of locations and affinity groups in the Locations and affinity groups section of this recipe. </p>
<h4><a>There&#8217;s more</a><a>&#8230;</a></h4>
<p>Each Windows Azure subscription can create 6 hosted services. This is a soft limit that can be raised by requesting a quota increase from Windows Azure Support at: </p>
<p><a href="http://www.microsoft.com/windowsazure/support/">http://www.microsoft.com/windowsazure/support/</a> </p>
<p>There are also soft limits on the number of cores per subscription (20) and the number of Windows Azure storage accounts per subscription (5). These limits can also be increased by request to Windows Azure Support. </p>
<h5>Locations and affinity groups</h5>
<p>The list of locations and affinity groups can be retrieved using the list locations and list affinity groups operations respectively in the Service Management API. We see how to do this in the Using the <a href="http://wappowershell.codeplex.com/">Windows Azure Platform PowerShell Cmdlets</a> recipe in this chapter. </p>
<p>As of this writing, the locations are: </p>
<ul>
<li>Anywhere US
<li>South Central US
<li>North Central US
<li>Anywhere Europe
<li>North Europe
<li>West Europe
<li>Anywhere Asia
<li>Southeast Asia
<li>East Asia </li>
</ul>
<p>The affinity groups are specific to a subscription.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/186/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/186/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/186/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=186&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/08/29/creating-a-windows-azure-hosted-service/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
		<item>
		<title>Microsoft Windows Azure Development Cookbook</title>
		<link>http://convective.wordpress.com/2011/08/08/microsoft-windows-azure-development-cookbook/</link>
		<comments>http://convective.wordpress.com/2011/08/08/microsoft-windows-azure-development-cookbook/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 23:59:50 +0000</pubDate>
		<dc:creator>Neil Mackenzie</dc:creator>
				<category><![CDATA[Azure AppFabric]]></category>
		<category><![CDATA[Diagnostics]]></category>
		<category><![CDATA[Service Management]]></category>
		<category><![CDATA[SQL Azure]]></category>
		<category><![CDATA[Windows Azure]]></category>
		<category><![CDATA[Windows Azure Diagnostics]]></category>
		<category><![CDATA[Windows Azure Service Management]]></category>

		<guid isPermaLink="false">https://convective.wordpress.com/2011/08/08/microsoft-windows-azure-development-cookbook/</guid>
		<description><![CDATA[The reason I didn&#8217;t write many posts on the blog in the early part of this year was that I was writing a book on Windows Azure for Packt Publishing. This book, Microsoft Windows Azure Development Cookbook, is now available &#8230; <a href="http://convective.wordpress.com/2011/08/08/microsoft-windows-azure-development-cookbook/">Continue reading <span class="meta-nav">&#8594;</span></a><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=183&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The reason I didn&#8217;t write many posts on the blog in the early part of this year was that I was writing a book on Windows Azure for <a href="http://www.packtpub.com/">Packt Publishing</a>. This book, <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">Microsoft Windows Azure Development Cookbook</a>, is now available from all the usual <a href="http://www.amazon.com/Microsoft-Windows-Azure-Development-Cookbook/dp/1849682224/ref=sr_1_1?ie=UTF8&amp;qid=1312844601">outlets</a> as well as direct from the <a href="http://www.packtpub.com/microsoft-windows-azure-development-cookbook/book">publisher</a>.</p>
<p>The book is one of a series of <a href="http://www.packtpub.com/books/cookbooks">cookbooks</a> published by Packt. They are intended to provide &#8220;recipes&#8221; showing how to implement specific techniques in a particular technology. They are not intended to be narrative books read from cover-to-cover – although they certainly can be.</p>
<p>In the <em>Microsoft Windows Azure Development Cookbook</em>, I show how to perform various development tasks across the Windows Azure Platform – including the Window Azure Storage Service, Windows Azure hosted services, Windows Azure Diagnostics, and the Windows Azure Service Management REST API. I also provided some &#8220;recipes&#8221; for the Windows Azure AppFabric and SQL Azure, although these areas are sufficiently large as to deserve their own books rather than be reduced to chapters in a general book. Packt has provided a free <a href="http://www.packtpub.com/sites/default/files/2220-chapter-7-managing-hosted-services-with-the-service-management-api.pdf?utm_source=packtpub&amp;utm_medium=free&amp;utm_campaign=pdf">download</a> of the chapter on the Windows Azure Service Management REST API.</p>
<p>One of the problems in writing about a new technology is that the technology develops as the book is being written. This was particularly true of the Windows Azure Access Control Service. This is an interesting part of the Windows Azure Platform but is one that is not covered in the book – partly because the technology was changing and partly because of the difficulty of shoehorning information about it into the structure of the book.</p>
<p>As with any large project, the creation of a book takes many people. I am particularly indebted to the technical editors who provided a lot of comments that immeasurable improved the book:</p>
<p><a href="http://blog.maartenballiauw.be/">Maarten Balliauw</a> (@maartenballiauw)</p>
<p><a href="http://michaelcollier.wordpress.com/">Michael Collier</a> (@MichaelCollier)</p>
<p><a href="http://www.cerebrata.com/">Gaurav Mantri</a> (@gmantri)</p>
<p><a href="http://brentdacodemonkey.wordpress.com/">Brent Stineman</a> (@BrentCodeMonkey)</p>
<p>They, of course, bear no responsibility for the errors that are inevitable in any project like this. I am also grateful to the many people at Packt who worked on the book and helped ensure it came out in a timely fashion.</p>
<p>The chapters on the Windows Azure Storage Service would have been very difficult to do had I not used Cerebrata&#8217;s <a href="http://www.cerebrata.com/Products/CloudStorageStudio/Default.aspx">Cloud Storage Studio</a>. This is an excellent product and I highly recommend it to anyone using the Windows Azure Storage Service.</p>
<p>The genesis of the book is clearly in this blog. However, the coverage of the various features is much more extensive in the book. So, if you like the posts on the blog you should look at the <em>Microsoft Windows Azure Development Cookbook</em>.</p>
<p>And now, on to all that new stuff the Windows Azure Team keeps <a href="http://blogs.msdn.com/b/windowsazure/">announcing</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/convective.wordpress.com/183/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/convective.wordpress.com/183/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/convective.wordpress.com/183/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=convective.wordpress.com&amp;blog=16172360&amp;post=183&amp;subd=convective&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://convective.wordpress.com/2011/08/08/microsoft-windows-azure-development-cookbook/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a98462019087eda659aafb34f393f3ab?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">nmackenzie2010</media:title>
		</media:content>
	</item>
	</channel>
</rss>
