Installing two build agents on TeamCity

Other than jogging my memory in the future when I need to do the same thing again, this post adds no value other than to direct people to Marcos Placona’s great blog post on how to run two build agents on the same TeamCity instance. Unfortunately this doesn’t work out of the box so there is some tweaking involved, as you’ll see.

So, without further ado, over to you Marcos…

http://www.placona.co.uk/1327/technology/new-teamcity-agents-the-right-way/

Granting folder/file access permissions to IIS AppPool users

By default, processes than run under IIS won’t have permission to access folders you create on your server hard drive. So, if you want your web-sites to interact with folders and files you’ll need add access permissions using the standard folder properties dialog:

Security Permissions Dialog

Permissions must be granted to the AppPool that your site uses. To grant permissions to AppPool users, the user name you enter in the Select Users or Groups dialog:

Select User or Group Dialog

…should match the following pattern:

IIS AppPool\[AppPool Name]

When you click Check Names the text you entered will magically detect the AppPool.

Exotic .NET XML configuration file sections

The .NET framework makes application configuration really simple by supplying an out-of-the-box XML configuration file structure and associated classes to access the information contained within it.

By default, it allows configuration key-value pairs to be set and retrieved easily at run time. For example, the following configuration settings:

  <appSettings>
    <add key="ServerName" value="WinDB1"/>
    <add key="DatabaseName" value="MyData"/>
    <add key="EnableFeature" value="true"/>
  </appSettings>

…can be retrieved using:

var appSettingsReader = new AppSettingsReader();

var serverName = (string)appSettingsReader.GetValue("ServerName", typeof(string));
var databaseName = (string)appSettingsReader.GetValue("DatabaseName", typeof(string));
var enableFeature = (bool)appSettingsReader.GetValue("EnableFeature", typeof(bool));

…or (if you add a reference to System.Configuration):

var serverName = ConfigurationManager.AppSettings["ServerName"];
var databaseName = ConfigurationManager.AppSettings["DatabaseName"];
var enableFeature = bool.Parse(ConfigurationManager.AppSettings["EnableFeature"]);

…although as per a past post of mine, Encapsulated and strongly-typed access to .NET configuration files I don’t recommend that you litter your code with references to AppSettingsReader (or ConfigurationManager), but instead that you wrap all configuration up in a class so that settings are encapsulated away.

It is often necessary to hold more complex configurations though. Many developers I’ve worked with have tried to use the key-value model to store such settings, using a single string with various delimiters to hold separate different values. For instance, given a person construct with an ID, title, first name, last name and birth date attributes, some developers would be tempted to do something like this:

  <appSettings>
    <add key="Person1" value="I:1|T:Mr|F:Joe|L:Bloggs|D:1980-01-01"/>
  </appSettings>

…and then use string split functions to populate a Person class when reading information from the configuration file. While this approach works, it results in brittle, hard to read configuration files and complex string logic to take strings apart.

Instead, it is better to use the exotic configuration capabilities included in the framework. Here is an example demonstrating how you might store configuration information to populate the following Person class:

using System;

namespace ConfigurationExample
{
    public class Person
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime BirthDate { get; set; }
    }
}

The configuration file to store such settings might look like this:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <configSections>
    <section name="people" type="ConfigurationExample.PeopleConfigurationSectionHandler, ConfigurationExample" />
  </configSections>
  
  <people>
    
    <person id="1">
      <title>Mr</title>
      <firstName>Joe</firstName>
      <lastName>Bloggs</lastName>
      <birthDate>
        <year>1980</year>
        <month>1</month>
        <day>1</day>
      </birthDate>
    </person>

    <person id="2">
      <title>Miss</title>
      <firstName>Jane</firstName>
      <lastName>Black</lastName>
      <birthDate>
        <year>1984</year>
        <month>2</month>
        <day>3</day>
      </birthDate>
    </person>
    
  </people>
  
</configuration>

A class implementing IConfigurationSectionHandler must be written to read this exotic configuration file structure; you will need a reference to System.Configuration in order to use this interface. The location of your class is given in the ‘configSections’ declaration at the top of the file. In this case the framework is being instructed to look for a class with name and namespace ‘ConfigurationExample.PeopleConfigurationSectionHandler’ in the ‘ConfigurationExample’ DLL/project in order to read the configuration section named ‘people’.

That class could look something like this:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Xml;

namespace ConfigurationExample
{
    public class PeopleConfigurationSectionHandler : IConfigurationSectionHandler
    {
        public object Create(object parent, object configContext, XmlNode section)
        {
            var people = new List<Person>();

            foreach (XmlNode node in section.ChildNodes)
            {
                if (node.NodeType == XmlNodeType.Comment)
                {
                    continue;
                }

                var id = GetAttributeInt(node, "id");
                var title = GetChildNodeString(node, "title");
                var firstName = GetChildNodeString(node, "firstName");
                var lastName = GetChildNodeString(node, "lastName");

                var birthDateNode = GetChildNode(node, "birthDate");

                var birthDateYear = GetChildNodeInt(birthDateNode, "year");
                var birthDateMonth = GetChildNodeInt(birthDateNode, "month");
                var birthDateDay = GetChildNodeInt(birthDateNode, "day");

                people.Add(new Person
                {
                    Id = id,
                    Title = title,
                    FirstName = firstName,
                    LastName = lastName,
                    BirthDate = new DateTime(birthDateYear, birthDateMonth, birthDateDay),
                });
            }

            return people;
        }

        private static string GetAttributeString(XmlNode node, string attributeName)
        {
            try
            {
                return node.Attributes[attributeName].Value;
            }
            catch
            {
                var message = string.Format("Could not read attribute named '{0}' in people section of configuration file", attributeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static int GetAttributeInt(XmlNode node, string attributeName)
        {
            try
            {
                var value = GetAttributeString(node, attributeName);
                return int.Parse(value);
            }
            catch
            {
                var message = string.Format("Could not convert value stored in attribute named '{0}' to an integer", attributeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static XmlNode GetChildNode(XmlNode parentNode, string nodeName)
        {
            try
            {
                return parentNode[nodeName];
            }
            catch
            {
                var message = string.Format("Could not find node named '{0}' in people section of configuration file", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static string GetChildNodeString(XmlNode parentNode, string nodeName)
        {
            try
            {
                return parentNode[nodeName].InnerText;
            }
            catch
            {
                var message = string.Format("Could not read node named '{0}' in people section of configuration file", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }

        private static int GetChildNodeInt(XmlNode parentNode, string nodeName)
        {
            try
            {
                var value = GetChildNodeString(parentNode, nodeName);
                return int.Parse(value);
            }
            catch
            {
                var message = string.Format("Could not convert value stored in node named '{0}' to an integer", nodeName);
                throw new ConfigurationErrorsException(message);
            }
        }
    }
}

Although there is quite a lot of code there, it’s all pretty simple. More importantly, it’s not too brittle and very simple to extend should you wish to add more attributes to the Person class.

The method required by the IConfigurationSectionHandler interface is Create:

public object Create(object parent, object configContext, XmlNode section)

This is what gets called when the framework asks for the contents of the ‘people’ section. The ‘section’ parameter contains the people node from the XML. In essence, the code creates a list in which Person objects are stored, and loops over the child nodes in order to extract the correct information.

There are two important points to note about the code:

1) The code that detects for the presence of XML comments:

if (node.NodeType == XmlNodeType.Comment)
{
    continue;
}

…ensures that developers don’t break the code by adding comments into the XML.

2) All the helper methods in the class (e.g. GetAttributeString, GetChildNodeString, etc…) must expect there to be issues with the XML and throw meaningful, self-explanatory exceptions when things do go wrong. When there are problems with these types of sections it is not always obvious what the problem is from the default exceptions .NET throws (particularly if you’re using this technique in the start up code of a Windows Service) so you will save yourself a lot of head scratching further down the line by writing good error messages. The chances are that you will have more than one section handler in your project so it’s a good idea to encapsulate such helper methods away in an abstract ConfigurationSectionHandler base class to cut down on duplication and to promote reuse.

Assuming you have registered your section handlers correctly in the ‘configSections’ declaration, you can retrieve the Person objects as follows:

var people = (IList<Person>)ConfigurationManager.GetSection("people");

Since the IConfigurationSectionHandler interface uses the ‘object’ type as its return value you need to cast the result to the correct type. It would have been nice if the interface was made generic, but I guess you can’t have everything!

If you’re following the advice in my previous post on configuration encapsulation, you’ll probably want to wrap this call up in your ConfigurationFile class, as follows:

using System.Collections.Generic;
using System.Configuration;

namespace ConfigurationExample
{
    public class ConfigurationFile
    {
        private readonly IList<Person> people;

        public ConfigurationFile()
        {
            people = (IList<Person>)ConfigurationManager.GetSection("people");
        }

        public IList<Person> People
        {
            get
            {
                return people;
            }
        }
    }
}

Note that a reference to the Person list is stored when the class constructs to save the running the cast each time you want to retrieve the contents of the configuration file section.

In summary, it’s a little more work to write exotic configuration file sections, but the advantages over brittle, difficult to extend key-value implementations is certainly worth the extra effort.

Help! My Windows desktop is upside down!

Occasionally when I hit a bunch of keys while trying to find those elusive Windows/Visual Studio short-cuts I end up managing to spin the desktop on my PC so that it is either upside down or rotated by 90 degrees. I’m sure this is a useful feature if you want to fix your monitor to a wall or ceiling, but for most users it’s just an annoyance that is hard to get out of if you happen to do it by mistake… unless you’re good at Googling while in the handstand position.

So, if you’re reading this with your head tilted to one side, or indeed in an upside down position, the keys you need to press to get your desktop the right way up again are:

CTRL + ALT + Up Arrow

Using the other arrow keys will rotate your desktop back to less readable configurations.

NHibernate and log4net

Here’s a quick trick for people using NHibernate and log4net within their .NET applications. (…and if you’re not using NHibernate or log4net, you should seriously think about it!)

Add the following to your log4net configuration to find out what’s going on inside NHibernate:

  <logger name="NHibernate">
    <level value="DEBUG" />
  </logger>
  <logger name="NHibernate.SQL">
    <level value="DEBUG" />
  </logger>

As those kind folks at NHibernate have already set up the loggers behind the scenes, everything just works. The SQL logger is especially useful as it’ll show you explicitly which SQL statements are being generated by NHibernate. You can adjust the levels of NHibernate logging independently of your normal application logging, which is useful as the NHibernate logs tend to be pretty verbose.

The full configuration will look something like this:

<log4net>
  <appender name="TraceAppender" type="log4net.Appender.TraceAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <param name="ConversionPattern" value="%d %-5p- %m%n" />
    </layout>
  </appender>
  <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="Application.log"/>
    <appendToFile value="true"/>
    <rollingStyle value="Date"/>
    <datePattern value="yyyy-MM-dd'.log'"/>
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="DEBUG"/>
    <appender-ref ref="TraceAppender"/>
    <appender-ref ref="RollingFileAppender"/>
  </root>
  <logger name="NHibernate">
    <level value="ERROR" />
  </logger>
  <logger name="NHibernate.SQL">
    <level value="ERROR" />
  </logger>
</log4net>

Detecting web-site SPOFs

Web-site development today is a complex business, requiring knowledge of many different technologies and areas. It is becoming increasingly difficult (and costly!) for development teams to have sufficient knowledge in each of these disciplines, and as a result, specialist functions are often delegated to third parties. Some examples are:

  • Images are often hosted by CDNs.
  • JavaScript files such as jQuery and Google Analytics are often also hosted by CDNs.
  • Online payments are taken by third parties.
  • News feeds come from external social media sites.
  • Adverts are supplied by ad-providers.

This results in modern web-sites effectively being “mash-ups” of content taken from all over the internet. This is fine, until the third party providers become unavailable and parts of your site stop working. Worse still, if you’ve coded your site in such a way that your content depends explicitly on certain providers being available, a delay or failure from a third-party can cause your own web-page to white-screen for a period of time, or even indefinitely. These types of issues are known as Single Points of Failure, or SPOFs.

There are ways to mitigate against SPOFs, some examples being to include JavaScript references at the bottom of your HTML (or better still to load the JavaScript asynchronously) and to have fallback code options for when third-party services are not available, such as placeholder images/text. Some companies even employ two CDNs and switch between them to ensure that content always comes from the most available source.

However, before you can do any of this, you need to know whether you’ve got a problem. I recently learnt about a great tool to help diagnose such problems, called Spof-o-matic. I know, it’s an awful name, but the tool itself is very good. It can be added to Google Chrome as an extension, and appears as a grey circle at the top right hand corner of the screen:

Spof 1

If the circle remains grey the site you are on doesn’t have any SPOFs. However, if it changes to a warning triangle, SPOFs have been detected:

Spof 2

Clicking on the circle gives more information about the SPOF (in this case it’s to do with Google Fonts):

Spof 3

…and it’s even possible to simulate the SPOF actually failing so you can find out what effect it would have on your site. A smaller red hexagon in the centre of the original grey circle reminds you that you have enabled this:

Spof 4

There’s also a cool feature to generate videos depicting how your site would be behave if the SPOF should occur, via http://www.webpagetest.org/.

So, before you go live with your new site, run it through Spof-o-matic to make sure your user experience will not be destroyed if third-parties you rely on let you down.

Taking databases offline in SQL Server 2012

Whenever I try and use the Take Offline feature in SQL Server 2012 via SQL Server Management Studio, the progress window hangs, and no matter how long I wait, nothing seems to happens.

I found an alternative way to do this today, which solves the problem nicely. Simply run the following T-SQL:

ALTER DATABASE {DatabaseName} SET OFFLINE WITH ROLLBACK IMMEDIATE

…and the database goes offline, ready for other operations such as database restores to be performed.

Keeping up with technology

It can sometimes be frightening how quickly the IT world changes. Almost every week something is released that promises to be the “next big thing” that will “revolutionise the way we develop applications”. A lot of my colleagues populate their “learn next” list by reading Twitter, but personally this approach doesn’t work for me as I don’t scroll through my feed very often, and when I do I’m not usually in a good place to start reading more about a new technology and delving into a “Hello World”.

Instead, a colleague recommended the ThoughtWorks Technology Radar. It’s updated about twice and year and suggests Techniques, Tools, Platforms and Languages & Frameworks to look into.

For me it was quite intimidating at first when I realised I didn’t recognise most of the things on the list, but even just finding out what each thing is can be extremely helpful when solving everyday IT problems. Not only that, but it solves the difficult problem of knowing which horses to back. There simply isn’t time to learn about every new bell and whistle on the market, but the Technology Radar helps by suggesting which tools to trial.

Thanks ThoughtWorks!

Some useful DOS commands

Useful DOS commands I’ve come across:

  1. Write to file
    [cmd] > [file]

    The result of the command on the left will be written to the file on the right. The file will be created if it doesn’t already exist, and overwritten if it does.

    Example:
    echo abc > c:\temp\myfile.txt

    Writes the text ‘abc’ to a new file called c:\temp\myfile.txt

  2. Append to file
    [cmd] >> [file]

    The result of the command on the left will be appended to the file on the right. If the file doesn’t exist it will be created.

    Example:
    echo abd >> c:\temp\myfile.txt

    Appends the the text ‘abc’ to the file c:\temp\myfile.txt

Basic Log4Net step-up

The following post explains how to get Log4Net working in a .NET console application.

The first step is create your console application and add references to Log4Net. The easiest way to add the correct references is via NuGet, where it is simply listed as log4net.

You’ll need to add a configuration file to tell Log4Net how you want it to log. A basic example would be:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>

  <log4net>
    <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
      <file value="Test.log" />
      <appendToFile value="true" />
      <maximumFileSize value="5000KB" />
      <maxSizeRollBackups value="50" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%utcdate{yyyy-MM-dd HH:mm:ss.fffffff} - %level - %logger - %message%newline" />
      </layout>
    </appender>
    <root>
      <level value="DEBUG" />
      <appender-ref ref="RollingFile" />
    </root>
  </log4net>
  
</configuration>

This example simply adds a rolling log file. It’s called rolling because it starts a new log file at triggered intervals, allowing you to delete historical log files when you’ve finished with them. In this case, a new log file is started each time the current log file gets to 5000KB. It’s worth taking a look at the Log4Net documentation to find out about the different types of logging available. It is also possible to write your own appender if you want to do something not already built it to Log4Net.

In order to tell Log4Net to pick your configuration, you need to add the following to your application:

[assembly: XmlConfigurator]

The most obvious place for this is the AssemblyInfo.cs file.

This tells Log4Net to look in the default configuration file for the Log4Net configuration settings, but you can also tell Log4Net to look in another custom configuration file using the overloads available to the XmlConfigurator, although I prefer to keep all configuration in a single file.

Then it’s just a case of using the logger:

using System;
using log4net;

namespace Test
{
    public static class Program
    {
        public static void Main()
        {
            var log = LogManager.GetLogger(typeof(Program));
            log.Debug("Test console application started");

            Console.ReadLine();
        }
    }
}

Note that the LogManager returns an object implementing the ILog interface.

If you’re using dependency injection, you should wire up the dependency injector to return your ILog instance. The following shows how to do this if you’re using Castle Windsor:

using Castle.MicroKernel.Registration;
using Castle.Windsor;
using Castle.Windsor.Installer;
using log4net;

namespace Test
{
    public static class Injector
    {
        private static readonly object InstanceLock = new object();

        private static IWindsorContainer instance;

        public static IWindsorContainer Instance
        {
            get
            {
                lock (InstanceLock)
                {
                    return instance ?? (instance = GetInjector());
                }
            }
        }

        private static IWindsorContainer GetInjector()
        {
            var container = new WindsorContainer();

            container.Install(FromAssembly.This());

            RegisterInjector(container);
            RegisterLog(container);

            return container;
        }

        private static void RegisterInjector(WindsorContainer container)
        {
            container.Register(
                Component.For<IWindsorContainer>()
                    .Instance(container));
        }

        private static void RegisterLog(WindsorContainer container)
        {
            container.Register(
                Component.For<ILog>()
                    .Instance(LogManager.GetLogger(typeof(Injector)))
                    .LifestyleSingleton());
        }
    }
}

The following statement will return an ILog instance as expected:

var log = Injector.Instance.Resolve();

There you have it!