Monthly Archives: March 2012

Using Amazon SES for .Net Application Mail Delivery

Until March 2012 Amazon’s Simple Email Service (SES) had limited support for mail being sent via existing .Net code and the IIS SMTP virtual server.  Some recent changes mean this is now possible so in this post I’ll quickly cover how you can configure your existing apps to utilise SES.

If you don’t understand why you should be using SES for your applications then you should be looking at the Amazon SES FAQ and before you start any of this configuration you need to ensure that you have created your SMTP credentials on the AWS console and that you have an appropriately validated sender address (or addresses).  Amazon is really strict here as they don’t want to get blacklisted for being a spammer host.

IIS Virtual SMTP Server

Firstly, let’s look at how we can setup the SMTP server as a smart host that forwards mail on to SES for you.  This approach means that you can configure all your applications to forward via IIS rather than talking directly to the SES SMTP interface.

1. Open up the IIS 6 Manager and select the SMTP Virtual Server you want to configure.

1.iis_virtual_smtp

2. Right-click on the server and select Properties.

3. In the Properties Window click on the Delivery tab.

4. On the Delivery tab click on the Outbound Security button on the bottom right.

5. In the Outbound Security dialog select “Basic Authentication” and enter your AWS SES Credentials.  Make sure you check the “TLS Encryption” box at the bottom left of the dialog.  Click OK. Your screen should look similar to this:

2.delivery_setup

6. Now open the Advanced Delivery dialog by clicking on the button.

7. Modify the dialog so it looks similar to the below.  I put the internal DNS name for my host here – the problem with this is that if you shut off your Instance the name will change and you need to update this.  Click OK.

3.advanced_delivery

Now you should be ready to use this IIS SMTP Virtual Server as a relay for you applications to SES.  Make sure you set AWS SecurityGroups up correctly and that you are restricting which hosts can relay via your SMTP server.

Directly from .Net Code

Without utilising the Amazon AWS SDK for .Net you can also continue to send mail the way you always have – you will need to make the following change to your App.config or Web.config file.

<mailSettings>
      <smtp deliveryMethod="Network" from="validated@yourdomain.com">
          <network defaultCredentials="false"
                   enableSsl="true"
                   host="email-smtp.us-east-1.amazonaws.com"
                   port="25"
                   userName="xxxxxxxx"
                   password="xxxxxxxx" />
      </smtp>
</mailSettings>

Thanks to the author of the March 11, 2012 post on this thread on the AWS support forums for the configuration file edits above.

With these two changes most “legacy” .Net applications should be able to utilise Amazon’s SES service for mail delivery.  Happy e-mailing!

Tagged , , , ,

Doing the Shimmy Fake (VS11 Beta Unit Test Isolation).

I’m sure many of you have read of or heard about the Moles Power Tool that shipped as an add-on to the original Visual Studio 2010 release back in 2009. There was certainly a lot of speculation about which way this Microsoft Research project would go.

The great news is that with the impending Visual Studio “11” release it appears the Moles Power Tool is now baked into the Microsoft.QualityTools namespace.

I first read about this on the MSDN ALM blog which I’d recommend you go and have a look at. My first thought was that the new Shim Fake is essentially what a Mole was previously. In writing up a few simple test cases my hunch was confirmed (see the tooltip reads “Sets the mole of…”:

fakemole

(I expect this will change before the RTM release though!)

So what can you do with a Shim? A Shim allows you to redirect calls to a method to a delegate you control which means you can control flow in tests that might otherwise have been blocked. Where I’ve used this heavily previously was with SharePoint 2010 classes and with the System.Configuration namespace.

You need to do a bit of work to create the baseline for a Fake – firstly the assemblies must be referenced in your Unit Test project in Visual Studio – right click on the assembly under “References” and choose “Add Fake Assembly”:

The Add Fakes Assembly context menu item.

Visual Studio will add some XML files that define the Fake and a new reference will appear that represents the Fakes:

Solution Explorer with Fakes.

A Simple Example

The easiest way to show how this all works in your favour is with a simple example. Firstly let’s assume we have a simple helper class that utilises System.IO.File. In the past we would have had to resort to 3rd party products to redirect any calls to System.IO.File so that we can test the code around the call. Here’s our File helper class definition:


public class FileWriter
{
     public void AppendContentsToFile(string filePath, string conentToAppend)
     {
         try
         {
             System.IO.File.AppendAllText(filePath, conentToAppend);
         }
         catch (Exception ex)
         {
             // log and throw.
         }
     }
}

And now let’s see how we use a Shim to allow us to test the FileWriter AppendContentsToFile method. The important elements to note are: using the Fakes namespace so that you can create a ShimContext which is needed to use a Shim. You’ll also notice that the Shim has a different class name and that the method combines the name and type of each parameter. If you don’t use a ShimContext your test will fail, but helpfully the test runner will actually provide a code sample of what needs doing in order to fix the test.

By using an anonymous delegate we provide a redirection of the call to a method we write and control. This quickly becomes a powerful way to isolate just your code from underlying Framework methods.


using Microsoft.QualityTools.Testing.Fakes;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using UnitTestingDemoApp;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestFileWriterAppendContents()
        {
            using (ShimsContext.Create())
            {
                var writer = new FileWriter();

                System.IO.Fakes.ShimFile.AppendAllTextStringString = (file, contents) =>; AppendStringToFile(file, contents);

                writer.AppendContentsToFile(&quot;C:\\some\\path\\afile.text&quot;, &quot;somecontents&quot;);
            }
        }

        private void AppendStringToFile(string filePath, string textToAppend)
        {
            // perform some logic, maybe throw exceptions.
        }
    }
}

This is a simple example of how Shims can be used – right now beyond MSDN there isn’t a lot of detail about but if you read up on Moles you will quickly get the idea.

And the Shimmy Fake? Well, I tip my hat to Australian kids entertainers the Wiggles and their Shimmy Shake from 2008…

Tagged , , , , ,

Configure Mercurial Pull with HTTP Authentication for Jenkins on Windows

As part of the journey our team is going on in 2012 I am looking to migrate our processes and tools to a more scalable and maintainable state.  One of the first items to look at was the replacement of that early cornerstone of CI – CruiseControl.  Our existing server was aging and was running on a platform that meant Azure SDK support was unavailable.  To resolve this I moved to a new machine and new CruiseControl build only to discover that the Mercurial features don’t work.

After an initial clone the CC builds failed – having spent time investigating I decided to see what else was about that allowed us to do centralised builds.  Bearing in mind this is a transition state I didn’t want invest a huge amount of time and money in a solution and found the Jenkins CI offering online.  As a bonus it has support (via plugins) for Mercurial and MSBuild so it seemed to fit the bill.

However…

As is always the way things didn’t quite work as I wanted.  Our existing build setup utilises HTTP authentication and not SSH to connect to our hosted Mercurial repositories and when I setup new Jenkins builds I was seeing that each build would clone the entire remote repository again which in some instances is not desirable given their size.  This is what I saw at the top of my build console log:

Started by user anonymous
Building in workspace E:\Program Files (x86)\Jenkins\jobs\XXXXXXXXX\workspace
[workspace] $ hg.exe showconfig paths.default
ERROR: Workspace reports paths.default as https://AAAAAAAA@bitbucket.org/BBBBB/XXXXXXXXX
which looks different than https://AAAAAAAA:PPPPPPPP@bitbucket.org/BBBBB/XXXXXXXXX
so falling back to fresh clone rather than incremental update

So I was scratching my head about this – we’ve always used the inline auth approach but it looked like in this instance the Jenkins Mercurial plugin / Mercurial client was deciding that the inline authentication made the source different enough that it wouldn’t even attempt to do a pull.

Digging around I discovered that the hg command line supports use of “ini” files to set global parameters.  I could theoretically have just set this in the baseline ini file that comes with the Mercurial client but as that file says “any updates to your client software will remove these settings.”

So, how to resolve?

Here are the steps I followed to resolve:

1. Create a new non-admin windows login with a valid password.

2. Grant this login control of the Jenkins folder (and any others that Jenkins may read / write / update).

3. Open up Windows Services and change the Jenkins service logon to be the new logon from (1).

4. Create a .hgrc file in the new windows login’s “C:\Users\<username>\” folder with these contents:

[auth]
bitbucket.prefix = bitbucket.org/BBBBB
bitbucket.username = AAAAAAAA
bitbucket.password = PPPPPPPP

5. Restart the Jenkins Windows Service.

Now when you run your build you will see a much more expected site:

Started by user anonymous
Building in workspace E:\Program Files (x86)\Jenkins\jobs\XXXXXXXX\workspace
[workspace] $ hg.exe showconfig paths.default
[workspace] $ hg.exe pull --rev default
[workspace] $ hg.exe update --clean --rev default
0 files updated, 0 files merged, 0 files removed, 0 files unresolved

Hopefully this post will save you some time if you’re trying to achieve the same sort of thing for your team.

Tagged , , ,