WF Migration Cookbook: Workflow Tracking Introduction In the .NET Framework 4, Microsoft is releasing the second major version of Windows Workflow Foundation (WF). WF was released in .NET 3.0 (this included the types in the System.Workflow.* namespaces; let’s call this WF3) and enhanced in .NET 3.5. WF3 is also part of the .NET Framework 4, but it exists there alongside new workflow technology (this includes the types in the System.Activities.* namespaces; let’s call this WF4). This paper presents guidance for redesigning WF3 tracking code and configuration using equivalent WF4 tracking code and configuration. Please see the “WF Migration Overview” document for an introduction to WF3 to WF4 migration, and links to related documents. The latest version of these documents can be found at http://go.microsoft.com/fwlink/?LinkID=153313 The information contained in this document relates to pre-release software product, which may be substantially modified before its first commercial release. Accordingly, the information may not accurately describe or reflect the software product when first commercially released. This document is provided for informational purposes only, and Microsoft makes no warranties, express or implied, with respect to this document or the information contained in it. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. Microsoft, Windows, Visual Studio, and the .NET logo are trademarks of the Microsoft group of companies. All other trademarks are property of their respective owners. WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 1 Overview Tracking is a feature used to gain visibility into the execution of workflow instances. Let us look at how tracking is enabled in WF3 and compare it with tracking in WF4. Tracking types in WF3 are located in the System.Workflow.Runtime.Tracking namespace. In WF4, the tracking types are located in the System.Activities.Tracking namespace. Tracking in WF3 is enabled by associating a TrackingService with a workflow instance. In WF4, tracking is enabled by associating a TrackingParticipant with a workflow instance. Out of the box, WF3 provides a SqlTrackingService that writes tracking events to a SQL database. WF4 provides an out of the box TrackingParticipant that writes to Event Tracing for Windows (ETW). In WF3, to write tracking information to a custom location, it is necessary to implement a custom TrackingService that provides a custom TrackingChannel. In WF3, to write tracking information to a custom location, it is necessary to implement a custom TrackingParticipant. The WF4 SDK samples demonstrate how to implement several custom TrackingParticipants. Enabling Tracking In WF3, tracking is enabled as follows when using WorkflowRuntime: WorkflowRuntime wr = new WorkflowRuntime(); wr.AddService(new SqlTrackingService(…)); In WF4, the way to enable tracking depends upon the host being used. If WorkflowApplication is used, a tracking participant is added like this: WorkflowApplication app = new WorkflowApplication(…); app.Extensions.Add(new EtwTrackingParticipant()); If the WF4 WorkflowServiceHost is used, tracking can be enabled through code or config. Adding the EtwTrackingParticipant through code and config is shown below. ServiceHost host = new ServiceHost(…); EtwTrackingBehavior trackingBehavior = new EtwTrackingBehavior { ProfileName = "Sample Tracking Profile" }; host.Description.Behaviors.Add(trackingBehavior); WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 2 <behaviors> <serviceBehaviors> <behavior> <etwTracking profileName="Sample Tracking Profile" /> </behavior> </serviceBehaviors> <behaviors> A custom TrackingParticipant can be added to the WF4 WorkflowServiceHost by writing a custom behavior, as demonstrated in the TextFileTracking and SQLTracking samples in the WF4 SDK. Tracking Events WF3 emits the following types of tracking events: Instance events (WorkflowTrackingRecord) Activity events (ActivityTrackingRecord) Custom events (UserTrackingRecord) WF4 emits the following types of tracking events: Instance events: WorkflowInstanceRecord and derived TrackingRecords corresponding to UnhandledException, Terminate, Cancel, Suspend and Abort. These records are conceptually equivalent to the Instance events in WF3. Activity State events: ActivityStateRecord. These records are conceptually equivalent to the ActivityTrackingRecord in WF3. Activity Schedule events: ActivityScheduledRecord. Emitted when a parent activity schedules a child activity. This tracking record contains information about the scheduling and scheduled activities. Activity CancelRequested events: CancelRequestedRecord. Emitted when a parent activity cancels a child activity. This tracking record contains information about the cancelling and canceled activities. Activity FaultHandling events: FaultPropagationRecord. Emitted when an activity faults and the fault is handled. Bookmark Resumption events: BookmarkResumptionRecord. Emitted when a bookmark is resumed . Custom events: CustomTrackingRecord. Equivalent to the UserTrackingRecord in WF3. Emitting Custom tracking data In WF3, custom tracking data is emitted using one of the two TrackData method overloads found on the System.Workflow.ComponentModel.Activity class. If an optional key is provided, it can be used when specifying a filter for the custom tracking data in a tracking profile. WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 3 using System; using System.Workflow.ComponentModel; namespace Cookbook_CustomActivities_WF3 { public class MyActivity : Activity { protected override ActivityExecutionStatus Execute( ActivityExecutionContext context) { this.TrackData("Tracking something"); … } } } In WF4, custom tracking data is added to a CustomTrackingRecord and is emitted using the Track method on the activity execution context. The name of the custom tracking record, provided to the constructor, can be used to query for the record. The custom data is specified as a dictionary of <string, object> pairs within the emitted record. using System; using System.Activities; using System.Activities.Tracking; namespace Cookbook_CustomActivities_WF4 { public class MyActivity : CodeActivity { protected override void Execute(CodeActivityContext context) { CustomTrackingRecord record = new CustomTrackingRecord("CustomTracking"); record.Data.Add("CustomData", "Tracking something"); context.Track(record); … } } } Tracking Profiles In WF3, a tracking profile defines a list of "track points," which subscribe for events that will be passed on to a tracking service. A tracking profile can be created in code or read from an XML file. WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 4 In WF4, a tracking profile defines a list of “tracking queries,” which subscribe for events that will be passed on to a tracking participant. As in WF3, a tracking profile can be created in code or specified declaratively. If the tracking profile is specified in a declarative manner, it is specified in a config file (app.config or web.config). Tracking query elements are configuration elements that can be read and written to a config file using System.Configuration APIs. Subscribing for instance events In WF3, workflow track points have a set of matching locations that describe which workflow events must be tracked. Here is an example in XML: <TrackingProfile xmlns="http://schemas.microsoft.com/winfx/2006/workflow/ trackingprofile" version="3.0.0.3"> <TrackPoints> <WorkflowTrackPoint> <MatchingLocation> <WorkflowTrackingLocation> <TrackingWorkflowEvents> <TrackingWorkflowEvent>Created</TrackingWorkflowEvent> <TrackingWorkflowEvent>Completed</TrackingWorkflowEvent> </TrackingWorkflowEvents> </WorkflowTrackingLocation> </MatchingLocation> </WorkflowTrackPoint> </TrackPoints> </TrackingProfile> In WF4, the equivalent of a workflow track point is a workflow instance tracking query. Tracking records can be matched using workflow instance states. The queryable states for a workflow instance are specified by System.Activities.Tracking.WorkflowInstanceStates. Here is an example in config: <trackingProfile name="Sample Tracking Profile"> <workflow activityDefinitionId="*"> <workflowInstanceQueries> <workflowInstanceQuery> <states> <state name="Started"/> <state name="Completed"/> </states> </workflowInstanceQuery> </workflowInstanceQueries> </workflow> </trackingProfile> Subscribing for activity events In WF3, activity tracking records are matched using ActivityTrackPoint, which can match Activity Types Activity Execution Status Conditions WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 5 Extracts For example: <ActivityTrackPoint> <MatchingLocations> <ActivityTrackingLocation> <Activity> <Type>System.Workflow.ComponentModel.Activity, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</Type> <MatchDerivedTypes>true</MatchDerivedTypes> </Activity> <ExecutionStatusEvents> <ExecutionStatus>Initialized</ExecutionStatus> <ExecutionStatus>Executing</ExecutionStatus> <ExecutionStatus>Canceling</ExecutionStatus> <ExecutionStatus>Closed</ExecutionStatus> <ExecutionStatus>Compensating</ExecutionStatus> <ExecutionStatus>Faulting</ExecutionStatus> </ExecutionStatusEvents> </ActivityTrackingLocation> </MatchingLocations> </ActivityTrackPoint> In WF4, activity tracking records are matched using an ActivityStateQuery that can match Activity Display Name Activity Execution States Variable names Argument names For example: <activityStateQueries> <activityStateQuery activityName="MyActivity "> <states> <state name="Executing"/> <state name="Canceled"/> <state name="Faulted"/> <state name="Closed"/> </states> </activityStateQuery> </activityStateQueries> Subscribing for custom events In WF3, custom tracking records are matched using a UserTrackingPoint that can match: Activity Types Custom data type WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 6 <UserTrackPoint> <MatchingLocations> <UserTrackingLocation> <Activity> <Type>System.Workflow.ComponentModel.Activity, System.Workflow.ComponentModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</Type> <MatchDerivedTypes>true</MatchDerivedTypes> </Activity> <Argument> <Type>System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</Type> <MatchDerivedTypes>true</MatchDerivedTypes> </Argument> </UserTrackingLocation> </MatchingLocations> </UserTrackPoint> In WF4, custom tracking records are matched using a CustomTrackingQuery that can match: Activity Display Name Custom Track Record Name <customTrackingQueries> <customTrackingQuery name="CustomTrackingEvent" activityName="MyActivity"/> </customTrackingQueries> Annotations In WF3, annotations are specified as list of strings on a track point. activityTrackPoint.Annotations.Add("This is an annotation"); In WF4, annotations are specified as pairs of strings on a tracking query. activityStateQuery.QueryAnnotations.Add("ActivityAnnotation", "This is an annotation"); Data Extraction In WF3, extracts can be used to retrieve data along with tracking events. WF4 provides data extraction in the form of variable and argument extraction when a tracking record is emitted from an activity. There is not a separate notion of data extraction at the workflow instance WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 7 level; the equivalent of workflow level extraction in WF4 is extraction of variables from the root activity of the workflow instance. When an activity executes, variables in scope for that activity can be extracted. Argument extraction allows input arguments to be extracted when the activity starts executing (state=Executing) and all arguments to be extracted when the activity completes (state=Closed). Tracking Types in WF3 and WF4 The following table shows namespace mappings from WF3 to WF4 for tracking related types. WF3 namespace System.Workflow.Runtime.Tracking WF4 namespace System.Activities.Tracking The following table shows mappings between WF3 and WF4 types. WF3 Tracking WorkflowTrackingRecord ActivityTrackingRecord UserTrackingRecord TrackingService+TrackingChannel TrackPoint WorkflowTrackPoint ActivityTrackPoint UserTrackPoint SqlTrackingService WF4 Tracking WorkflowInstanceRecord ActivityStateRecord CustomTrackingRecord TrackingParticipant TrackingQuery WorkflowInstanceQuery ActivityStateQuery CustomTrackingQuery n/a TrackingProfileSerializer n/a ActivityDataTrackingExtract n/a Comments WF4 has no out of box participant that writes to SQL. There is a SQL tracking sample provided with WF4 samples that demonstrates how a SQL tracking participant can be implemented. In WF4, tracking profile queries are configuration elements that can be serialized using standard System.Configuration APIs. Variable and argument extraction can be specified as part of an ActivityStateQuery. Summary In summary, while the concept of tracking does not fundamentally change from WF3 to WF4, there are a set of steps required to redesign WF3 tracking artifacts as WF4 tracking artifacts. WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 8 Please send us your feedback and questions related to WF migration. We look forward to helping you successfully adopt and utilize WF4 technology. Additional Information Visual Studio 2010 - http://go.microsoft.com/fwlink/?LinkID=151797 WF4 – http://msdn.microsoft.com/wf/future/ .NET Framework 4 http://www.microsoft.com/downloads/details.aspx?FamilyID=ee2118cc-51cd-46ad-ab17af6fff7538c9&displaylang=en WF4 Migration Guidance - http://go.microsoft.com/fwlink/?LinkID=153313 WCF and WF Samples for .NET Framework http://go.microsoft.com/fwlink/?LinkID=144388 WCF and WF4 Training Kit - http://code.msdn.microsoft.com/wcfwf4 WF 4 Migration Cookbook: Tracking (.NET 4 - Beta 2 Release) Page 9