find a location for property in a new city

Thursday 19 January 2012

Interesting little Azure points

I often discover little interesting facts about Azure while I am using it that I would blog about but would only last one line/paragraph so I don't bother. This is what I should tweet about I suppose but I get the feeling my tweets (@britishdev) get lost within 10mins surrounded by your little cousin Kate reporting, "@KatezLulz: OMG I just ate broccoli!!!1! :p" and I can't compete with that. So here is a blog post which I will try to keep updates with short and sharp points about Windows Azure.

#1 What happens to your Azure deployment if your machine is turned off halfway through?

It depends where you are in your deployment. As long as the uploading phase is done you will be fine. Sort of. Visual Studio and the management portal make it look a lot more simple than it is to deploy an Azure package but it does it in steps like: Upload, Create, Start instances etc (or along those lines anyway). So if you switch your computer off after you have uploaded you will not lose everything and have to start again but it wouldn't have deployed fully either. Next time you log in to the management portal you will find your instances are there but "Stopped" so you simply need to start them using the great big Start button in the Azure management portal and it is done. Trivial.

#2 You can filter your Azure Table Storage viewer in Visual Studio

Type filters into the bar such as Timestamp gt datetime'2012-01-19T10:00:00Z'. This will get every record after 19th Jan 2012 10am. Here is a full list of table filters.

Follow britishdev on Twitter

Friday 13 January 2012

Case sensitive Azure storage

Azure storage URLs are case sensitive as you may have noticed. If you have not noticed then: OMG AZURE STORAGE URL ARE CASE SENSITIVE!!1! This is most likely because URL specification states that URLs should be case sensitive so as to ensure different casings should represent different locations. Admittedly, this is rather odd when compared with IIS and subsequently web sites running in Azure.

I am a developer and architect by trade so I am more than aware of the importance in maintaining consistent URLs throughout a web site. Search engines index sites in a case sensitive way and so it is important not to accidentally display duplicate web content on differently cased URLs. To handle this in the past I have always insisted that my teams adopt a lower case policy where by every URL written in code, links, references etc are always written in lower case. This avoids such an SEO disaster. I also create a redirect rule using IIS Rewrite Module to 301 redirect any URLs containing uppercase characters to its lowercase version.

With this policy in mind it should not be difficult to now use Azure storage by simply maintaining these standards. It is wise to create a repository class that will handle all interaction with Blob, Tables and Queue storage that can abstract common rules away from the developer each time they wish to use them. One of these rules would be to ensure that when saving to these repositories the filenames and containers are lower cased using .ToLower() (in C#). Also when getting an object from storage you could also ensure that the file name requested is also lower cased in the same way.

This does not however prevent users accessing the URL using uppercase but really according to the URL specs they should not and using smart code you can most likely avoid this from happening. For example, if links are only ever displayed in lowercase someone if very unlikely to ever access it using uppercase.

Azure case sensitivity conclusion

So in summary, although it is an odd inconsistency between IIS and storage it is only a trivial programming exercise to enforce and a minor coding standard to communicate to your team. This will ensure that storage is always used as intended allowing you to reap the great benefits of using Windows Azure Storage.

Follow britishdev on Twitter

Wednesday 11 January 2012

Using the Azure API to see a deployment status using .NET

See the status of your Windows Azure deployments using the Windows Azure Service Management REST API. Since this is REST based you can use any framework or programming language that can make web requests. Python, Java etc here is .NET.

Here is a short bit of C# code that will allow you to call the part of the Windows Azure Service Management REST API that deals with getting the status of your hosted service in Azure.

You can see how the REST API is expected to be used here at Get Hosted Service Properties. This code accesses that API:

static void Main(string[] args)
{
    var subsctiptionId = "f62e5e87-5c76-4a94-9136-794fae3eff16";
    var hostedService = "colintest";
    //I have another post that details how GetCertificateByThumbprint method works:
    //http://www.britishdeveloper.co.uk/2012/01/adding-certificate-to-request-in-net.html
    var certificate = GetCertificateByThumbprint("23A43AE81F15CB000000000000000000000000000");

    var statusApiUrl = string.Format(
       "https://management.core.windows.net/{0}/services/hostedservices/{1}?embed-detail=true",
       subsctiptionId, hostedService);
    var hostedServiceStatus = new Uri(statusApiUrl);
    Console.WriteLine("Hosted service status");
    MakeApiRequest(hostedServiceStatus, certificate);
    
    Console.ReadKey();
}

private static void MakeApiRequest(Uri requestUri, X509Certificate2 certificate)
{
    var request = (HttpWebRequest)HttpWebRequest.Create(requestUri);
    request.Headers.Add("x-ms-version", "2011-10-01");
    request.Method = "GET";
    request.ContentType = "application/xml";
    request.ClientCertificates.Add(certificate);

    try
    {
        using (var response = (HttpWebResponse)request.GetResponse())
        {
            Console.WriteLine("Response status code: " + response.StatusCode);

            using (var responseStream = response.GetResponseStream())
            using (var reader = new StreamReader(responseStream))
            {
                Console.WriteLine("Response output:");
                Console.WriteLine(reader.ReadToEnd());
            }
            Console.WriteLine("");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        throw e;
    }
}

Since you have used ?embed-detail=true in the querystring this add extra detail. From here you can get all sorts of useful information such as: Status e.g. Running or DeploymentSlot e.g. Production.

Note: The GetCertificateByThumbprint(string thumbprint) method I used is of course simplifying attaching a certificate to the request for the sake of conciseness. You can have a look at what this method is doing here at attaching a certificate to a WebRequest.

Follow britishdev on Twitter

Adding a certificate to a request in .NET

Sometimes you need to send a security certficate with your WebRequest to authenticate with the web service you are accessing, e.g. a REST API via .NET. To authenticate you may need to send a certificate with your web request to authenticate with the API. This guide shows you how to do that using .NET.

First you need to be able to find your certificate. Sometimes it is hard to remember where exactly your certificate is so I have created two methods which together will search all usual locations until it finds the certificate based on its thumbprint.

This bit of code finds and returns the certificate:

//Returns a certificate by searching through all likely places
private static X509Certificate2 GetCertificateByThumbprint(string thumbprint)
{
    X509Certificate2 certificate;
    //foreach likely certificate store name
    foreach (var name in new[] { StoreName.My, StoreName.Root })
    {
        //foreach store location
        foreach (var location in new[] {StoreLocation.CurrentUser, StoreLocation.LocalMachine})
        {
            //see if the certificate is in this store name and location
            certificate = FindThumbprintInStore(thumbprint, name, location);
            if (certificate != null)
            {
                //return the resulting certificate
                return certificate;
            }
        }
    }
    //certificate was not found
    throw new Exception(string.Format("The certificate with thumbprint {0} was not found",
                                       thumbprint));
}

private static X509Certificate2 FindThumbprintInStore(string thumbprint,
                                                      StoreName name, StoreLocation location)
{
    //creates the store based on the input name and location e.g. name=My
    var certStore = new X509Store(name, location);
    certStore.Open(OpenFlags.ReadOnly);
    //finds the certificate in question in this store
    var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint,
                                                     thumbprint, false);
    certStore.Close();

    if (certCollection.Count > 0)
    {
        //if it is found return
        return certCollection[0];
    }
    else
    {
        //if the certificate was not found return null
        return null;
    }
}

With this method created that gets a certificate you can now easily add a certificate to an HttpWebRequest like so:

var request = (HttpWebRequest)HttpWebRequest.Create("https://mysecureapi.com/listofsecrets");
var certificate = GetCertificateByThumbprint("23A43AE81F15CB000000000000000000000000000");
request.ClientCertificates.Add(certificate);
Now when you set up the rest of your request and GetResponse you will be sending the certificate also.

Follow britishdev on Twitter

Saturday 7 January 2012

Do not use iisreset in Azure

So you have remote desktop in to one of you Azure instances and you are free to do anything you like right? Wrong! Do not change things! And as I found do not use IISReset.

I have heard many times that remoting in to an Azure instance is for looking and debugging only, NOT for changing things. In fact I have even given this advice to many clients I have spoken to about Azure. But who am I to practice what I preach?

Really, I give the advice of not changing things when RDPing into an Azure instance because any changes you make will at some point be lost when your instances are automatically updated for you and then redistributed to other machines. Any changes you wish to be permanent on your machine will need to be part of your package.

Anyway, you can see why I avoid making changes, because of a lack of persistence but that doesn't mean I shouldn't do a cheeky IIS reset when trying to fix an issue right? Hmm, wrong.

Do not restart IIS on an Azure instance

I do not know why, there must be some black magic Azure voodoo that goes on after IIS is initialised that doesn't happen when you restart it yourself manually. Anyway, I learnt that it will completely destroy your instance. The site will not respond any longer from that instance. The best way to effectively do an IIS Reset is to Reboot your instance from the Azure Management Portal.

Follow britishdev on Twitter

Friday 6 January 2012

How to run Crystal Reports on Azure

Here is a step by step guide on how to make an ASP.NET project that uses Crystal Reports run successfully on Azure. If you try to run a Crystal Report in your ASP.NET site without the Crystal Reports runtime installed you will receive a "System.Runtime.InteropServices.COMException" with description "The Report Application Server failed".

The problem is that you need to install the Crystal Reports runtime. This isn't a problem with regular hosting since you can just install Crystal Reports on each of your servers and off you go.

With Azure, though, if you remote into the machine and install it, it will work fine until your deployment is redistributed to another machine which it will do at some point due to the nature of cloud computing.

How to install Crystal Reports on your Azure web role

Fortunately it is still easy with Azure. Easy when you know how anyway. Here are the steps you will need to take:

First of all you will need to download the SAP Crystal Reports runtime engine for .NET Framework 4 (64-bit). This should extract as a msi file called CRRuntime_64bit_13_0_2.msi.

In your web application in Visual Studio you should paste this msi file at the route of your web project and include it in the project. Right click it in the Solution Explorer and set its 'Build Action' to 'None' and also set its 'Copy to Output Directory' to 'Always Copy'.

Next you will create a command file to execute this msi file. Create a new text file, call it StartUp.cmd and then save it in the root of your web project (next to the msi). In that file write the following:

@ECHO off

ECHO "Starting CrystalReports Installation" >> log.txt
msiexec.exe /I "CRRuntime_64bit_13_0_2.msi" /qn
ECHO "Completed CrystalReports Installation" >> log.txt

Set the properties of StartUp.cmd to 'Build Action' = 'None' and 'Copy to Output Directory' = 'Always Copy'.

Now in your ServiceDefinition.csdef make this cmd file a start up task by adding the following lines:

<WebRole name="Web" vmsize="Small">
  ...
  <Startup>
    <Task commandLine="StartUp.cmd" executionContext="elevated" taskType="background" />
  </Startup>
</WebRole>

You are now instructing each instance that starts up with your package to run the Crystal Reports msi file that installs the runtime on the instance ready for its use in Azure.

A few Crystal Reports on Azure tips

I ran into a few bits and bobs which caused me unnecessary pain along the seemingly clean process outlined above. I will share them with you in case you do too in no particular order.

  • Make sure your .rpt Crystal Report files are set to Build Action: Content and Copy to Output Directory: Copy always.
  • Don't be alarmed with how long it takes to deploy. It will take much longer to upload than usual because you are now uploading an extra 77MB of installation files. It took me an hour to deploy on my home connection!
  • Ignore all the warnings about how your web project is dependent on various Crystal Report assemblies since Azure will have them just as soon as your installation file runs.
  • Configure a remote desktop connection when you do your deployments since it will be invaluable should anything go wrong and at an hour per deployment you don't want to be messing about.
  • Visual Studio may have added a load of random assemblies in your web.config you are not aware of and don't need and may even cause problems like log4net.

That is all. Good luck - it's very satisfying when you get it going.

Follow britishdev on Twitter

Wednesday 4 January 2012

Azure AppFabric Cache billing

I have started using Windows Azure AppFabric Cache service recently and I was confused at how much money it was costing.

I started using a new subscription yesterday and I seem to have already used 53.68 MB of my 128MB cache. In one day?!

However, if I look at my cache in the Azure management portal I am not using it at all!

So where has this 53MB of AppFabric Cache come from? Since I've only put my site live for less than 24hrs I was worried I was blazing through my 128MB/month allowance but then I thought about it logically for a moment. You don't use up a cache you just use it. It doesn't go anywhere.

How AppFabric Cache usage is calculated and billed

With this in mind it becomes obvious what has happened. I set my AppFabric cache up before I got around to deploying my site. So really it has been used since 22nd December, which is 13 days ago. It is irrelevant that I have deployed a site onto it only yesterday.

Look at the maths: 128MB/31days = 4.13MB/day * 13days = 53.68MB. It is a confusing way of displaying it but still, it makes sense.

Follow britishdev on Twitter