The Tracking Profile Editor (TPE) is great for simple scenarios, but when your tracking requirements involve complex logic, loops, or variables that aren’t visible to the TPE, you need the OrchestrationEventStream (OES).
📝 One-Minute Brief
While the TPE is the standard for BAM tracking, the OrchestrationEventStream (OES) is the preferred method for developers needing programmatic control within an orchestration. OES ensures transactional consistency: if the orchestration transaction rolls back, the BAM data does as well. This post explains how to instantiate the OES and use it to Begin, Update, and End BAM activities directly from an Expression Shape, ensuring your tracking data is always synchronized with your process logic.
The OrchestrationEventStream (OES) is one of the artifacts developers should consider to programmatically populate a BAM activity model within a BizTalk orchestration.
The OES writes BAM Activity data into the state of the BizTalk orchestration and does not require a database round-trip each time. When the orchestration completes or reaches a persistence point, the BAM activity data is written into the MessageBox along with the orchestration state.
The biggest advantage of using OrchestrationEventStream over other streams (like DirectEventStream) is that it is transactionally consistent. Because this data is part of the orchestration state, all data is rolled back along with the orchestration if an error occurs. That means if the orchestration fails and rolls back to the last checkpoint, your BAM data won’t show “phantom” successful steps. This method gives you complete transactional integrity, unlike the other event stream options, and offers the best performance for an orchestration-based solution.
The OES API stores tracking data first in the BizTalk MessageBox database. Periodically, the data is processed and persisted to the BAM Primary Import database by the Tracking Data Decode Service (TDDS).
It is found in Microsoft.BizTalk.Bam.EventObservation namespace. To use the API, you must add the Microsoft.Biztalk.BAM.Xlangs.dll to your project.
So, in your BizTalk project, include references to the following assemblies:
- Microsoft.BizTalk.Bam.EventObservation and Microsoft.BizTalk.Bam.XLANGs.
These assemblies may be found in your Microsoft BizTalk Server 2006\Tracking folder.
The OrchestrationEventStream is utilized by the TPE tool. In BizTalk Server 2004, it was an internal component used by TPE and not exposed for general use. The transactional integrity requirement came up during a customer engagement, so it was later exposed in the 2004 release by a hotfix and is in the box with BizTalk Server 2006.
Sample code
Note that because the OrchestrationEventStream is implemented as a static class, there is no need to manually create an event stream each time, and a connection string isn’t required because the OrchestrationEventStream piggybacks on the persistence of the orchestration.
//Create a new, unique activity identifier to use as the ActivityID in BAM
string activityId = Guid.NewGuid().ToString() + "_" + DateTime.Now;
//Start the activity record identified by activityId
Microsoft.BizTalk.Bam.EventObservation.OrchestrationEventStream.BeginActivity(“MyTrackingDemo”, activityID);
// Updates the activity record.
Microsoft.BizTalk.Bam.EventObservation.OrchestrationEventStream.UpdateActivity(“MyTrackingDemo”, activityID, “MESSAGE_ID”, msg(BTS.MessageID), "TRANSACTION_CREATED", DateTime.UtcNow);
// End the activity record.
Microsoft.BizTalk.Bam.EventObservation.OrchestrationEventStream.EndActivity(“MyTrackingDemo”, activityID);
Note: You don’t need a connection string! The engine already knows where the BAM database is.
Hello Sandro, I’m playing with OES and I’m trying to find a way to update a completed activity.
Imagine an Orchestration that updates the status of an object.
The orchestration will run many different times as an app is sending us the life-cycle data (created – updated – finished – deleted).
All these are different calls, and will happen across a considerable amount of time (days).
What I’m trying to do is have 1 row per object in BAM that tells me the latest status of the object.
So far I’ve only been able to add one row per call, potentially having up to 3 rows per object.
Is there any way to accomplish this?
Thanks
-g