Selectively "Eating" Messages in BizTalk Send Ports
This week I met with a healthcare customer who is using BizTalk to build a robust publish-subscribe architecture. One component
of this involves making last second decisions to either send or "eat" messages going out to a send adapter. I put together
a quick sample to demonstrate how you can selectively eat messages on the way out of BizTalk.
The core logic for this naturally resides in a custom pipeline component. Mine, called "EatMessage", is a (any) send pipeline.
I have some custom properties that enable this component to be reused in multiple scenarios. The code looks like this:
public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
{
//grab value out of context using property fields
object eatField = inmsg.Context.Read(_FieldName, _FieldNS);
//if that value exists
if (eatField != null)
{
//compare the context value to the property condition
if (eatField.ToString() == _EatCondition)
{
System.Diagnostics.EventLog.WriteEntry("Custom Pipeline", "Message Eaten");
//eat the message
return null;
}
else
{
return inmsg;
}
}
else
{
return inmsg;
}
}
So as you can see, I've got some design time properties that store the context property value and namespace, and a field
that is used to determine whether to eat the message or not. For instance, the _EatCondition might be equal to "true", which
means if the context value equals "true" then eat the message. Or, it could be a date, or number, or whatever.
Next I build my schema. Basic stuff, contains a node called DoNotSend which I'll set via a map, prior to sending the message
through the pipeline.
I then created a property schema with the one promoted EatValue node. I could reuse this with multiple different schemas.
Now the fun part. I created a new Send pipeline in my BizTalk project. I first drop the XML Assembler component, then plop
down the MessageEater component. As you can see here, there are the three properties I use later in the code.
Finally, I create a map. This map uses functoids to see if the Patient ID is a certain value, and if so, sets the DoNotSend
node to true. Otherwise, sets it to false.
After deploying the project, I created a send port to the FILE system. In it, I selected my new Send pipeline, and, the map. Since
the order of processing in a send port goes "Map --> Pipeline" I can be sure that the map outcome will feed the latest data to my pipeline component. After
building and testing, indeed, when I send a file through BizTalk with one particular Patient ID the message never comes back out, and
DOES get dropped if the Patient ID equals something else. Nice.
Technorati Tags: BizTalk
Comments
- Anonymous
August 01, 2006
Very nice indeed.
I used a similar approach in a receive pipeline. The Pipeline did a simple xpath query and if it met a condition the message would be eaten.
A great advantage of this that BizTalk doesn't get clobbered with unwanted messages. - Anonymous
August 01, 2006
Yes. receive pipeline is an ideal spot if it works for the given scenario. And, if you can use streaming XPath, you can get away with any performance hit of looking up nodes in the DOM.