One of the new features that was made available with v1.4.0 of the BRE Pipeline Framework (see this post for a summary of new features) was the ability to make use of XML based vocabulary definitions in the BRE execution policy called by the BRE Pipeline Framework pipeline component. The framework is also able to cater for multiple different message types being assessed by the same policy. This opens the door to a whole new range of possibilities as unless you are calling on BRE Policies programmatically and are very familiar with the BRE, chances are you thought that you could only make use of XML based facts in orchestrations (or hadn’t even realized that there are nuances involved in dealing with them outside of orchestrations).
A bit of theory first (skip the next two paragraphs if you want to get straight into the practical usage of the framework)… When you pass in an XML message into the Call Rules shape in an orchestration what happens under the hood is that the orchestration instantiates an object of type Microsoft.RuleEngine.TypedXmlDocument (definition contained within the Microsoft.RuleEngine assembly) whose constructor takes in the document type and the message body’s stream. This object is what corresponds to XML based vocabulary definitions, the document type property of the object helping the BRE assess which vocabulary definitions are related to the message being dealt with.
Thus in order for the BRE Pipeline Framework to manipulate XML based facts we must be able to instantiate a TypedXmlDocument object and assert it into the BRE execution policy where we can assess and update XML messages using XML based vocabulary definitions. In order for this to be done the framework must be told what the message type is so that the TypedXmlDocument can be constructed appropriately. The BRE Pipeline Framework architecture lends itself well to this situation since the pipeline component calls two BRE Policies. It first calls what is called an InstructionLoaderPolicy (this is optional and only done if the InstructionLoaderPolicy parameter on the pipeline component is populated with a value) which is used for resolution and to assert necessary facts into the ExecutionPolicy which is the next BRE policy that is called to perform message inspection and updates. It is in the InstructionLoaderPolicy that we will instantiate the TypedXmlDocument.
On to the practical stuff… I came up with a hypothetical scenario whereby we want to build a BizTalk application that receives Shipment and Employee messages on a file receive port and writes them out on a file send port. If Shipment messages contain boolean elements indicating that it is a priority shipment and is fragile then I want to set the VIP element to true. If Employee messages contain an element indicating that an employee has worked for greater than or equal to 5 years then I want to set an element denoting that he is due for a reward to true. The schemas structures and example messages (both of which match the conditions of the aforementioned rules) are below.
First things first, lets setup the receive pipeline which contains the BRE Pipeline Framework component. Note that I have used an XML Disassembler pipeline component prior to the BRE Pipeline Framework component, we’ll touch upon that later. Note that I have set an InstructionLoaderPolicy and ExecutionPolicy (also note that I set the ApplicationContext…this is meant to be optional but the current version of the BRE Pipeline Framework has a bug whereby the rules will crash if an ApplicationContext value is not supplied…to be fixed in the next minor version).
The next thing is to create rules in our InstructionLoaderPolicy to check the incoming message’s root node name and namespace and to appropriately create and assert a TypedXmlDocument. The vocabulary definitions you’ll want to use for assessing the root node name and namespace are the GetMessageRootNodeName and GetMessageRootNodeNamespace in the BREPipelineFramework vocabulary (first introduced in v1.1). If you had executed an XML Disassembler pipeline component prior to the BRE Pipeline Framework component then these utilities will assess the BTS.MessageType context property of the message, if not then they will run XPath statements against the message which is of course more expensive so if possible you should resolve the BTS.MessageType before calling the BRE Pipeline Framework pipeline component.
To create the TypedXmlDocument object you will want to use the SetTypedXmlDocument vocabulary definition in the BREPipelineFramework vocabulary (first introduced in v1.1) in a rule’s action, and you will want to pass in the fully qualified class name of the corresponding XML schemas as below.
You can now use XML based vocabularies in your ExecutionPolicy as below (note that I have used friendly business terms for the display values of my vocabulary definitions), which would not have been possible if we hadn’t asserted the TypedXmlDocument in the InstructionLoaderPolicy.
The below Shipment file will now be converted to the file on the right.
And the below Employee file will be converted to the file on the right.
I have uploaded a sample solution to my Google drive. If you download it and import\install the MSI file (make sure you’ve already installed the latest version of the BRE Pipeline Framework and imported all vocabularies) that will install the application for you. You will have to create folders corresponding to the receive location and send port and you will find sample files in the root folder of the package.