Windows Workflow Foundation, or WF, is oftentimes compared to BizTalk’s orchestration-underlying XLANG language. WF’s underlying XAML language, like the XLANG language, provides an extensible and declarative means to describe the execution of a business process. Within BizTalk, this business process is implemented in the form of an orchestration. Within WF, the business process is executed as either a sequential or a state machine workflow.
Since WF’s introduction and given the striking similarities to BizTalk orchestrations, BizTalk architects have wondered how WF is aligned with BizTalk, and whether that alignment takes advantage of the umbrella of ancillary technologies, such as BAM, that BizTalk has to offer. The answer is that WF may be positioned alongside BizTalk and BAM quite nicely, complementing BizTalk, BAM, and other technologies that are a part of BizTalk.
This chapter will cover the following:
app.config
fileThis chapter assumes you have basic knowledge of workflow within applications, XML, Visual Studio 2008, and BizTalk Server Administration.
While Microsoft has announced significant changes will be coming within .NET Framework 4.0 with regard to WF and WCF (effectively dubbed WCF+WF 4.0), you may assume that the next version of BizTalk, built upon the .NET Framework 4.0, will be updated to include these changes.
Although it was known that Microsoft had an SOA product (Indigo) in the works at the time of Microsoft’s Professional Developer’s Conference 2005, little was known about its companion product, Windows Workflow Foundation, which was announced at the conference.
As the portfolio of Microsoft’s server offerings has grown, so too has the number of proprietary implementations of workflow-like technology. While BizTalk implemented its own business process workflow first as orchestrations and then later added Human Workflow Services, products such as Content Management Server hosted long-running workflows some time ago. Microsoft also had no application-level workflow offering by which developers could build .NET applications without resorting to third-party offerings, such as K2 or Skelta.
With each server implementing its own flavor of workflow, it made sense for Microsoft to provide some “foundational” workflow APIs by which application-level workflows could be constructed and upon which additional capability could be built (e.g., Microsoft Office Share-Point Server builds its workflows using WF).
As WF emerged, many questioned whether it would replace XLANG as the execution engine of BizTalk. While the same team worked on both technologies, it was ultimately decided that the two technologies would coexist as they target different environments. In fact, Microsoft, as part of its pledge toward future BizTalk versions, has made it clear that existing investments within XLANG will never be sacrificed at the expense of the “latest and greatest.”
Within WF, a workflow represents the implementation of a specific process. Application code, in general, is the implementation of a specific process. What differentiates application code from a workflow is the means in which it executes and the way in which that execution is represented.
Workflows within WF execute in one of two ways: either sequentially or as a result of an event firing or a condition being met (referred to as state machine workflows). BizTalk orchestrations may be thought of as sequential as well. Figures 9-1 and 9-2 depict a sequential BizTalk orchestration and a sequential WF workflow. Note the similarities.
In building an orchestration, it’s oftentimes known what the proposed outcome will be or what the set of steps to take place are. Sequential workflows lend themselves to the same design pattern: a fixed set of steps that largely follows a path from A to B and may take some tangents.
State machine workflows are more geared toward human interaction or interaction from an outside force. They are less fixed, less rigid, and more adept at handling events as they occur (see Figure 9-3). Over time, message and orchestration design patterns have emerged within BizTalk as a result of a desire to handle events in a nonlinear fashion. Publish-subscribe responds to the event of a message publication. The convoy pattern fully accepts message events will occur out of order and expects to build some mechanism to deal with them. The same may be said of the aggregator pattern.
If a workflow represents the implementation of a specific process, activities represent the individual tasks or units of work of that process. Out of the box, BizTalk provides activities in the form of shapes within the toolbox. WF provides similar capabilities, but also the ability to build custom activities by inheriting from the activity class.
When a BizTalk developer wishes to encapsulate a process or promote reuse of a sequence of events, this is accomplished by either building a separate orchestration that is called or started by a primary orchestration or calling into a custom code component within a code shape. Within WF, a developer may encapsulate multiple activities in a single activity, known as a composite activity, instead of calling across activities (or their BizTalk equivalents). This is done by inheriting from the CompositeActivity
class.
When you use the activities and the WF designer within Visual Studio, it begins to become clear that the toolset is largely geared toward building workflow within an application.
From a purely physical standpoint, after creation, an orchestration file (ODX) is simply a code file. Likewise, a WF workflow is code as well. Both provide a rich visual interface for designing the code. BizTalk, however, has the distinct advantage of providing for not only the creation of the code, but also the execution environment, known as the BizTalk run time or BizTalk host.
WF workflows, in the form of WF libraries, must be executed using a .NET 2.0–compliant hosting process, such as a Windows Forms application, WPF application, Windows service, web application, console application, etc.
Once the workflow hosting process has been instantiated, it communicates to the WF run time, which provides access to the WF framework. In order for the WF run time to properly execute workflows, it must support three services.
Of note, the Dublin suite of technologies, while not fully detailed, is expected to address many of the shortcomings of the management of WCF and WF technologies.
Persistence, within the context of a business process, is the ability to store the state of the process in a typically durable medium (such as a database, file store, etc.). BizTalk implements this capability utilizing persistence points, specifically when
Some argue that the fact that BizTalk automatically provides management of its persistence points is beneficial to the developer; others argue that this persistence mechanism should be surfaced via an API and that calls to it should be made more explicit.
Because it is unknown where the WF run time will be hosted, WF implements a PersistenceService
, which provides the ability to persist, dehydrate, or rehydrate the state of a workflow. A Windows Forms application, WPF application, or Windows service that runs continually manages the state of the workflow within the execution space of the application or service. But for an ASP.NET application, the state of the workflow must be maintained in some external store. In instances where the request made to the ASP.NET application is load balanced across multiple servers, there is no guarantee that the same server will receive the successive request. As such, some medium must be in place between changes to the business process to maintain the state of the workflow.
As with BizTalk, there are times when it is necessary to “sleep” a process, awaiting either external input or for a specific period of time to elapse. From a memory management standpoint, especially when considering scalability, keeping each workflow in memory soon becomes unrealistic.
WF provides one out-of-the-box persistence mechanism, SQL Server, using SqlWorkflowPersistenceService
. Fortunately, unlike BizTalk, WF provides you the ability to “roll your own” persistence service by creating a class that inherits from the WorkflowPersistenceService
class. As with SqlWorkflowPersistenceService
, your persistence service then serializes the state of the workflow in the following instances:
TransactionScopeActivity
completes.CompensatableSequenceActivity
completes.PersistOnCloseAttribute
completes.WorkflowInstance
is invoked that causes a persistence operation, such as Unload
and TryUnload
. The Load
method results in a previously unloaded and persisted workflow being retrieved and loaded back into memory.The mechanism utilized to persist to the store, binary representation and GZIP compression, is identical between BizTalk and WF.
The WF Tracking Service is to HAT what WF workflows are to BizTalk orchestrations. The WF Tracking Service provides visibility into the execution process of a workflow, such as duration, decision points made and route taken, and completion state of activities executed therein. While many comparisons have been made between the WF Tracking Service and BAM, it’s important to remember that BAM is business and activity focused, whereas the WF Tracking Service and HAT are message based.
As may be surmised, WF ships with one tracking service out of the box, the SqlTrackingService
, which provides the ability to write tracking data to a SQL Server–based data store. Additional tracking services may be created to persist data and aggregated during the execution process (with some performance penalty, of course).
As with BAM, there are two primary phases to the design of a tracking profile for WF. However, BAM provides you at least one tool for the creation of an observational model, whereas WF leaves implementation and configuration to the developer. Again, expect this shortcoming to be introduced with the Dublin suite of technologies, currently slated to be released at the time of Visual Studio 2010.
The WF Scheduling Service manages how workflow instances are scheduled by the workflow run-time engine. While not directly analogous, the WF Scheduling Service is akin to the service window capabilities found within a BizTalk receive or send location, providing for a specific date/time during which an orchestration may be executed.
The WF Scheduling Service provides two out of the box classes: DefaultWorkflowSchedulerService
and ManualWorkflowSchedulerService
. The difference between the two largely has to do with the threading model; while the former is more positioned toward Windows Forms and WPF apps, the latter is geared toward ASP.NET applications.
The purpose of a rules engine tool is the centralization of an application’s or enterprise’s business rules. From a central repository, rules are made accessible for reuse by multiple business processes and may be efficiently and consistently maintained while avoiding the need to change code in multiple places. Additionally, redeployments of rule sets are often unnecessary for small changes to variables. The underlying principles serve to promote reuse of code and abstraction of logic.
While BizTalk provides a rules engine in the form of the BRE, WF also provides its own rules engine in the form of the WFRE. Although they were engineered by the same team, the BRE and the WFRE differ greatly in their design and implementation.
While similar in concept and designed by the same team, BizTalk and WF are strikingly different in their implementation. Table 9-1 summarizes those differences.
What emerges clearly from this comparison chart involving BAM are the following assertions:
Think of BizTalk as executing business processes between systems. Think of WF as executing business processes within a system. Think of WCF as the entry points to and exit points from a system. Also, remember that as of .NET 3.5, WCF can be used to instantiate a WF workflow.
So how may the contents of a WF workflow or activity provide data to BAM? We’ll explore that next.
As the overall interceptor architecture was covered in detail in Chapter 8, we won’t revisit it again. However, it is important to understand how the WF interceptor works.
The WF interceptor is implemented as a WF Tracking Service named BamTrackingService
, which inherits from the base TrackingService
class and implements the IProfileNotification
interface. The WF run time sends three types of events to a tracking service: workflow events, activity events, and user events. These events are implemented as track points.
Workflow events, as you may imagine, provide visibility into the life cycle of the work-flow instance with events such as Created
, Completed
, Idle
, Suspended
, Resumed
, Persisted
, Unloaded
, Loaded
, Exception
, Terminated
, Aborted
, Changed
, and Started
.
Activity events describe and provide visibility into the life cycle of an activity instance. Status events for an activity include Executing
, Closed
, Compensating
, Faulting
, and Canceling
.
User events are defined by the developer of the workflow and the activity. Each activity offers a TrackData()
method with two overloads. The objectData
or key and objectData
passed to this method is passed to the tracking service as a User
event.
The tracking run time, which executes within the host application, uses a tracking profile similar to BAM’s to filter which events will be reported to the tracking service. Because BamTrackingService
determines the items to be tracked based upon what the BAM developer determines should be tracked via the IC file, the implementation of BamTrackingService
is unique.
When BamTrackingService
is first initialized, it first creates a new instance of a BamProfileManager
, the primary class used to manage BAM tracking profiles as they relate to WF tracking profiles, validating and managing track points, and validating activities, users, and workflows. The configuration file is read to set the ConnectionString
to the PI tables as well as the polling interval, and then WF event source names are read into a collection.
The first functional event that occurs is a TryGetProfile()
call from the tracking run time to the tracking service, requesting a specific workflow type and tracking profile. The first attempt is to retrieve a local WF tracking profile. An attempt is then made to retrieve an interceptor configuration from the PI tables for the specific workflow event source. Providing everything is successful, BamProfileManager
then takes over and begins parsing the interceptor configuration via the SetupMetadata
and HelpSetupMetadata
methods. A TrackingProfile
object is returned. This object is the mechanism that communicates which events, by way of its call to the PI tables, are to be observed rather than monitoring all events that occur within the WF workflow.
The tracking run time then calls the GetTrackingChannel()
method from BamTracking-Service
. A BamTrackingChannel
is a mechanism to handle the tracking events and data that occur within the workflow instance. It’s important to note that in its construction, the BamTrackingChannel
instantiates a DirectEventStream
object and a WorkflowInspector
object. The WorkflowInspector
object actually transforms tracking data and produces events that are recorded to the BAM Primary Import database.
At execution time, events and data that the service requested through the tracking profile are sent to the tracking channel for the instance via the Send
method of the tracking channel. A new tracking channel is used for each WF workflow instance, preventing synchronization and locking issues from occurring as each workflow instance runs on a single thread.
WF tracking profiles are much like BAM tracking profiles. WF tracking profiles include work-flow track points, activity track points, and user track points. So what is a track point? Simply a construct that defines information on the type of data to collect and when to collect it.
A WF tracking profile is simply a collection of track points. The BAM WF interceptor, by way of the SetupMetadata
method, actually performs mapping between the WF interceptor configuration (which in essence is a BAM tracking profile) and the WF tracking profile.
Without going into too much detail here (you can find detailed info on MSDN by searching for “Windows Workflow Foundation: Tracking Services Deep Dive”), the WF tracking profile is structured as follows:
WorkflowTrackPoints
MatchingLocations
Events
Annotations
Activity TrackPoint
Matching/Excluded Locations
ActivityType
MatchDerivedTypes
ExecutionStatusEvents (for example, Executing or Closed)
Conditions
Member
Operator (Equals/Not Equals)
Value
Annotations
Extracts
Workflow Extract
Activity Extract
User TrackPoint
From a cursory glance, a BAM tracking profile/interceptor configuration and a WF tracking profile appear rather similar.
The basic process for enabling BAM to monitor WF workflows is as follows:
bam_<activity>_EventWriter
) SQL Server roles to enable the application to read the interceptor configuration information and write to the BAM activities.app.config
file to load the BAM Tracking Service or manually load the BAM Tracking Service within your code, and then restart the application.With a little experience with WF, you should be familiar with each of these steps with the exception of creating the interceptor configuration file targeted toward WF applications and modifying the app.config
file. Let’s cover the WF IC file first.
The WF interceptor file is based upon XML Schemas stored in the <Installation Path>Microsoft BizTalk Server 2009SDKSamplesBAMInterceptorXSDs
directory. These files, CommonInterceptorConfiguration.xsd
, WcfInterceptorConfiguration.xsd
, and WorkflowInterceptorConfiguration.xsd
, are used by the bm.exe
utility to validate the configuration file before deployment.
Chapter 8 covered the WCF interceptor schema as well as the CommonInterceptor-Configuration schema. The WorkflowInterceptorConfiguration schema includes the following:
<xs:element name="Operation">
<xs:complexType>
<xs:sequence>
<xs:element name="Argument" type="xs:string" minOccurs="0"
maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="Name" type="WorkflowOperationType" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="WorkflowOperationType">
<xs:restriction base="xs:string">
<xs:enumeration value="GetActivityName" />
<xs:enumeration value="GetActivityEvent" />
<xs:enumeration value="GetWorkflowEvent" />
<xs:enumeration value="GetActivityType" />
<xs:enumeration value="GetUserDataType" />
<xs:enumeration value="GetUserKey" />
<xs:enumeration value="GetUserData" />
<xs:enumeration value="GetWorkflowProperty" />
<xs:enumeration value="GetActivityProperty" />
<xs:enumeration value="GetContextProperty" />
</xs:restriction>
</xs:simpleType>
As stated in Chapter 8, the config file for your BAM WF interceptor is really just a means for BAM to call specific methods without requiring you to write code, namely
BeginActivity(activityName, activityInstance)
UpdateActivity(activityName, activityInstance, params object[] data)
EndActivity(activityName, activityInstance)
EnableContinuation(activityName, activityInstance, continuationToken)
AddReference(activityName, activityID, referenceType, referenceName, referenceData, longReferenceData)
The EventSource
element specifies the source of the events appearing in the interceptor configuration file. The element includes the three attributes listed in Table 9-2.
Following is a complete example of an EventSource
element for WF:
<ic:EventSource Name="ProcessingWorkflow" Technology="WF"
Manifest="SimpleWorkflow.OrderWorkflow, SimpleWorkflow, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null"/>
The BAMActivity
element simply defines the name of the BAM activity and is a container for other elements. The element includes only one attribute, which is listed in Table 9-3.
Following is an example of a BAMActivity
element containing the preceding example:
<ic:BamActivity Name="Order">
...
</ic:BamActivity>
The OnEvent
element is the heart and soul of the config file definition. It defines a logical event that is mapped to the BAMActivity
element that encloses it. The OnEvent
element contains the four attributes listed in Table 9-4.
The OnEvent
element will also include child elements, as listed in Table 9-5.
You may have noticed within the WF interceptor schema an enumeration of WFOperationTypes
. The WF interceptor provides the ten operations listed in Table 9-6 to extend filter and updating capabilities within an interceptor configuration file.
While incredibly useful when extracting data from WF activities, mapping to WF activities, and flushing that data to BAM, these operations also have their limitations due to the implementation of the WF interceptor, as you may have noticed.
Each of these operations (as well as Equals
, And
, Concatenate
, and Constant
) may only be used against specific track point categories. As you may recall from Chapter 8, Filter
elements and data extraction or manipulation operations are defined within an IC file.
Tables 9-7 and 9-8 summarize whether the operations may be used in filter expression operations and whether they may be used within data extraction or manipulation operations.
Now, with a thorough understanding of the WF IC config, the last step is to edit the WF application’s app.config
file.
The app.config
file edit is really a simple process. Open the app.config
file in Notepad or Visual Studio 2008. Locate the Configuration
element, and within it paste the following:
<WorkflowServiceContainer>
<Services>
<add type="Microsoft.BizTalk.Bam.Interceptors.Workflow.BamTrackingService,
Microsoft.BizTalk.Bam.Interceptors, Version=3.0.1.0, Culture=neutral,
PublicKeyToken=31bf3856ad364e35"
ConnectionString="Integrated Security=SSPI;
Data Source=.;Initial Catalog=BAMPrimaryImport"
PollingIntervalSec="5"/>
</Services>
</WorkflowServiceContainer>
You’ll need to make sure the Section
element is the same name as the one used by your application code when using the WorkflowRuntime
class. You’ll also need to modify the ConnectionString
section to point to the BAM PI database, save the file, and restart your application.
Now that you have a better understanding of how BAM and WF complement one another, we’ll detail how the Arnold, Wilbur, and Olivia Corporation (AWO) utilizes the two technologies to complement one another.
As you’ll recall, AWO is an international leader in specialty building materials construction. AWO began in the 1840s because of combined contributions from its founders Jacobs and Lang. AWO is nearing some 170 years of accrued business knowledge and expertise in the building materials construction space.
Over time, separate and distinct applications have emerged under the guidance and supervision of the enterprise architect at AWO. Some of these systems include
Figure 9-4 presents the diagram for this enterprise architecture.
The BizTalk Server 2009 implementation utilizes the WF interceptor to monitor WF work-flows within each of the applications and provide an end-to-end systems integration business process for builders.
One of the big “value-adds” for AWO over its competitors is that BuilderWeb is fed with real-time data from the enterprise in BAM. When a builder visits the application and browses the catalog, he is able to determine not only whether the building material is in stock and the current price, but also whether there have been any problems in the past with the material and whether the supplier has had a track record of problems. This is important because builders provide a warranty to their houses from defects in materials. Comprehending this risk provides the builder a better understanding of whether the material will withstand a huff and a puff.
BAM is able to monitor outstanding workflow complaints from customers and correspondence that has gone out to suppliers from HogCall, monitor attempts to order materials by BBWolf as part of SheepDetector, and monitor whether BuilderWeb is selling enough materials to meet expected sales.
AWO’s enterprise architect has also contacted AWO’s Microsoft Partner account manager and asked that the next version of SharePoint Server include the ability for BAM to monitor SharePoint Server–based workflows. Currently, BAM may not be used to monitor MOSS work-flows as MOSS is a “closed” workflow system.
EXERCISE 9-1. CREATING A WF SEQUENTIAL WORKFLOW TO MONITOR
EXERCISE 9-2. CREATING A WF OBSERVATION MODEL
EXERCISE 9-3. CREATING THE WF INTERCEPTOR CONFIGURATION
EXERCISE 9-4. LOADING THE WF INTERCEPTOR RUNTIME
Windows Workflow Foundation is a strong complementary technology to BAM.
In this chapter, you learned about WF and the context of BAM within BizTalk and WF. The chapter included coverage of the WF interceptor architecture, how a WF tracking profile is structured, and how to monitor a WF workflow using the WF interceptor. The chapter also covered the syntax of a WF interceptor configuration file and how to edit the app.config
file to enable monitoring of WF workflows within BAM.
Sometimes it is useful to get at an even more granular level when writing data to BAM or when you want to monitor an application that doesn't utilize BizTalk, WCF, or WF. The next chapter will cover the BAM API and how it may be used to capture and process BAM data.