Policy based routing using the Business Rule Engine resolver

There are several samples that come with the ESB Guidance installation utilizing the BRE Resolver to resolve the endpoints.  All of them implements a very simple rule that states  {if 1==1 then…}. This can still be useful when you only want to use the BRE for the purpose of having an endpoint repository. In which case you'd create one policy for each endpoint.

But what if you'd like to apply a rule like {if Customer == "Microsoft" then… else..}. Of course the ’else' statement has to be implemented as a new rule, but part from that, this could be very useful if you like to route the message to different endpoint depending on the context of the message. Sort of like Content Based Routing but being able to support more complex scenarios.

Looking at the BRE connection string there is a ’useMsg' property. How to use this property is not described in the documentation, and in all the samples useMsg is set to null (False).

BRE:\\policy=GetCanadaEndPoint;version=1.0;useMsg=;

Setting this property to True, should cause the Resolver Manager to add the message as a fact upon executing the policy. Unfortunately there is a bug in the ResolveProvider in ESB.Resolver.ESB assembly:

Dictionary<string, string> IResolveProvider.Resolve(string config, string resolver, 
    IBaseMessage message, IPipelineContext pipelineContext)
{
    
    // Resolve the params from arguments by creating
    // class from schema, and storing the results
    Resolution resolution = new Resolution();
    XmlDocument xd1 = null;

    try
    {
        // Populate context
        ResolverMgr.SetContext(resolution, message, pipelineContext);

        // resolve with rules and return dictionary
        return ResolveRules(config, resolver, xd1, resolution, message);

    }
    catch (System.Exception ex)
    {
        EventLogger.Write(MethodInfo.GetCurrentMethod(), ex);
        throw;
    }
    finally
    {
        if (null != resolution)
            resolution = null;                
    }
}

The problem is that the XmlDocument xd1 (the actual bts message) is always going to be null, and will cause an null object reference exception to be raised. You will have to fix this by changing it to (line 224):

XmlDocument xd1 = new XmlDocument(); 

The next problem was a little bit trickier to figure out. It seemed the BRE could not match the DocumentType with the actual message. As it turn out, the DocumentType has to be added to the BizTalk context properties before the resolver is executed or it will be set to "Microsoft.Practices.ESB.ResolveProviderMessage".

This means you have to change the DocumentType in the Business Rule Composer.

Then set the useMsg property to True:

BRE:\\policy=GetEndPointByCustomer;version=1.0;useMsg=True;

And implement your rule:

Good luck!