Looking at Azure
I’m going to build on my tradition of blogging my notes as I explore new toolkits. Just like I did with LINQ, I’ll be posting blog entries about what I’ve learned as I work with the Azure platform.
Dissecting HelloFabric
I’m skipping the HelloWorld sample because the only thing I learned was that the current Device Fabric is not compatible with the Current Windows 7 beta build. Two different pre-release components, so I’m not too surprised.
HelloFabric gives a good overview of some of the basic functionality provided by the cloud infrastructure. When you run the sample, you’ll have see a simple webpage that demonstrates some of the Azure APIs.
Let’s look at the code first, and then peek at the cloud specific configuration. The first thing you see when you run the application is that it tells you if it is running in the cloud, or on a standard ASP.NET context. There’s a bit of code in the the page load handler that looks at the ApplicationEnvironment to see where it’s running.
1: // Check if we are running in the fabric
2: if (ApplicationEnvironment.ApplicationModel == ApplicationModel.Cloud)
3: {
4: Label3.Text = "Running in the fabric." ;
5: if (Request.IsSecureConnection)
6: {
7: Label2.Text = "Running over a secure connection.";
8: }
9: else
10: {
11: Label2.Text = "Not running over a secure connection. Please see the documentation to test this sample with SSL.";
12: }
13: }
14: else
15: {
16: Label3.Text = "Running outside the fabric.";
17: Label2.Text = "";
18: }
The next item you’ll see in the page is that the label contains a set of banner text from one of the config files:
1: Label1.Text = ApplicationEnvironment.Settings["BannerText"];
A little further down the page, you’ll see that you can enter a message that will get written to the log. The code couldn’t be much simpler:
1: String msg = TextBox1.Text;
2: switch (DropDownList1.Text)
3: {
4: case "Alert":
5: ApplicationEnvironment.LogAlert(msg);
6: break;
7: case "Error":
8: ApplicationEnvironment.LogError(msg);
9: break;
10: case "Warning":
11: ApplicationEnvironment.LogWarning(msg);
12: break;
13: case "Information":
14: ApplicationEnvironment.LogInformation(msg);
15: break;
16: case "Verbose":
17: ApplicationEnvironment.LogVerbose(msg);
18: break;
19: default:
20: ApplicationEnvironment.LogError("Unexpected kind");
21: return;
22: }
Finally, there’s a button that creates a null reference exception so you can exercise the tools that you’ll use to debug code that runs in the cloud.
You’ll note that all the code I’ve shown so far use this ApplicationEnvironment class. The ApplicationEnvironment class provides some basic capabilities that abstract away the core operating environment.
In its class constructor, it looks at the RoleManager and if the role manager is running, it determines that the operating environment is the cloud. Next, it looks to see if there is a web context. That would mean it’s running in a standard web environment. If neither of those facts are true, it assumes it is running on the desktop:
1: protected void Button1_Click(object sender, EventArgs e)
2: {
3: String msg = TextBox1.Text;
4: switch (DropDownList1.Text)
5: {
6: case "Alert":
7: ApplicationEnvironment.LogAlert(msg);
8: break;
9: case "Error":
10: ApplicationEnvironment.LogError(msg);
11: break;
12: case "Warning":
13: ApplicationEnvironment.LogWarning(msg);
14: break;
15: case "Information":
16: ApplicationEnvironment.LogInformation(msg);
17: break;
18: case "Verbose":
19: ApplicationEnvironment.LogVerbose(msg);
20: break;
21: default:
22: ApplicationEnvironment.LogError("Unexpected kind");
23: return;
24: }
25: }
You’ll notice from the code above that the constructor also constructs a logger object based on where its running. A further dive into the code shows that the RoleManager class contains methods to write to a log in the Azure fabric.
1: public override void LogAlert(string msg)
2: {
3: RoleManager.WriteToLog("Critical", msg);
4: }
The other logger implementations should be familiar to any .NET developer.
The last item you saw was reading a string from the configuration file. That’s also different in the fabric, and the ApplicationEnvironment class abstracts that away from you. To read configuration items while running in the fabric you use the RoleManager.GetConfigurationSetting method:
1: return RoleManager.GetConfigurationSetting(name);
Of course, to read something from a config file, you’ll have to put the data in a config file. Azure changes that again. You have to define your config settings in your service definition.csdef file:
1: <ConfigurationSettings>
2: <Setting name="BannerText"/>
3: <Setting name="LogAllRequests" />
4: <Setting name="LogFailedRequests" />
5: </ConfigurationSettings>
And, you assign values to them in the ServiceConfiguration.cscfg file:
1: <ConfigurationSettings>
2: <Setting name="BannerText" value="Hello Fabric!" />
3: <Setting name="LogAllRequests" value="false" />
4: <Setting name="LogFailedRequests" value="true" />
5: </ConfigurationSettings>
Of course, you saw that there are some other settings in those config files, and that’s how logging gets enabled, and that makes use of the other classes in the Common library used in this sample.
The two boolean values affect an IHttpModule implementation that logs all requests, or just some of the requests. When the module initializes, it reads the configuration setting and attaches a handler for all requests, or just error requests. The code demonstrates how to configure logging at runtime, because there is an overhead associated with the extra logging functionality.
If you want to explore the fabric sample yourself, make sure you open the Device Fabric logger to see the logging capabilities. That’s where all the logging messages go in the end.
In some ways, Azure development, at the code level, looks boring. It’s too familiar. But then, that’s the point: Azure builds on the existing tools and libraries we already use.