Today I digged up one of my old Azure projects that I used for practice while I took the certification nearly two years ago. Unfortunately I haven’t had many opportunities to work with Azure in the mean time so my Azure skills are a little rusty, hence this brush up. It is a little sad that Azure didn’t really catch on with the customers I usually work with, apparently they love their on-premise SharePoint too much 🙁 – Hopefully SP2013 will change that, but I have my doubt.
Upgrade to Azure June 2012 CTP
Anyways, my old project was up for an upgrade, last time I worked with azure the version of most of the dlls were 1.7.0 and since then the SDK has been released in a version 1.8.0/2.0.0 (June 2012 CTP). So first I had to update my SDK, thankfully installing the SDK was a lot smoother this time than two years ago, the Microsoft Web Platform installer were able to install everything I needed.
Next up I did an upgrade of my solution to VS2012, which was painless too. Then I started replacing the old assemblies with the 1.8.0/2.0.0 ones, and then things started to get messed up. Apparently things have changed quite a bit in Azure world, so lot of my code needed to get refactored. I had used code from the Microsoft.WindowsAzure.StoreClient assembly in lot of places in my old code, and as far as I understand this now should be replaced by the Microsoft.WindowsAzure.Storage assembly. This process was a little painful, because all the classes in the two namespaces are named the same so Resharper happily added the reference to the StoreClient again and again.
When all the references were corrected I discovered that a few other things also were changed, namely the configuration loading.
I ended up using the following in my StorageManager
CloudStorageAccount storageAccount = null;
var connectionString = CloudConfigurationManager.GetSetting("DataConnectionString");
if (connectionString == "UseDevelopmentStorage=true")
storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
storageAccount = CloudStorageAccount.Parse(connectionString);
For some reason the CouldStorageAccount.Parse method is unable to parse the connection string, if you have it set to UseDevelopmentStorage=true, hence the ugly code. Another thing worth mentioning is that CloudConfigurationManager is a wrapper class that when RoleEnvironment.IsAvailable is true reads the configuration from your cscfg files, but when you are not running your code in a RoleEnvironment etc. because it’s called from an IIS hosted website then it reads from the good old AppSetting in the web.config.
From my WorkerRole OnStart I was also able to remove:
Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
which at least makes this part of the code a little cleaner.
With these changes my old code was actually Azure June 2012 CTP compatible. So I moved on to improving the code, by adding a new CouldTable for some new data I wanted to store. This using the CloudTables (my original solution only used BlobStorage and Queues) forced me to install Microsoft.Data.OData, and its dependencies Microsoft.Data.Edm, and System.Spartial (as explained here). This can easily be installed with NuGet, but the latest version of Microsoft.Data.OData is 5.2.0 and that version doesn’t work with Microsoft.WindowsAzure.Storage 2.0.0, so you have to open the Package Manager Console, and specifically install version 5.0.2 by running:
Install-Package Microsoft.Data.OData -Version 5.0.2
Oh the horror of incompatible assemblies, this is starting to remind me of good old C++ lib days.
With the correct OData assemblies also my CouldTables were working, at least on my DEV environment (publishing to Azure is still to come, maybe in another post).
Azure Diagnostics (logging)
Then I finally wanted to add some logging, as we all know this should be done last. I’m using the simplest form of Azure logging I can think of, the Microsoft.WindowsAzure.Diagnostics.DiagnosticMonitorTraceListener which is the following added to the worker role app.config:
And the following added to my ServiceConfiguration.cscfg
And then it spun up in my workers OnStart, like so:
DiagnosticMonitorConfiguration dmc = DiagnosticMonitor.GetDefaultInitialConfiguration();
dmc.Logs.ScheduledTransferPeriod = TimeSpan.FromMinutes(1);
dmc.Logs.ScheduledTransferLogLevelFilter = LogLevel.Verbose;
When I added the DiagnosticMonitor I discovered the last horror of the day, namely that Micorsoft.WindowsAzure.Diagnostics.DiagnosticMonitor version 1.8.0 is dependent on the Microsoft.WindowsAzure.StoreClient version 1.7.0 assembly (which I had just been able to remove from my solution by my refactoring). Somebody at Microsoft’s Azure team clearly want WindowsAzure development to be messy.
Cost of Running an Azure solution
As part of todays research I found this nice article that explains why it’s important to design your Azure solutions good, if you don’t want to burn your money on nothing.