XmlDisassemble in a passthrough pipeline?
So, I a couple of weeks ago now I opened a case on Connect, and this is just to wrap it up in a blog-post for discovery and archive purposes.
We use BAM for infrastructure tracking. We apply a simple tracking profile to all our ports for all our customers in all our environments. BAM does this like a charm, and handles the clean up, indexing, and archiving of this data automatically by schedulable jobs – tunable to customer requirements. Many times BizTalk will be used to do file transports without really caring about the content, alongside the more traditional transformation or orchestration work. Other times the requirements might cause me to want to bring in a file in BizTalk to handle things like processing, disassemble, splitting or something else in one (or more) orchestrations. To me, nothing strange with this, and I’m hardly alone in this.
Even though the passthrough pipeline is used, with BAM tracking, disassemble of the incomming file will be attempted or performed. This might result in disassemble errors and/or debatching of message with envelopes were that was not intended.
If you do BAM tracking and apply that to a port that has the passthrough pipeline on it the code will create a xmldisassembler as part of the BAM tracking process in the passthrough pipeline. If this does not find what it considers XML through it's Probe method, things seem fine. Otherwise this can create issues. Two that we have identified is:
- If the message passed through the passthrough pipeline matches that of an envelope schema deployed to BizTalk it will be debatched into the first document by the pipeline.
- if the document contains faulty xml - pipeline processing will get an exception.
Why does this happen?
Looking through the code with Reflector gives us some insights. The ReceivePipeline class, base class of the PassThruReceive class implements the GetNext member. Towards the end of that code the below code is present:
msg = base.DoBamTracking(msg, Pipeline.BamTrackingMode.BamTrackingOnly);
The DoBamTracking method (which resides in the even more generic Pipeline class) decides whether or not BAM tracking is necessary be looking at some context properties (supposedly populated by the fact that I’ve applied a Tracking Profile and mapped it to the port in which context the pipeline is running). If it is it then creates a XmlDasmComp component and Probes the message. If Probe returns false, then we are, as stated above, fine. If not… later in the code it will use the (XmlDasmComp) component to run Disassemble followed by its GetNext implementation and return the result. The result: A disassemble message – if it succeeds that is.
IBaseMessage Pipeline.DoBamTracking(IBaseMessage, BamTrackingMode)
IBaseComponent component = PipelineManager.CreateComponent(
Version=220.127.116.11, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL");
IProbeMessage message2 = (IProbeMessage) component;
if (!message2.Probe(this.pipelineContext, msg))
IDisassemblerComponent component2 = (IDisassemblerComponent) component;
next = component2.GetNext(this.pipelineContext);
Steps to reproduce
- Deploy a envelope schema and a document schema.
- Set up a BAM activity with at least one field.
- Connect the BAM element in the tracking profile to something.
- Create a receive port with a passthrough pipeline.
- Connect the tracking profile to the receive port.
- OPT 1) Send a message through with badly formed xml, like a one line message with only the text "<TestMessage>" (xmldisassembler exception). OR
OPT 2) Send a valid envelope with two document in it through (debatch will occur and leave only the first document).
Code to reproduce
contains artifacts built for 2010)
contains 2006 (R2)/VS.NET 2005 artifacts.)
I have tested this in 2010, 2009, 2006 R2 SP1 CU3 - all have the issue.
Are you experiencing this issue?
If you are having this issue and want it fixed, vote it up on Connect and mark is as reproducible.
Further, we have found that to stop this from happening on a port the only way is to to re-create it. Removing the port mapping in the tracking profile for some reason is not sufficient.