Blog Moved

10 05 2013

Hey there. Just a quick heads up, I’ve moved my blog to http://www.bencode.net





BizTalk Server 2009 Unit Testing

13 06 2010

I feel like i’ve missed the boat with this, but the “first class” unit testing support that has been added to BizTalk Server 2009 is terrific. Unit testing with BizTalk Server up to this point, has always been very involved and custom.

How was this ground breaking feat made possible? A project level build switch has been added to all Visual Studio BizTalk project types. Check it out, bring project properties up for any BizTalk 2009 project in your solution, and there will be an “Enable Unit Testing” true/false flag sitting there.

Setting this to true, instructs the BizTalk MSBuild tasks that take our precious BizTalk artefacts like orchestrations, maps, pipelines and so on and parses and compiles them into MSIL, to add an extra layer of inheritance between for example, our pipeline and the real BizTalk pipeline base class. A whole family of these new “intermediate” testable classes live in the Microsoft.BizTalk.TestTools.dll assembly (available under c:\Program Files(x86)\Microsoft BizTalk Server 2009\Developer Tools\) such as Microsoft.BizTalk.TestTools.Pipeline.TestableReceivePipeline and Microsoft.BizTalk.TestTools.Map.TestableMap.

Now the level resistance to getting effective unit tests up an running is so low, there really is no excuse not to have good repeatable unit tests across all your BizTalk artefacts.

Here’s a small snippet (intended for use as an MSTest unit test) that invokes a BizTalk map, and verifies the resulting output using some LINQ to XML.

[TestClass]
public class MapTests
{
  public MapTests() { }

  public TestContext TestContext { get; set; }

  [TestMethod]
  public void Foo_To_Bar()
  {
    TestableMapBase map = new Foo_To_Bar();
    map.ValidateInput = false;
    map.ValidateOutput = false;
    map.TestMap(
      "input.xml",
      InputInstanceType.Xml,
      "output.xml",
      OutputInstanceType.XML);

    var document = XDocument.Load("output.xml");

    string interchangeId =
      (from header in document.Descendants("Header")
       select (string)header.Element("InterchangeId")).Single();

    Assert.IsTrue(interchangeId.Length > 0);
  }
}





Back To Basics: Sharing Libraries in a Team

13 06 2010

When developing in a team consisting of more members than yourself, you’ll quickly run into the scenario where shared libraries and/or other similar resources need to be shared in someway.

Its especially nice when you can cleanly compile code freshly pulled from source control. In my opinion, this is a must. Sloppiness here can cause heartache throughout the the entire development lifecycle of the project. This problem is aggravated with the introduction of new starters that come on board…they do a get latest, build and spend the next few days crawling through hundreds of build errors.

So what to do with all those third party assemblies that have made their way into the code base? If Alice added the references on her box, checks in, Bob is not going to be happy when he goes to do a “get latest”.

Its at this point most environments i’ve worked within take the laziest and simpliest option. “Hey everyone, we need to make that we all bind source control to the same local working folder (e.g. c:\projects\) mmmkay?”. If everyone has a local working folder of c:\projects, then absolute dll’s references should resolve just fine. While this is simple and can work, is rarely documented beyond the developers that came up with the plan.

What alternatives are there? Several, they all involve adding a layer of indirection, so the physical location of the assemblies is abstracted away from the project references. The simplest and effective strategy I have seen leverages subst (or the more modern symbolic linking support now available in Vista and higher using mklink). The idea is in source control, maintain a hive of pre-built assemblies that are common across the team, for example:

$/Foo.Common.Hive/NUnit.Framework/1.1.23.0/NUnit.Framework.dll
$/Foo.Common.Hive/bLogical.Shared.Functoids/1.0.0.0/bLogical.Shared.Functoids.dll

Bind them to a physical location *anywhere* on your development/build box. Run the following command:

subst q: c:\local\location\of\your\choice\

This will create a virtual drive (q:) on the machine that actually resolves to the contents of the “c:\local\location\of\your\choice\” directory. Visual Studio assembly reference’s should be added through the virtual (q:) drive – hence adding a layer of abstraction. The only catch is all developers need to ensure that the virtual drive is subst’ed prior to building—however on the plus side, I can put the source where I like, and the chances of getting a clean build have been improved significantly.





C# 3.0 Language Extensions

25 12 2008

Put together a little snippet to remind myself of the some of the beautiful language extensions that shipped with the C# language.

namespace CSharpLanguageExperiment
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    class Program
    {
        static void Main(string[] args)
        {
            // Object Initialiser
            Person bill = new Person { FirstName = “Bill”, LastName = “Gates”, Age = 40 };

            // Type Inference
            var ben = new Person { FirstName = “Ben”, LastName = “Simmonds”, Age = 25 };

            // Anonymous Types
            var john = new { FirstName = “John”, LastName = “Smith”, Age = 18 };

            // Anonymous Delegate
            Func<string, bool> filter1 = delegate(string name)
            {
                return name.Length > 4;
            };
            filter1(“hel”);

            // Lambda Expression
            Func<string, bool> filter2 = x => x.Length > 4;
            filter2(“foobar”);

            // Extension Method
            ben.GetData();

            // Queries
            List<Person> people = new List<Person>();
            people.Add(bill);
            people.Add(ben);
            Func<Person, bool> filter = x => x.Age > 30;
            IEnumerable<Person> exp = people.Where(filter);

            foreach (Person person in exp)
            {
                Console.WriteLine(person.GetData());
            }
        }
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }

        public override string ToString()
        {
            return String.Format(“{0} {1}”,
                FirstName,
                LastName);
        }
    }

    // Extension Method
    public static class PersonExtension
    {
        public static string GetData(this Person person)
        {
            return String.Format(“Name: {0} {1} Age: {2}”,
                person.FirstName,
                person.LastName,
                person.Age);
        }
    }
}





70-235 Certified

21 12 2008

A few weeks ago I sat the 70-235 exam. Coming from a real-world perspective I wasnt overly impressed with the exam. To me it felt mind numbingly robotic and very 2006 R1 feature set focused (e.g. BAM and BRE). However the exam successfully probed some interesting areas within BizTalk, encouraging me to learn things about BizTalk that I would not otherwise get exposure to.

Patrick Wellink’s post “How to prepare for the BizTalk 2006 Exam” concisely summarised how to prepare for this exam. At first I sensed some sarcasm in Patrick’s post, but now having successfully passed the exam found his post to be scaringly accurate.

  1. Create a nice BizTalk solution
  2. Use party resolution
  3. Use correlation
  4. Send a message to a web-service that requires authentication
  5. Use a business rule with a database fact
  6. Use business rules that assert and retract
  7. Make sure you deploy the solution
  8. Run messaages through it
  9. See what happens if the orchestrations are not started
  10.   See what happens if the rules are not deployed
  11.   Remeber the name of each tool you use (e.g. orchestration view in VS.NET)
  12.   Know the stages of the pipelines
  13.   Finally create a BAM View in excel
  14.   Deploy the BAM View
  15.   Deploy the tracking profile
  16.   See if it works through the BAM Portal
  17.   Now modify the BAM view
  18.   Update the BAM view
  19.   Do some BAM with continuations
  20.   Know (memorise) your persistence points




XHTML Formatted Messages

21 12 2008

BizTalk messages are very XML centric. A while ago there was a requirement to produce a neatly formatted XHTML report, which was destined to be emailed.

At the time I stumbled across a customised version of the XslTransform pipeline component which ships with the BizTalk SDK. It demonstrates how to apply an XSLT transformation in the pipeline. The customised version I was playing around with, pulled up XSLT from a SQL data store.

Regardless of where or how the transformation be done, we needed to produce an XHTML document as a result. The thing with XHTML is that is it just that. Its XML. A XSD schema can be produced from a well formed piece of XHTML. Therefore it is possible to create a strong message type (e.g. FooReport.xsd) which can then be pub/sub’ed with BizTalk.

High level steps:

  1. Generate the document schema using xsd.exe.
  2. Write the necessary transformation using BizTalk mapper, using the above as the destination schema.
  3. Depending on the client which will be picking up and rendering the XHTML (e.g. outlook, firefox) it is usually necessary to set the MIME type, so it knows to treat the content as a piece of XHTML. To do this from BizTalk set the ContentType context property:
    errorReport(Microsoft.XLANGs.BaseTypes.ContentType) = “text/html”;




BizTalk 2006 Install Problems on WinXP

21 12 2008

Today while doing some vanilla BizTalk 2006 R2 installs, discovered the installer was choking with:

Error 5003.Regsvcs failed for assembly C:\Program
Files\Microsoft BizTalk Server 2006\Microsoft.BizTalk.Deployment.dll.
Return code 1.

Regsvcs

Awesome. Other cases of a malfunctioning regsvcs executable have been reported. For reasons that remain unknown to me regsvcs.exe stop functioning following the installation of SP1 for VS.NET 2005 and the .NET 2.0. regsvscs.exe appeared to be intact, but invoking any of it functionality (including listing its command line help) would return nothing—hence the return code 1 problem.

Solution: Repair the .NET Framework 2.0 binaries. I grabbed a fresh copy of the service pack. It is important that regsvcs.exe functions correctly—you can test it while reinstalling the service pack by running “regsvcs.exe /?“. If it lists out help your good to go.