How to write BAM Events from pipeline components.

In BizTalk 2004, to write any BAM event from the BizTalk pipeline, you will need to write some code 🙂  To simplify the learning, I will illustrate by adapting an SDK sample.

Adapt the SDK CustomComponent (found in …/SDK/Samples/Pipelines/CustomComponent) sample, you will find two directories:

  • FixMsg – the custom pipeline component (you will need to splice BAM code here) 
  • PipelineComponentSample – custom pipeline and will use the above custom pipeline component.

Modify the FixMsg to include the below sample (Search for Execute method):

public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)

IBaseMessagePart bodyPart = inmsg.BodyPart;
if (bodyPart!=null)

//Splice BAM Code here:
WriteBAMEvent(pc, “Execute”, inmsg);

return inmsg;


// Add a new method to write to BAM

private void WriteBAMEvent(IPipelineContext context, string StageDescription, IBaseMessage inmsg)

EventStream _BAMEventStr = null;
// Create an EventStream instance

// Use can use BES/DES or MES
// DES – DirectEventStream – writes direct to BAMPrimaryImport (Synchronous call, no latency)
//_BAMEventStr = new DirectEventStream(“Integrated Security=SSPI;Data Source=.;Initial Catalog=BAMPrimaryImport”,1);

// BES – BufferedEventStream – writes to MessageBox (Asynchronous call, no wait in call)
// _BAMEventStr = new BufferedEventStream(“Integrated Security=SSPI;Data Source=.;Initial Catalog=BizTalkMsgBoxDb”,1);

// MES – MessagingEventStream – Async and participates in Pipeline transaction context).
// – Note: Available in BizTalk 2004 with SP1 patch and Biztalk 2006
_BAMEventStr = context.GetEventStream();


catch(Exception e)

throw (e);


// Sample BAM Event Code here:
string ActivityID;
//Create a new, unique activity identifier to use as the ActivityID in BAM
ActivityID=”BAM_” + Guid.NewGuid().ToString() + “_” + DateTime.Now + “_” + StageDescription;

//Start the activity record identified by ActivityID

_BAMEventStr.UpdateActivity(“PurchaseOrder”,ActivityID, “ProductName”,”QFE1117″);


// Optional Flush


Reference on MessagingEventStream:[bts06]/html/M_Microsoft_BizTalk_Component_Interop_IPipelineContext_GetEventStream.asp

Reference on EventStream:[bts06]/html/T_Microsoft_BizTalk_Bam_EventObservation_EventStream.asp

To understand the above and details on how to fetch message specific data, please refer to sectio on Developing Pipeline Components in the help or use this link:
You would at least need to implement these interfaces.
IBaseComponent, IComponent, IComponentUI.

The above is tedious and is the only means for writing to BAM in Biztalk 2004. In Biztalk 2006, you can do some of this easily via TPE drag and drop.


Comments (13)

  1. Eric Stott says:

    Is it possible to use the GetEventStream() in regular Orchestrations, as I don’t want to have to code in the location of the BAM database for every enviornment? To me, it looks like this is only available in the pipeline component.

  2. keithlim says:

    OrchestrationEventStream sample code:

    Yes, in terms of accessing an EventStream that participates in the Orchestration context but the syntaxt is different.  Here is how:

    Once you have correctly referenced the Microsoft.BizTalk.Bam.EventObservation.dll in your BizTalk project, you can write the following in your orchestration, e.g. Expression Editor (click on the appropriate shape in orchestration to launch this):

    // Sample code for using OrchestrationEventStream from an orchestration, no need to new it:

    Microsoft.BizTalk.Bam.EventObservation.OrchestrationEventStream.BeginActivity( "PurchaseOrder", "PO123");

    Note: this only applies to Biztalk 2006.

  3. Eric Stott says:

    So right now, I have to reference a Business Rule to determine which server the ‘home’ BAMPrimaryImport lives on then if I am still on 2k4, is there a registry entry or some other way that I can automatically find out what server the MessageBox or PrimaryImport database lives without making a call to the BRE?

  4. keithlim says:

    There is a location where you can read this in registry and then read then read the data in the database to find the information, but this is method is not supported because this is internal implementaiton and no guarantee that it would not change.  The OES was there for that reason.  I will look up if there is any code I could send you.

  5. Eric Stott says:

    Thanks! I don’t particularly like having to make a business rule for something that should be automated. The biztalk application ‘should’ know where its home is!

  6. Eric Stott says:

    If you can provide an example in BTS 2K4 exmaple, or how to implement it, that would be great.

  7. keithlim says:

    Example for retrieving Biztalk MesageBox and BAM PIT server and database can be found in this link:

  8. Many of you guys are eagerly anticipating the release of the Microsoft BizTalk Server 2006 R2… and the

  9. Jason Landon says:


    Your examples are great, but I’ve chosen in BizTalk 2006 R2 to use a custom pipeline component to enable continuation (as above) and then use custom code (strongly typed API, GenerateTypedBAMAPI)as opposed to the TPE, within my orchestration for BAM.  My question is how do I go about identifying the unique activityid that was generated in the pipeline in my custom code. Thanks.

  10. keithlim says:

    Normally you would want to use a piece of data from the payload message as the activityid.  If you were to use one that is generated from within the pipeline, you would need to make this data available as the message is being passed to the orchestration.  Could you post another question to this thread for further help.



  11. Jason Landon says:

    Yes, I need to pass the activityid to the orchestration.  I’m not sure how to make this data available.  Are there any examples for doing so?


  12. keithlim says:

    I have posted your question here to solicit other helps in the Biztalk discussion:

    Please post your future questions here.



  13. BAM is probably the most useful & undervalued piece of software built for SOA world so far. Reason…