Random ramblings about Technology

  • Adding a new BizTalk Server Isolated Host needs a new Application Pool

    Recently, we tried creating a secondary Isolated Host to separate receive and send processing for WCF. After reconfiguring the servers, we were faced with the "Receive location for address '' not found. (The BizTalk receive location may be disabled)". Puzzled, we looked around for configuration issues. After some reading (http://technet.microsoft.com/en-us/library/aa559328.aspx), we remembered a new isolated host needs a new application pool. Adding another application pool to the mix the the new host fixed our trouble... Jotted down for posterity ;-)
  • Running Virtual Machines under alternate user credentials on a Domain Controller

    Introduction

    Recently, I was experimenting with Team Foundation Server 2008, setting it up with SSL and running it within a test domain. For the Team Foundation Server, I couldn't use the host installation as it runs Windows Server 2003 R2 x64 edition and TFS doesn't support (see the TFS installation guide, under 'Overview of Team Foundation Architecture', '64-bit Support in Team Foundation') this setup in a single server scenario. So, I installed Virtual Server 2005 R2 SP1, installed TFS on top, configure SSL and voila, a working TFS setup.

    When I shut down the host computer, I want the virtual machine of TFS to save state and come back up again when the host is turned on again. This can be done in Virtual Server using an alternative use running the actual Virtual Machine instance. Trying to set this up in a least privilege way proved not to be obvious from documentation, so this blog entry documents what I did for posterity (and myself ;-)).

    Outline

    Here's what needs to be done in order to circumvent obscure error messages:

    1.       We need a new user group so the account we'll use doesn't belong to default domain users and inherits no permissions.

    2.       We need a new user to run the Virtual Machine instance, the user should belong to this group only.

    3.       The user needs to be given 'Local on locally' rights.

    4.       Permissions need to be set on the folder containing network configuration information for Virtual Server.

    5.       Permissions need to be set on the folder containing the Virtual Machine and the actual files (*.vhd, .vmc) making up the Virtual Machine.

    6.       The Virtual Machine needs to be configured to use the new user.

    Instuctions

    Let's configure the necessary elements.

    1. Create a new group

    Create a new group within the Active Directory Users and Computers MMC snapin (found under Administration Tools):

    emptygroup

    2. Create a new user

    Create the user which is to run the specific Virtual Machine (done from the same MMC snap-in), add it to the 'empty' group, set the 'empty' group as it's Primary Group and remove the 'Domain Users' group from the list. After this, your user overview should resemble this image:

    vmuser

    3. Assign 'Log on locally' rights to the user

    This step is critical in getting the Virtual Machine running under the new user context. Steps to achieve the appropriate right setting are described here. If the user doesn't receive the 'Log on locally' right, Virtual Server will display an error: 'The account name and password could not be set. The virtual machine account could not be set. The account has not been granted the requested logon type.'. Make sure the security policy is updated before using the account.

    4. Set permissions for the used virtual network interface

    Now that we have the user and it's group configured, let's set the appropriate permissions for the user to make use of the configured network. Mind you, these instructions will only allow the user to use the network it's given access to from the instructions, the 'local network only' et al will not work as the user has no rights on the files used for those configurations.

    The virtual network configuration files for Virtual Server are stored in %SystemDrive%\Documents and Settings\All Users\Application Data\Microsoft\Virtual Server\Virtual Networks. The user needs permissions as specified in order to use the network. If permissions are set incorrectly, the Virtual Machine will not have network access.

    networkpermissions

    5. Set permissions on Virtual Machine folders and files

    In order to start up the Virtual Machine, save state, etc, the new user needs access rights on the folder storing the actual files making up the Virtual Machine as well as specific rights on the Virtual Machine files. The folder structure containing my Virtual Machine files is:

    %SystemDrive%\vms\<Virtual Machine>

    First, let's set the appropriate rights on the folder hosting all Virtual Machines:

    mainvmfolderpermissions

    Now, let's set the permissions for the appropriate Virtual Machine ('tfs') folder:

    vmfolderpermissions

    Lastly, set up permissions for the Virtual Machine files (my TFS has 3: tfs.vmc, tfs.vhd and sql.vhd):

    vmpermissions

    6. Configure the Virtual Machine

    All permissions are set, we're ready to configure Virtual Server to run the Virtual Machine under the new user context:

    configure virtual machine

    Wrap up

    That's it! We've configured the Virtual Machine to run under a user context which has the least amount of privileges it needs to function correctly. The Virtual Machine will save it's state when the host is shut down and will automatically turn back on when the host comes back online.

    HTH

  • Fixing exception messages on the .NET Compact Framework 3.5

    FWIW: I recently ran into trouble while developing for the .NET Compact Framework, v3.5. Upon all exceptions, the framework would tell me:

    "An error message is available for this exception but cannot be displayed because these messages are optional and are not currently installed on this device. Please install ‘NETCFv35.Messages.EN.wm.cab’ for Windows Mobile 5.0 and above or  ‘NETCFv35.Messages.EN.cab’ for other platforms. Restart the application to see the message."

    Interpreting the message as 'I have to run the NETCFv35.Messages.EN.wm.cab (I'm developing an application for WM6) on my device', I copied the file from C:\Program Files (x86)\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\Diagnostics onto my mobile device and ran the installation.

    To no avail, nothing changed and I was stuck. After installing the 'Power Toys for .NET Compact Framework 3.5', however, I configured logging using the '.NETCF Logging Configuration' application and found the following error for the loader log:

    'Attempt to load [\Program Files\SomeApp\System.SR.dll] has failed (err 0x80001000).'

    Renaming the file 'SYCCFA~1.001', included in the aforementioned CAB file into System.SR.dll and adding it as a reference in my application proved to fix the issue. I now had readable exception messages.

    Just jotting this down as there's nothing to be found on the web regarding the issue that I could find.

  • Testing WCF service implementations

    When writing WCF implementations, or any code for that matter, testing is an important part of the process. This week, I was building tests for implemented WCF services and had difficulty aligning all the external dependencies of the tests (running hosts, configuration settings, behavior component references, etc). As a result, I set up my WCF services to be self-hosted services, run from the context of the test itself. This has several advantages, and some pitfalls. The advantages:

     

    ·         Isolation, the test has external dependencies only to the actual service implementation.

    ·         No manual setup running hosts to ensure they are available, the test ‘just works’.

     

    The pitfall might be:

     

    ·       Configuration settings could become out-of-sync. Because the host of the service implementation runs within the context of the test and thereby it’s AppDomain, you need to configure the service ABCs within the test configuration file. This could mean over time you’d get configuration settings for the tests no longer in sync with the actual host.

     

    However, because the scope of the tests is under your control and so is it’s configuration, the described pitfall might not pose an issue.

     

    In order for the test to host it’s own instance of the services to be tested I created a generic container. It’s a simple, but effective, class which can easily host different service types (all tracing and the IDisposable implementation removed for clarity):

     

    /// <summary>

    /// Defines a generic implementation of a runnable background host.

    /// </summary>

    /// <typeparam name="T">The service to run within the host.</typeparam>

    public class RunnableBackgroundHost<T> : IDisposable where T : class, new()

    {

    internal AutoResetEvent stopEvent = new AutoResetEvent(false);

     

    /// <summary>

    /// Starts the host on a new thread.

    /// </summary>

    public void Run()

    {

                ThreadPool.QueueUserWorkItem(

    new WaitCallback(delegate(object state)

                {

                    using (ServiceHost host = new ServiceHost(typeof(T)))

                    {

                        host.Open();

     

                        stopEvent.WaitOne();

     

                        host.Close();

                    }

    }));

    }

     

    /// <summary>

    /// Stops the running host.

    /// </summary>

    public void Stop()

    {

    stopEvent.Set();

    }

    }

     

    Using this class, testing services become quite easy. Set up the host before starting the test:

     

    [System.Diagnostics.CodeAnalysis.SuppressMessage(

    "Microsoft.Performance",

    "CA1812:AvoidUninstantiatedInternalClasses"), TestClass]

    class HostInit

    {

    protected static RunnableBackgroundHost<Service1> service1;

    protected static RunnableBackgroundHost<Service2> service2;

     

    [AssemblyInitialize]

    public static void AssemblyInitalize(TestContext context)

    {

    service1 = new RunnableBackgroundHost<Service1>();

    service2 = new RunnableBackgroundHost<Service2>();

     

    service1.Run();

    service2.Run();

    }

     

    [AssemblyCleanup]

    public static void AssemblyCleanup()

    {

    service1.Stop();

    service2.Stop();

    }

    }

     

    And set up your test, using a generated proxy (svcutil) and assuming the service is alive:

     

    [TestClass]

    public class Service1Tests : IDisposable

    {

    private Service1Client service1Client;

     

    [TestInitialize]

    public void TestInitialize()

    {

    service1Client = new Service1Client();

    }

     

    [TestMethod]

    public void TestService1Method1()

    {

    Service1Request request = new Service1Request();

    request.Id = "1";

     

    Service1Response response = service1Client.Method1(request);

     

                Assert.IsNotNull(response, ErrorMessages.NullResponse);

                Assert.AreEqual<int>(

    response.Field,

    1,

    ErrorMessages.NonMatchingId);

    }

    }

     

    ErrorMessages is a simple resource file containing the messages the test would display in case of failure.

     

    What the test framework does in this case:

     

    ·         Call the static method HostInit.AssemblyInitalize marked with [AssemblyInitialize].

    ·         For every class within the test marked with [TestClass]

    o    Call any instance method marked with [TestInitialize].

    o    Run any method marked with [TestMethod].

    o    ...

    ·         Call the static method HostInit.AssemblyCleanup marked with [AssemblyCleanup].

     

    Within the test configuration file, configure both the service host and the client:

     

    <system.serviceModel>

    <client>

    <endpoint

    address="http://localhost:8889/Services/Service1"

    binding="basicHttpBinding"

    contract="IService1" />

    </client>

    <services>

    <service name="Service1">

    <endpoint

    address="http://localhost:8889/Services/Service1"

    binding="basicHttpBinding"

    contract="IService1" />

                      </service>

    </services>

    </system.serviceModel>

     

    That’s the basic setup. You can now easily test different services by defining the tests for it in it’s own class using it’s own generated client proxy and adding the service to the HostInit class. You could test behaviors by adding them to the configuration file and writing a test for them if they can be tested from the outside.

     

    Just press SHIFT+ALT+X to run the test in the debugger. No console windows popping up, your test just executes :).

  • WCF Message validation (1) – WCF samples to the rescue

    Recently, I needed to validatie messages going into a WCF service. It turned out the WCF samples are a rich source of knowledge and I found a sample which performs XMLSchema-based validation in \TechnologySamples\Extensibility\MessageInspectors.

     

    The sample contains a few classes:

    • ClientValidationException.cs
      • Defines exceptions where validation fails clientside
    • SchemaValidationBehavior.cs
      • Defines an implementation of IEndpointBehavior in order to be an extender for defined endpoints
    • SchemaValidationBehaviorExtensionElement.cs
    • SchemaValidationMessageInspector.cs
    • ValidationFault.cs

    The sample uses a property called Schemas within it’s configuration, allowing us to define which schemas should be taken into account when validating.

     

    <schemaValidator validateRequest="True" validateReply="True">

    <schemas>

    <add location="messages.xsd" /> 

    </schemas>

    </schemaValidator>

     

    That’s great, but as you all probably know, WCF services have the ABC’s: Address, Binding and Contract. What I actually wanted the behavior to do was validate my message against the actual Contract of the endpoint the validator was working on.

    In order for this to work, I did two thing:

     

    1.       I removed all “Schemas” configuration and arguments from the code.

    2.       I modified the SchemaValidationBehavior class to validate the actual contract.

     

    The first steps should be self-explanatory, but the second I want to elaborate on. What I actually did was modify the methods ApplyClientBehavior and ApplyDispatchBehavior. The sample took the configured Schemas property to create the actual SchemaValidationMessageInspector:

     

    SchemaValidationMessageInspector inspector =

    new SchemaValidationMessageInspector(

    schemaSet, validateRequest, validateReply, false);

     

    I wanted to dynamically use the endpoint contract:

     

    WsdlExporter exporter = new WsdlExporter();

    exporter.ExportContract(endpoint.Contract);

     

    SchemaValidationMessageInspector inspector =

    new SchemaValidationMessageInspector(

    exporter.GeneratedXmlSchemas,

    validateRequest, validateReply, false);

     

    After modifying both methods to perform this kind of setup, it was easy to configure validation based on the endpoint contract (some elements abbreviated for clarity):

     

    <system.serviceModel>

    <services>

    <service name="SomeService">

    <endpoint

    address="SomeAddress"

    binding="wsHttpBinding"

    contract=" ISomeService"

    behaviorConfiguration="SomeServiceEndpointBehavior" />

    </service>

    </services>

     

    <behaviors>

    <endpointBehaviors>

    <behavior name="SomeServiceEndpointBehavior">

    <SchemaValidator

    validateRequest="True"

    validateReply="True" />

    </behavior>

    </endpointBehaviors>

    </behaviors>

     

    <extensions>

    <behaviorExtensions>

    <add

    name="SchemaValidator"

    type="SchemaValidationBehaviorExtensionElement, ..."/>

    </behaviorExtensions>

    </extensions>

    </system.serviceModel>

     

    That’s it, now we have a service endpoint validated based on it’s WSDL contract.

     

    The sample code is attached for your enjoyment.

  • Shockwave Flash preview handler for Windows Vista and Outlook 2007.

    Based on the excellent article from Stephen Toub, I was inspired to write a Shockwave Flash preview handler. Basically, it's just a plain UserControl which hosts the ActiveX wrapper for the player. It works from both Outlook 2007 and Windows Vista. The installer is attached.

    Shockwave Flash preview handler in action

  • Programmatic BizTalk Server Orchestrations - code repost

    A previous post of mine had some sample code on creating BizTalk Server Orchestrations programmatically, opening up template based guidance packages. The sourcecode for the sample can now be found here.

  • BizTalk Server Pipeline Component Wizard moved

    As we are phasing out GotDotNet, projects need a new location to be hosted. I've moved the BizTalk Server Pipeline Component Wizard to it's new location. Please find it here.