I have recently worked on several projects that have been built to utilize the Microsoft cloud platform called Azure. Azure offers a lot of really interesting benefits, and especially when it comes to being elastic. You can basically throw however much data you want at it, and as long as you are willing to pay for it, it will handle it. It doesn’t matter if you throw data at it that needs to be computed, or if you throw vast amounts of data that needs to be stored. Azure will handle it for you.
On top of that, it is really easy to build for. There isn’t really a whole lot to learn before one can get up and running in the cloud. Microsoft even offers a sweet SDK that gives you access to the cloud based services locally on your machine. It offers you the ability to deploy your webroles (web applications) straight to a local “cloud” and debug it. So you don’t even need to have an Azure account to starting to work with it.
Azure also offers a couple of interesting storage alternatives. It has basically 3 “simple”, but almost infinitely expandable, storage areas as well as good old SQL in the cloud. The “simple” storage is based around blobs, queues and tables.
In blob storage, you can store any binary object. Big or small doesn’t matter. Well…almost at least. For a so called block blob, you are limited to 200Gb per blob, and for table blobs the number is 1Tb. Yes…1 TERRA byte…and that is in one file. Ad you do not need to download it all to read it. You can read pieces out of that huge file.
Queue storage are exactly what it sounds like. It consists of queues where you can place string based messages that needs to be handled at some point. You can then create build a process that picks items off the queue and processes them when they arrive, or when the processor has time.
And finally you’ve got table storage. Table storage sounds like a relational database like SQL, but it isn’t. It is basically consists of simple tables with no way of adding relations. It also has limited indexing support and sorting and so on. But on the other hand, it is huge. You can just keep pushing data on to the table and it will just handle it. So it is a crude kind of database with almost not upper limit on size.
And then finally you have SQL Azure, which is more or less Microsoft SQL Server in the cloud. However, it lacks some of the features you get on a local server.
So…what has this got to do with Silverlight and my blog? Well…the cool thing is that all of the simple storage areas are available through a RESTful interface. So we can consume them using Silverlight. Or at least you would think so. The issue is that only blob storage is really possible to work with…but more on that later…
So if we store data in blobs, we can read these blobs from a Silverlight client. And since we are talking blobs, we can put ANYTHING there. We can store images, videos, xml, xap packages…yes anything. And all of this data can be retrieved using simple HTTP requests from Silverlight.
While building our Silverlight applications however, we want to use the local Development Storage service instead of using the real cloud. The local service means no cost, and no need for an internet connection even. It is a part of the Windows Azure SDK that you can download here.
There is however a couple of snags when it comes to using blob storage it from Silverlight. Unless you host your XAP file as a blob in blob storage, which is very easy but trickier to debug, your HTTP request to the blob storage will be considered a cross domain call. And as we all know, cross domain calls are “dangerous” and requires Silverlight to retrieve a client access policy before allowing it. That client access policy must be located at the root of the domain being called.
In Azure blob storage, you place all your blobs (files) in container (directories (only one level of containers allowed)). And there is by default a container called $root. Any blob placed in this container will be exposed at the root of the domain. So by uploading a clientaccesspolicy.xml file to this container, we expose the file needed for Silverlight to allow us to get access.
The only problem when using the local Development Storage is that is plays some tricks with the Urls that you use. In dev storage, the root of the storage is actually placed at “/devstoreaccount1/”. So a client access policy placed in the $root container, will actually end up being served up at “/devstreaccount1/clientaccesspolicy.xml”. And thus will not be found by Silverlight, causing Silverlight to throw a hissy fit and not allow you to access dev storage.
So how do we solve this? Well…you can’t reconfigure the local storage service to do anything else. So to work with blob storage from Silverlight, we either need to use the real cloud or we need to get creative. And since using the real cloud costs money and makes it impossible to work without an internet connection (and possibly slow with one), I prefer getting creative.
My solution to this problem was to build a proxy application. Basically build an application that runs on the local machine and works as a tiny webserver. It accepts requests that are meant to go to dev storage and forwards them to the correct location. So instead of making requests to the local dev storage’s Url (127.0.0.1:10000), you make the requests to this service (127.0.0.1:11000). It then looks at your request, copies the parameters and makes a request to the dev storage service. It then takes the response and passes it back to the original request…as a proxy… It also adds the “/devstoreaccount1/” part to the Uri, making the required Uri a lot more similar to the Uri used for the real storage.
It also handles calls to the clientaccesspolicy.xml file a little differently. Instead of passing that request on to the dev storage, it returns a client access policy stored in the application as a resource. A client access policy that makes no limitations at all.
Since this solution seems to work quite well, I have packaged it up and placed it on CodePlex for people to use. That way there is no need for everyone to build their own version, which makes it even easier to get up and working with the Azure platform. The Url for the CodePlex project is http://agazuredevstoreproxy.codeplex.com/.
Hope you find it useful…
But I did mention before that only blob storage was really usable from Silverlight and that I would explain why later…so I will…
All calls to Azure storage has be secured somehow (except calls to read publicly available blobs). The way that they are secured, is by signing the request using a secret key. The problem with signing requests with secret keys in Silverlight, is that the key must be sent to the client somehow, or even included in the Xap package. That makes the key much less secret. And defeats the purpose of even signing the request as anyone can just take the secret from the application and do what they like.
So to fix that, Microsoft has introduced a concept called Shared Access Signatures (SAS). An SAS is a string that is appended as a querystring parameter to the call to the storage service and acts as a secure signature. The SAS is time limited and can only be created by a client that has access to the storage key. So the SAS can be created on the server and passed to the Silverlight client as an initParameter. That way, Silverlight can access blobs and blob containers that aren’t public, without the key being passed around. More information and demos on how to do this is available here.
So why do I say that only blob storage can be used from Silverlight. That whole SAS thing seems a bit out of place and have very little to do with that statement. Except for the fact that you are not allowed to use SAS with table storage or queue storage. So only blob storage will work…
So…now I think I have covered everything I intended to cover in this post. And once again it became very long… But I guess that’s just the way I roll.
Once again I hope you found the information useful, and if you have any questions just drop me a line or write a comment. There are a lot of things to cover when it comes to Silverlight and Azure, so I will probably come back to this subject in future posts. So if you find this interesting, don’t forget to come back in the future…