The BizTalk BRE Pipeline Framework has now reached v1.3.0 and I thought it is about time I wrote a blog post on how it can be effectively used, and before I can do that I must also explain how it works.
The very first thing you need to get your head around is the concept of MetaInstructions. A MetaInstruction is a class that derives from BREPipelineFramework.MetaInstructionBase and contains methods that can be used to inspect a message (so you might have a method to get the value of a context property on a BizTalk message or to run XPath against the message body and return the result) using the result of the inspection in condition evaluation, and also can contain methods that are used to instantiate Instructions which will be acted upon in rule action when conditions evaluate successfully. These methods can have whatever signatures you want, an example of a method that is used for inspection is below, and as you can see it is very simple.
An Instruction is a class that implement IBREPipelineInstruction and is used to manipulate a BizTalk message (either the content or the context). An example of a MetaInstruction method that is used to setup an Instruction is below.
All the method in the MetaInstruction does is instantiate the Instruction calling on the relevant constructor and then call the base.AddInstruction method passing in the instruction so that it can be acted upon once condition evaluation is complete. The magic of the Instruction is in the Execute method of the Instruction class which has a very similar signature to the Execute method of a pipeline component, and this is where you would perform any manipulation of your message. Note that any properties of the Instruction class that were instantiated in your MetaInstruction method are available for use in the Execute method.
The next part of the puzzle is that each of the methods in a MetaInstruction class should have a BRE Vocabulary definition created with a friendly representation of the method such as the below.
Now that I’ve explained the basics lets walk through a real life scenario. Let’s say you have a one way WCF service which uses transport security with basic authentication. If the AD user against the message is equal to “Johann” then you want to promote the value “Gold” to the context property CustomerStatus which has a target namespace of http://customerstatus against the message, this context property would then be used to route the message to the appropriate orchestration or send port. The first thing we need to do is to create the appropriate receive pipeline that we will use on our receive location. After installing the BRE Pipeline Framework from the codeplex project page you should have the BREPipelineFrameworkComponent component in your list of pipeline components in the Visual Studio toolbox (if not then right click in the toolbox and select choose items, and make sure you tick the component in the pipeline components tab) which you should then drag to the appropriate stage of your pipeline, lets say decode in this case.
You’ll notice that there are a couple of properties that have been set against the pipeline.
- ApplicationContext – This value can be used in your rules policies to conditionally choose which rules get executed for which pipelines. You can have multiple pipelines all call on the same BRE Policy but because the ApplicationContext is given a different value in each pipeline you can choose which rules will fire when the policy is called by a specific pipeline. Typical usage would be to have the pipeline name or pipeline name + pipeline stage if you have a single pipeline with multiple BREPipelineFrameworkComponent pipeline components.
- Enabled – Defaults to true, if set to false then the pipeline component behaves in a pass through manner.
- ExecutionPolicy – This is the name of the BRE Policy which will evaluate conditions and take actions against your BizTalk message.
- InstructionLoaderPolicy – This is the name of the BRE Policy which will instantiate MetaInstructions for you so that they can be used in your ExecutionPolicy. As of v1.3.0 the out of the box MetaInstructions (contained within the BREPipelineFramework.SampleInstructions.ContextInstructions and BREPipelineFramework.SampleInstructions.HelperInstructions vocabulary definitions) no longer need to be loaded using a InstructionLoaderPolicy. InstructionLoaderPolicies are now only necessary for custom MetaInstructions. If you want more details on how to use these then go to the codeplex project documentation page.
- RecoverableInterchangeProcessing – If this is set to true then the pipeline component will support recoverable interchanges. This means that if you have had a message debatched in the pipeline prior to calling this component then if one of the debatched message fails for whatever reason in this pipeline execution then only that will fail and the rest will succeed. If this is set to false which is the default value then the whole message fails.
So in this case we have set the ApplicationContext to the name of the pipeline and we have set the ExecutionPolicy to BREPipelineFramework.ExecutionPolicy. Next up lets create the BRE Policy and the rule.
In the above rule you’ll notice that we have evaluated the application context so that this rule will only fire for pipelines that specified an application context of Rcv_BREPipelineFramework (the vocabulary definition for the application context is in the BREPipelineFramework vocabulary). On the next line of the condition we have evaluated the value of the BTS.WindowsUser (note that the selection of the context property is from a drop down list since a vocabulary definition has been catered for in the BREPipelineFramework.SampleInstructions.ContextInstructions vocabulary to enumerate all context properties in the BTS namespace as in most common namespaces), choosing to return an exception if the BTS.WindowsUser context property does not exist on the message in question (we could have also chosen to just return a blank value if the property wasn’t found). Lastly in the action we choose to promote the value Gold to the context property in question by specifying the name and namespace of the context property.
What is effectively happening behind the scenes is that in the condition the GetGlobalPropertySchemasContextProperty method in the BREPipelineFramework.MetaInstructions.ContextInstructions MetaInstruction class is called to return the BTS.WindowsUser context property and the ApplicationContext string property is assessed as well. If all the conditions evaluate and the actions fire then the SetCustomContextProperty method in the BREPipelineFramework.MetaInstructions.ContextInstructions MetaInstruction class is called to instantiate a SetContextPropertyPipelineInstruction Instruction object and to call the base.AddInstruction method passing in the instantiated Instruction object. Once all the Instructions have been instantiated then the execute method against each Instruction method will be called to manipulate the message.
Now at runtime if the rules change or need to be extended there is no need to update the pipeline component code and to go through a complex deployment cycle. Instead all you have to do is make a copy of the BRE policy, change or extend your rules and deploy the new version, all with no downtime to your BizTalk applications or any host instance restarts.
I hope this gives you an idea on how to effectively use the BRE Pipeline Framework for your requirements. Feel free to contact me if you have any questions.