Microsoft BizTalk Server 2006 R2 Beta 2 is finally public!

You can download it from: http://connect.microsoft.com/

 

In this post, I will showcase an entire sample interceptor configuration file for the Windows Workflow Foundation (WF) interceptor.  In working with

the new BAM WF/WCF interceptors, the interceptor configuration file answers the following questions related to interception:

 

  • When to extract data from the application?
  • Where to extract data from the application?
  • What data to extract from the application?

In addition, the interceptor configuration file describes how to map the extracted data into what I am loosely calling “BAM events”:

 

  • BeginActivity(activityName, activityInstance) [BA]
  • UpdateActivity(activityName, activityInstance, params object[] data) [UA]
  • EndActivity(activityName, activityInstance) [EA]
  • EnableContinuation(activityName, activityInstance, continuationToken) [EC]
  • AddReference(activityName, activityID, referenceType, referenceName, referenceData, longReferenceData) [AR]

These BAM events (BA, UA, EA, EC, AR) are the methods invoked on the EventStream class for sending tracking data to the BAM infrastructure.  If you are not familiar with BAM and EventStream, please refer to the following link on EventStream documentation:

 

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sdkmref_bts/html/T_Microsoft_BizTalk_Bam_EventObservation_EventStream.asp

 

Previous BAM instrumentation required making these method calls manually in your application code but now the BAM interceptors perform that functionality for you provided you create the appropriate interceptor configuration file.

 

At this point, I’m assuming that the reader is familiar with BAM concepts such as activities and continuations.

In the remainder of this post, I’m going to display a sample workflow application built using Windows Workflow Foundation (WF) and a sample interceptor configuration file that extracts various data from the workflow and sends that data to BAM.  In this post, I won’t explain the entire interceptor configuration in detail but instead try to provide an overview by showing you the interceptor configuration in its entirety.

 

Suppose I have the following workflow for a fulfillment process.

 

Sample Workflow 

 

Now suppose I want to track various data in this workflow inside BAM.  I might create the following interceptor configuration file. (Note: This is just a contrived example.  Don’t worry about all the details of the interceptor configuration for now.)

 

<ic:InterceptorConfiguration xmlns:ic="http://schemas.microsoft.com/BizTalkServer/2004/10/BAM/InterceptorConfiguration" xmlns:wf="http://schemas.microsoft.com/BizTalkServer/2004/10/BAM/WorkflowInterceptorConfiguration">

  <ic:EventSource Name="Workflow1" Technology="WF" Manifest="FulfillmentWorkflow.Workflow1, Fulfillment, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"/>

  <ic:BamActivity Name="FulfillmentActivity">

    <ic:OnEvent Name="FulfillmentEvent" Source="Workflow1" IsBegin="true" IsEnd="true">

      <ic:Filter>

        <ic:Expression>

          <wf:Operation Name="GetActivityName" />

          <ic:Operation Name="Constant">

            <ic:Argument>Fulfillment</ic:Argument>

          </ic:Operation>

          <ic:Operation Name="Equals" />

          <wf:Operation Name="GetActivityEvent" />

          <ic:Operation Name="Constant">

            <ic:Argument>Closed</ic:Argument>

          </ic:Operation>

          <ic:Operation Name="Equals" />

          <ic:Operation Name="And" />

        </ic:Expression>

      </ic:Filter>

      <ic:CorrelationID>

        <ic:Expression>

          <wf:Operation Name="GetContextProperty">

            <wf:Argument>InstanceId</wf:Argument>

          </wf:Operation>

        </ic:Expression>

      </ic:CorrelationID>

      <ic:Update DataItemName="City" Type="NVARCHAR">

        <ic:Expression>

          <wf:Operation Name="GetWorkflowProperty">

            <wf:Argument>City</wf:Argument>

          </wf:Operation>

        </ic:Expression>

      </ic:Update>

      <ic:Update DataItemName="Amount" Type="FLOAT">

        <ic:Expression>

          <wf:Operation Name="GetWorkflowProperty">

            <wf:Argument>Amount</wf:Argument>

          </wf:Operation>

        </ic:Expression>

      </ic:Update>

    </ic:OnEvent>

  </ic:BamActivity>

</ic:InterceptorConfiguration>

 

Although I don’t want to go into detail on the entire interceptor configuration, I do want to highlight a few different portions starting from the top down.

 

First I have defined an EventSource called “Workflow1” that maps to my fulfillment workflow in my application using the .NET qualified assembly name in the Manifest attribute.

 

Next I have a BamActivity called “FufillmentActivity” with the checkpoints “City” and “Amount”.  Whenever any of the interception events (OnEvent) are fired for the event source “Workflow1”, tracking data will be written to this BAM activity called “FufillmentActivity”.  The exact way that the tracking data is written is described by the BAM events BA, EA, UA, EC, and AR.

 

  • BA – IsBegin attribute on the OnEvent
  • EA – IsEnd attribute on the OnEvent
  • UA – Update element inside the OnEvent
  • EC – ContinuationToken element inside the OnEvent
  • AR – Reference element inside the OnEvent
  • Note: CorrelationID element inside the OnEvent defines the activityInstance (must be unique)

The sample configuration above contains a single interception event – when the filter evaluates to true, the interception event is fired which cause the following steps:

 

  1. New BAM activity instance for “FufillmentActivity” with activityInstance equal to the workflow instance ID
  2. Update activity on checkpoint “City” with the tracking data from the workflow
  3. Update activity on checkpoint “Amount” with the tracking data from the workflow
  4. BAM activity instance is ended

 For those who have worked with BAM before, these steps are exactly the same steps that would be performed during manual instrumentation of an application for BAM tracking.

 

The new BAM Manager [bm.exe] can be used to deploy the created interceptor configuration to the BAM PrimaryImport Database.

 

Example: bm.exe deploy-interceptor –FileName:Fulfillment_IC.xml

 

Now to add the WF interceptor to your workflow application, you can register the BAM Tracking Service through the application configuration (or programmatically through code as well).  The following is a sample application configuration.

 

<configuration>

  <configSections>

    <section name="WorkflowServiceContainer" type="System.Workflow.Runtime.Configuration.WorkflowRuntimeSection, System.Workflow.Runtime, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

  </configSections>

  <WorkflowServiceContainer>

    <Services>

      <add type="Microsoft.BizTalk.Bam.Interceptors.Workflow.BamTrackingService, Microsoft.BizTalk.Bam.Interceptors, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"          

           ConnectionString="Data Source=localhost;Integrated Security=true;Initial Catalog=BAMPrimaryImport"

           InterceptorConfigurationPollingInterval="300"

           />

    </Services>

  </WorkflowServiceContainer>

</configuration>

 

Once the workflow application is restarted with the updated application configuration, tracking data is now available inside BAM!

 

Although I haven’t explained everything inside the interceptor configuration (like filter, expression, different operations, etc. ) and other security considerations, I hope that by seeing a sample interceptor configuration in its entirety, this post has given you more insight into how the BAM interceptors work.