Click here to Skip to main content
Click here to Skip to main content

WorkflowProbe

, 12 Jun 2007 CPOL
Rate this:
Please Sign up or sign in to vote.
The WorkflowProbe is the custom WF Activity for capturing the business behavior within the type/XOML activated Workflow and publishing it to the WCF channel.

Contents

Note: This article was written using

  • .NET Framework 3.0 (RTM)
  • VS 2005 Extensions for Windows Workflow Foundation (RTM)

Features

  • Loosely and tightly coupled instrumentations
  • Auto-publishing properties of the selected activity
  • Explicitly capturing workflow properties
  • Support for sequential and/or state workflows activated by type or XOML
  • Interface contract-driven connectivity
  • Open connectivity model for any physical connectivity
  • Built with WCF connectivity
  • Viewing messages in the Windows TreeView Controller

Introduction

The WorkflowProbe is a custom Windows Workflow Foundation (WF) Activity to enable publishing of captured data to the Windows Communication Foundation (WCF) Channel. Basically, there are two kinds of data capturing: tightly and loosely coupled. In the first case, the Probe is incorporated into the code based on application needs. This process, known as instrumentation, requires compilation and deployment cycles. It is suitable for publishing the checkpoints and/or error exceptions with a fixed position in the code. Note that this case uses only a WorkflowProbe Publisher. See more details later.

The other choice of capturing business data is inserting the probe into the workflow, like an activity, and binding the properties for publishing purposes. The Probe can be plugged into the XOML workflow definition in the loosely coupled manner without any code behind. Dynamically modifying workflow and its probes is a great feature of the XOML-activated workflow.

The WorkflowProbe does't require setup of any properties. However, for capturing more details about the business data flowing, the Probe can be configured for the specific checkpoint using a standard binding mechanism. The following screen snippet shows WorkflowProbe properties:

Screenshot - Workfl11.jpg

As the above picture shows, there are four major categories of the properties:

  • Connectivity to select a specific WCF Publisher Proxy
  • Label as a group of the properties serialized and stored individually for fast query post-processing
  • Options/CaptureActivity enables capture of all public, serializable properties from the selected Activity
  • Parameters is a collection of the WorkflowBindingParameters allowing the capture of any workflow visible properties. The collection is the pair of the string and object, where the string represents a name of the parameter. Note that the publisher will also add binding information behind the property name with a delimiter character.

Beside the above properties, the Publisher will add additional useful information from the workflow. The following code snippet shows a Service Contract for fire-and-forget message publishing. Based on this interface contract, the message can be delivered to the service via different channels, bindings and behaviors.

[ServiceContract]
public interface IProbe
{
    [OperationContract(IsOneWay = true)]
    void WriteMessage(
        DateTime timestamp,     // captured timestamp
        string severity,         // message severity (i.e. Checkpoint, Error)
        string rootActivity,     // the Probe Root Activity 
        string location,         // location of the Probe (the Probe name)
        string topic,        // application specific topic 
        string key,         // application specific key
        string message,         // application specific message text
        Guid contextId,         // activity execution context Id
        Guid instanceId,         // workflow instance Id
        string machineName,     // Netbios machine name
        string appDomainName,     // appDomain name
        IDictionary<string, object> parameters    
            // collection of the captured properties
    );
}

From the connectivity point of the view, the Publisher represents a loosely coupled event source to the subscriber event sink (service). We can design many different event sinks based on business needs using the WCF and WPF technologies. This article includes a viewer of the Probe messages in the Windows Form TreeView Control. The following screenshot shows a WorkflowProbeViewer program connected to the WorkflowProbe via the WCF Channel (netNamedPipeBinding binding):

Screenshot - Workfl1.jpg

The WorkflowProbeViewer is a tiny non-persisted storage of the Probe messages for their interactive examination. The incoming message is stored into the TreeView nodes based on options such as filtering, severity, etc. See more details later. The WorkflowProbe Publisher is designed and implemented for the WCF communication model, which allows many variants via the configuration. The following configuration snippets show default connectivity via the netNamedPipeBinding channel at the client and server sides.

Client-side:

<system.serviceModel>
    <client>
        <endpoint name="WorkflowProbe" 
            address="net.pipe://localhost/WorkflowProbeService/console" 
            binding="netNamedPipeBinding" 
            contract="RKiss.WorkflowProbe.IProbe"/>
    </client>
</system.serviceModel>

Server-side:

<system.serviceModel>
    <services>
        <service name="RKiss.WorkflowProbe.ProbeSink" >
            <endpoint 
                address="net.pipe://localhost/WorkflowProbeService/console" 
                binding="netNamedPipeBinding" 
                contract="RKiss.WorkflowProbe.IProbe"/>
        </service>
    </services> 
</system.serviceModel>

As you can see, it is straightforward to change an endpoint for another binding, address, etc. Any connectivity-related change is done administratively, by simply restarting the workflow and viewer programs.

For changing properties in the WorkflowProbe such as capturing more data, publisher name, etc., we have basically two choices based on how the workflow is activated. In the case of activation by workflow type, we have to rebuild a workflow (tightly coupled instrumentation) and restart it. The second choice, where a workflow is XOML-activated -- meaning that there is no code behind it -- using the WorkflowProbe is very friendly and loosely coupled for any changes such as capturing data, plugging more probes, connectivity, etc. The following picture shows an example of the XOML-activated sequential workflow with a WorklowProbe: Probe1.

Screenshot - Workfl12.jpg

The above Probe1 captured all public properties of the Delay1 Activity. Additionally, the Delay1.TimeoutDuration has been attached to the Parameters collection. It is very easy to make any dynamic changes in the XOML resource based on the captured messages to tune a business workflow.

The WorkflowProbeViewer can collect the Probe messages from many workflows. However, for enterprise distributed applications, it is suitable to store the messages into the database and create a knowledge base of the application behavior for post-processing tools such as monitoring, tuning, analyzing, etc. The Interface Contract allows direct storage of a "parallel" message information necessary for fast query of the specific workflow context.

As I mentioned earlier, the captured data are serialized in the WCF Channel by default DataContractSerializer. During runtime, the serializer needs to know all object types. Otherwise, the Parameters will show a warning message. The missing types can be added into the config file, as is shown in the following config snippet:

Screenshot - Workf36.jpg

In the above example, the Dictionary<T, K> type has been added to the serializer. Note that WorkflowProbeViewer does not deserialize a probe message. It will therefore work for any type, since we need only display the elements and attributes of the message body.

That's all for a basic introduction of WorkflowProbe. I would now like to show some advanced usage of this Probe employing its Interface Contract.

Advanced WorkflowProbe features

  • The WorkflowProbe interface contract allows generation of an application-specific message to another workflow or WCF Service. More specific descriptions about the interface contract-driven communications with the workflow can be found in my article Workflow Adapter/Connector Pair.In this scenario, the WorkflowProbe represents an Adapter activity that sends a message to the Connector in the fire-and-forget manner. The following picture shows a connectivity to the State machine Workflow, where its Processor state is waiting for the IProbe message by the Connector_Fire Activity. Note that this scenario only requires the correct configuration and binding parameters.

Screenshot - Workfl2.jpg

  • The WorkflowProbe Publisher can be used within the code to send the IProbe message to another Workflow or WCF Service. The message can be qualified with appropriate Severity. The following code snippet shows how easily messages are sent without any additional parameters:
    // send info message via the default publisher
    Probe.Info(this, "MyTopic", "MyKey", "MyMessage", null);
    
    // send error message via the default publisher
    Probe.Error(this, "MyTopic", "MyKey", exception", null);
    
    // send info message via MyPublisher publisher
    Probe.Write(this,"MyPublisher", Severity.Info, 
        topic,key, message, null, null);
  • Connecting to the WS-Eventing model is permitted. From the WS-Eventing specification point of the view, the WorkflowProbe represents an Event Source to the Event Sink. The Subscriber subscribes an Event Sink interest -- including topic/key filter -- to the Subscription Manager for delivering an IProbe message to the specific Event Sink. The Probe is connected to the Notification Manager, where the message is delivered based on the active subscriptions in Subscription Storage. Of course, the Event Sink can be the Workflow Connector(s), as well. Based on the registered Subscription, the IProbe message can be delivered to many different Event Sinks via their bindings such as TCP, P2P, HTTP, MSMQ, named pipe, etc. The following picture shows a WorkflowProbe position in the WS-* driven Service Bus:

Screenshot - Workfl7.jpg

WorkflowProbeViewer

The WorkflowProbeViewer is a tiny monitoring tool that stores and examines the IProbe messages in the Windows TreeView Controller. The IProbe message contract is divided into two parts. The first one is known as a parallel message with predefined properties (timestamp, topic, key, etc.). This parallel probe information represents a unique key of the IProbe message for post-processing query. The other part of the message is the collection of the workflow properties based on the post-process interest. This part is serialized in the Dictionary<string, object> object. The following picture shows an example of the one IProbe Message captured in the Workflow1 by Probe1:

Screenshot - Workfl100.jpg

Note that the TreeView Node shows the type of the parameters. If the value of the parameters has been retrieved via binding process, this information is shown in the Node label. For example: Workflow1.TestNumber/(Workflow1, Path=TestNumber). The WorkflowProbeViewer features can be changed via context menu. Right Click on the TreeView pannel and we will see the following items:

Screenshot - Workfl4.jpg

There are 3 major items in the context menu:

  • Find Context is for expanding all nodes related to the same ContextId. By pressing the F4 key, we can expand/collapse these nodes.
  • Circulate enables circulation of IProbe Messages within the max number of TreeView Nodes. The default number of the Nodes is 100, but it can be changed in the config file.
  • Filter enables filtering of a specific incoming IProbe Message before storing it in the TreeView Node.

As you can see in the following picture, the WorkflowProbeViewer uses the WF Rule Set Editor to set up a message filter. By passing the ProbeMessageControl object to the RuleExecution, we can control the message and the storage such as maxNumberOfSamples, EnableProbe, CirculateSamples, ExpandNode, etc.

Screenshot - Workf25.jpg

The above Rule1 has been set up to store a short message (no parameters) when Topic=="Test1" and Key=="XOML". We can create many Rules and Rule Sets and select them later via the context menu.

Concept and design implementation

The concept of the WorkflowProbe is based on sending a message to the WCF channel in the fire-and-forget manner. The IProbe message can be created programmatically within the workflow code or by custom WorkflowProbe Activity. The following code snippet shows an Execute override method of the WorkflowProbe Activity, where the execution logic is divided into the 3 major parts: collecting captured parameters, collecting parameters from the selected Activity and calling the static Probe.Write method of the publisher.

protected override ActivityExecutionStatus Execute(
    ActivityExecutionContext executionContext)
{
    Activity activity = executionContext.Activity.Parent;

    // intercept before the call
    base.RaiseEvent(WorkflowProbe.InvokingEvent, this, EventArgs.Empty);
    OnInvoking(this);

    // explicitly captured workflow parameters           
    Dictionary<string, object> parameters = 
        CollectParameters(this.Parameters, null);

    // implicitly captured activity parameters
    if (this.CaptureActivity != "(none)")
    {
        Activity selActivity = 
            activity.GetActivityByName(this.CaptureActivity);
        if (selActivity != null)
        {
            Activity selectedActivity = 
                activity.GetActivityByName(this.CaptureActivity);
            if (selectedActivity != null)
            {
                Dictionary<string, object> activityProperties = 
                    CollectActivityParameters(selectedActivity, null);
                parameters.Add(selectedActivity.QualifiedName, 
                    activityProperties);
            }
        }   
    }

    // publish
    Probe.Write(this, this.Publisher, this.Severity, 
        this.QualifiedName, this.Topic, 
        this.Key, this.Message, parameters);

    return ActivityExecutionStatus.Closed;
}

The Publisher proxy is a standard WCF channel proxy based on the publisher config parameters:

// publisher proxy
ChannelFactory<IProbe> factory = new ChannelFactory<IProbe>(publisher);
channel = factory.CreateChannel();

channel.WriteMessage(DateTime.Now, severity.ToString(), 
    rootActivity, location, topic, 
    key, message, contextId, instanceId, Environment.MachineName, 
    AppDomain.CurrentDomain.FriendlyName, parameters);
  
    ((IChannel)channel).Close();

Note that the Publisher proxy will not throw any exceptions and that the service operation is declared as OneWay. Therefore the proxy will not wait for delivery of the message to the service (i.e. the fire-and-forget message pattern). To receive an IProbe message by the Windows Form program, we need to create a service class with a service contract and host it in the Windows Form. The following code snippet shows plumbing of the WCF Service with Windows Form using the IExtension<ServiceHostBase> mechanism:

namespace RKiss.WorkflowProbe
{
    #region Interface Contract
    [ServiceContract]
    public interface IProbe
    {
        [OperationContract(IsOneWay = true)]
        [ServiceKnownTypeAttribute(typeof(Exception))]
        void WriteMessage(Message message);
    }
    #endregion
  
    #region Service
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class ProbeSink : IProbe
    {
        #region IProbe Members
        public void WriteMessage(System.ServiceModel.Channels.Message message)
        {
            Form1 form = 
                OperationContext.Current.Host.Extensions.Find<Form1>();
            XmlDictionaryReader reader = message.GetReaderAtBodyContents();
            ProbeMessageControl pm = new ProbeMessageControl(reader);
            form.AddToTheTreeView(pm);
        }
        #endregion
    }
    #endregion
}

The following code snippet shows how Form1 has been attached to ServiceHost:

[STAThread]
static void Main()
{
    ServiceHost host = null;
    try
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Form1 form = new Form1();

        host = new ServiceHost(typeof(ProbeSink));
        host.Extensions.Add(form);
        host.Open();

        Application.Run(form);
    }
    catch (Exception ex)
    {
        Trace.WriteLine(ex);
    }
    finally
    {
        if (host != null)
            host.Close();
    }
}

That is all for the description of WorkflowProbe's conceptual parts and their implementation. Let's start testing.

Test

The WorkflowProbe solution contains few projects. There are two major projects: WorkflowProbe (Publisher) and WorkflowProbeViewer (Subscriber). For testing purposes, the solution contains the Client and WorkflowLibrary projects. The usage of WorkflowProbe requires adding the WorkflowProbe.dll assembly to the application bin folder or inserting it into the GAC. The following picture shows these projects in the WorkflowProbe solution:

Screenshot - Workfl500.jpg

The test of the WorkflowProbe is based on activating two workflow samples by type and XOML (Workflow1 and Workflow2) instrumented with WorkflowProbes. The following code snippet shows a test loop of the client side:

for (int ii = 0; ii < 100; ii++)
{
    // activate type workflow
    Dictionary<STRING, object> initdata = new Dictionary<STRING, object>();
    initdata["TestNumber"] = ii;
    WorkflowInstance instance1 = 
        workflowRuntime.CreateWorkflow(typeof(WorkflowLibrary.Workflow1), 
        initdata);
    instance1.Start();
  
    // activate xoml workflow
    string filename = @"..\..\..\WorkflowLibrary\Workflow2.xoml";
    using (XmlTextReader reader = new XmlTextReader(filename))
    {
        WorkflowInstance instance2 = workflowRuntime.CreateWorkflow(reader);
        instance2.Start();
    }
  
    waitHandle.WaitOne();
  
    Console.WriteLine("Press any key to continue ...");
    Console.ReadLine();
}

Now we can launch the WorkflowProbeViewer and Client (Tester) programs. By pressing the Enter key on the Tester console, the workflows will generate four IProbe Messages. The following picture shows this test:

Screenshot - Workfl501.jpg

The messages can be expanded in order to examine their context. After the test loop has succeeded, the WorkflowProbe can be inserted into the application Workflow and collect messages by WorkflowProbeViewer. Note that the application config file requires addition of the WCF proxy configuration. The following is an example of the client WorkflowProbe proxy channel configuration for named pipe binding:

<system.serviceModel>
    <client>
        <endpoint name="WorkflowProbe" 
            address="net.pipe://localhost/WorkflowProbeService/console" 
            binding="netNamedPipeBinding" 
            contract="RKiss.WorkflowProbe.IProbe"/>
    </client>
</system.serviceModel>

Conclusion

This article described a WorkflowProbe custom activity for capturing workflow properties and publishing them via the WCF Channel to a subscriber such as WorkflowProbeViewer. The WorkflowProbe Subscriber can be designed and implemented for different WCF Services based on business needs. Besides that, WorkflowProbe can be used to fire an event message to another workflow or service. The primary usage of WorkflowProbe is troubleshooting business workflow data and behavior. It is a free, tiny trace tool.

History

  • 5 November, 2006 -- Original version posted
  • 10 November, 2006 -- Updated
  • 12 June, 2007 -- Article edited and posted to the main CodeProject.com article base

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Roman Kiss
Software Developer (Senior)
United States United States
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmembersokalamax15-Nov-11 17:11 
QuestionAbout The &quot;CaptureActivity&quot; Property OF WorkflowProbe PinmemberCode Tom25-Sep-07 21:35 
GeneralVery Nice article [modified] PinmemberWcohen19-Jun-07 6:57 
GeneralRe: Very Nice article PinmemberRoman Kiss19-Jun-07 9:27 
GeneralNew upload (fixed small bug in the TreeView) PinmemberRoman Kiss10-Nov-06 11:38 
QuestionIs this the proper place for tracing? PinmemberRichard Gavel9-Nov-06 7:10 
AnswerRe: Is this the proper place for tracing? PinmemberRoman Kiss9-Nov-06 10:39 
GeneralExcellent WF Activity Pinmemberaerradi7-Nov-06 11:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.1411023.1 | Last Updated 12 Jun 2007
Article Copyright 2006 by Roman Kiss
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid