Metadata >> NuGet >> Microsoft.Activities.UnitTesting >> 2.0.3.9 >> Release .NETFramework,Version=v4.0.1 >> Microsoft.Activities.Extensions

Microsoft.Activities.Extensions/Tracking/StateMachineStateTracker.cs

// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StateMachineStateTracker.cs" company="Microsoft">
//   Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------

namespace Microsoft.Activities.Extensions.Tracking
{
    using System;
    using System.Activities;
    using System.Activities.DurableInstancing;
    using System.Activities.Statements;
    using System.Activities.Statements.Tracking;
    using System.Activities.Tracking;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Text;

#if NET401_OR_GREATER

    /// <summary>
    /// The state machine state tracker.
    /// </summary>
    public class StateMachineStateTracker : TrackingParticipant
    {
        #region Constants and Fields

        /// <summary>
        /// The find existing instances sql.
        /// </summary>
        private const string FindExistingInstancesSql =
            @"SELECT InstanceId, Value1      
FROM [System.Activities.DurableInstancing].[InstancePromotedProperties]
WHERE PromotionName = '{0}' 
AND Value2 = @ActivityID
AND Value3 = @DisplayName;";

        private const string FindExistingInstanceSql =
            @"SELECT InstanceId, Value1      
FROM [System.Activities.DurableInstancing].[InstancePromotedProperties]
WHERE PromotionName = '{0}' 
AND InstanceId = @InstanceId
AND Value2 = @ActivityID
AND Value3 = @DisplayName;";

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="StateMachineStateTracker"/> class. 
        /// </summary>
        /// <param name="rootActivity">
        /// The root Activity.
        /// </param>
        public StateMachineStateTracker(Activity rootActivity)
        {
            if (rootActivity == null)
            {
                throw new ArgumentNullException("rootActivity");
            }

            this.RootActivity = rootActivity;
            this.TrackedStateMachines = new Dictionary<string, StateTrackerInfo>();
        }

        #endregion

        #region Public Properties

        /// <summary>
        /// Gets CurrentState.
        /// </summary>
        public string CurrentState
        {
            get
            {
                return this.HasCurrentStateMachine()
                           ? this.TrackedStateMachines[this.CurrentStateMachine].CurrentState
                           : null;
            }
        }

        /// <summary>
        /// Gets CurrentStateMachine.
        /// </summary>
        public string CurrentStateMachine { get; internal set; }

        /// <summary>
        /// Gets InstanceId.
        /// </summary>
        public Guid InstanceId { get; internal set; }

        /// <summary>
        /// Gets PossibleTransitions of the currently executing StateMachine.
        /// </summary>
        public string PossibleTransitions
        {
            get
            {
                return this.HasCurrentStateMachine()
                           ? this.TrackedStateMachines[this.CurrentStateMachine].PossibleTransitions
                           : null;
            }
        }

        /// <summary>
        /// Gets RootActivity.
        /// </summary>
        public Activity RootActivity { get; private set; }

        /// <summary>
        /// Gets TrackedStateMachines.
        /// </summary>
        public Dictionary<string, StateTrackerInfo> TrackedStateMachines { get; private set; }

        /// <summary>
        /// Gets Transitions.
        /// </summary>
        public ICollection<Transition> Transitions
        {
            get
            {
                return this.HasCurrentStateMachine()
                           ? this.TrackedStateMachines[this.CurrentStateMachine].Transitions
                           : null;
            }
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The load instances.
        /// </summary>
        /// <param name="rootActivity">
        /// The root activity.
        /// </param>
        /// <param name="connectionString">
        /// The connection string.
        /// </param>
        /// <returns>
        /// </returns>
        public static IEnumerable<StateMachineStateTracker> LoadInstances(
            Activity rootActivity, string connectionString)
        {
            if (string.IsNullOrWhiteSpace(rootActivity.Id))
            {
                WorkflowInspectionServices.CacheMetadata(rootActivity);
            }

            try
            {
                using (var connection = new SqlConnection(connectionString))
                {
                    var command =
                        new SqlCommand(
                            string.Format(FindExistingInstancesSql, StateTrackerPersistenceProvider.StateTrackerName), 
                            connection);
                    command.Parameters.AddWithValue("@ActivityID", rootActivity.Id);
                    command.Parameters.AddWithValue("@DisplayName", rootActivity.DisplayName);
                    connection.Open();
                    var list = new List<StateMachineStateTracker>();
                    var dataReader = command.ExecuteReader();
                    while (dataReader.Read())
                    {
                        list.Add(
                            StateTrackerPersistenceProvider.Parse(
                                rootActivity, dataReader.GetGuid(0), dataReader.GetString(1)));
                    }

                    dataReader.Close();
                    return list;
                }
            }
            catch (Exception exception)
            {
                System.Diagnostics.Trace.WriteLine(exception.Message);
            }

            return null;
        }

        /// <summary>
        /// The load instances.
        /// </summary>
        /// <param name="instanceId">The instance Id </param>
        /// <param name="rootActivity">
        /// The root activity.
        /// </param>
        /// <param name="connectionString">
        /// The connection string.
        /// </param>
        /// <returns>
        /// </returns>
        public static StateMachineStateTracker LoadInstance(Guid instanceId,
            Activity rootActivity, string connectionString)
        {
            if (string.IsNullOrWhiteSpace(rootActivity.Id))
            {
                WorkflowInspectionServices.CacheMetadata(rootActivity);
            }

            try
            {
                using (var connection = new SqlConnection(connectionString))
                {
                    var command =
                        new SqlCommand(
                            string.Format(FindExistingInstanceSql, StateTrackerPersistenceProvider.StateTrackerName),
                            connection);
                    command.Parameters.AddWithValue("@InstanceId", instanceId);
                    command.Parameters.AddWithValue("@ActivityID", rootActivity.Id);
                    command.Parameters.AddWithValue("@DisplayName", rootActivity.DisplayName);
                    connection.Open();
                    var dataReader = command.ExecuteReader();
                    dataReader.Read();
                    return        StateTrackerPersistenceProvider.Parse(rootActivity, dataReader.GetGuid(0), dataReader.GetString(1));                    
                }
            }
            catch (Exception exception)
            {
                System.Diagnostics.Trace.WriteLine(exception.Message);
            }

            return null;
        }


        /// <summary>
        /// The promote.
        /// </summary>
        /// <param name="instanceStore">
        /// The instance store.
        /// </param>
        public static void Promote(SqlWorkflowInstanceStore instanceStore)
        {
            StateTrackerPersistenceProvider.Promote(instanceStore);
        }

        /// <summary>
        /// The trace.
        /// </summary>
        public void Trace()
        {
            var msg = new StringBuilder();
            msg.AppendFormat(
                "StateMachineStateTracker Tracking {0} state machine(s)\r\n", this.TrackedStateMachines.Count);
            foreach (var stateInfo in this.TrackedStateMachines.Values)
            {
                msg.AppendFormat("StateMachine: {0}\r\n", stateInfo.StateMachineName);
                msg.AppendFormat("\tCurrentState: {0}\r\n", stateInfo.CurrentState);
                msg.AppendFormat("\tPossibleTransitions: {0}\r\n", stateInfo.PossibleTransitions);
            }

            System.Diagnostics.Trace.WriteLine(msg.ToString());
        }

        #endregion

        #region Methods

        /// <summary>
        /// The track.
        /// </summary>
        /// <param name="record">
        /// The record.
        /// </param>
        /// <param name="timeout">
        /// The timeout.
        /// </param>
        protected override void Track(TrackingRecord record, TimeSpan timeout)
        {
            var smsr = record as StateMachineStateRecord;

            if (smsr != null)
            {
                try
                {
                    this.TrackedStateMachines.Remove(smsr.StateMachineName);
                }
                catch (KeyNotFoundException)
                {
                    // Do nothing - this is ok
                }

                this.InstanceId = smsr.InstanceId;

                var stateInfo = new StateTrackerInfo
                    {
                        CurrentState = smsr.StateName, 
                        StateMachineName = smsr.StateMachineName, 
                        Transitions = smsr.GetTransitions(this.RootActivity), 
                    };

                this.CurrentStateMachine = smsr.StateMachineName;
                this.TrackedStateMachines.Add(smsr.StateMachineName, stateInfo);
            }
            else
            {
                var wir = record as WorkflowInstanceRecord;
                if (wir != null)
                {
                    switch (wir.GetState())
                    {
                        case WorkflowInstanceRecordState.Canceled:
                            this.Clear();
                            break;
                        case WorkflowInstanceRecordState.Completed:
                            this.Clear();
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// The clear.
        /// </summary>
        private void Clear()
        {
            this.TrackedStateMachines.Clear();
            this.CurrentStateMachine = string.Empty;
        }

        /// <summary>
        /// The has current state machine.
        /// </summary>
        /// <returns>
        /// The has current state machine.
        /// </returns>
        private bool HasCurrentStateMachine()
        {
            return !string.IsNullOrWhiteSpace(this.CurrentStateMachine);
        }

        #endregion

        /// <summary>
        /// The state tracker info.
        /// </summary>
        public class StateTrackerInfo
        {
            #region Public Properties

            /// <summary>
            /// Gets CurrentState.
            /// </summary>
            public string CurrentState { get; internal set; }

            /// <summary>
            /// Gets PossibleTransitions.
            /// </summary>
            public string PossibleTransitions
            {
                get
                {
                    var result = new StringBuilder();

                    foreach (var e in this.Transitions)
                    {
                        if (result.Length > 0)
                        {
                            result.Append(", ");
                        }

                        result.AppendFormat("{0}", e.DisplayName);
                    }

                    return result.ToString();
                }
            }

            /// <summary>
            /// Gets StateMachineName.
            /// </summary>
            public string StateMachineName { get; internal set; }

            /// <summary>
            /// Gets Transitions.
            /// </summary>
            public ICollection<Transition> Transitions { get; internal set; }

            #endregion
        }
    }

#endif
}

Microsoft.Activities.Extensions

Depedencies

Name AssemblyVersion Culture PublicKeyToken Type
Microsoft.CSharp 4.0.0.0 neutral b03f5f7f11d50a3a Required
mscorlib 4.0.0.0 neutral b77a5c561934e089 Required
System 4.0.0.0 neutral b77a5c561934e089 Required
System.Activities 4.0.0.0 neutral 31bf3856ad364e35 Required
System.Activities.DurableInstancing 4.0.0.0 neutral 31bf3856ad364e35 Required
System.Configuration 4.0.0.0 neutral b03f5f7f11d50a3a Required
System.Core 4.0.0.0 neutral b77a5c561934e089 Required
System.Data 4.0.0.0 neutral b77a5c561934e089 Required
System.Runtime.DurableInstancing 4.0.0.0 neutral 31bf3856ad364e35 Required
System.ServiceModel 4.0.0.0 neutral b77a5c561934e089 Required
System.ServiceModel.Activities 4.0.0.0 neutral 31bf3856ad364e35 Required
System.Xaml 4.0.0.0 neutral b77a5c561934e089 Required
System.Xml 4.0.0.0 neutral b77a5c561934e089 Required
System.Xml.Linq 4.0.0.0 neutral b77a5c561934e089 Required

Sources

Path Related
Microsoft.Activities.Extensions/ActivityContextExtensions.cs Source
Microsoft.Activities.Extensions/ActivityXamlServicesEx.cs Source
Microsoft.Activities.Extensions/BookmarkResumptionException.cs Source
Microsoft.Activities.Extensions/CodeActivityMetadataExtensions.cs Source
Microsoft.Activities.Extensions/Diagnostics/TraceTrackingParticipant.cs Source
Microsoft.Activities.Extensions/Diagnostics/WorkflowApplicationIdleEventArgsDiagnostics.cs Source
Microsoft.Activities.Extensions/Diagnostics/WorkflowServiceTraceBehavior.cs Source
Microsoft.Activities.Extensions/Diagnostics/WorkflowServiceTraceElement.cs Source
Microsoft.Activities.Extensions/InArgumentExtensions.cs Source
Microsoft.Activities.Extensions/InputDictionary.cs Source
Microsoft.Activities.Extensions/NativeActivityMetadataExtensions.cs Source
Microsoft.Activities.Extensions/Occurance.cs Source
Microsoft.Activities.Extensions/OutputDictionary.cs Source
Microsoft.Activities.Extensions/ReflectionObject.cs Source
Microsoft.Activities.Extensions/ServiceModel/ConfigurationElementCollection.cs Source
Microsoft.Activities.Extensions/ServiceModel/SilverlightFaultBehavior.cs Source
Microsoft.Activities.Extensions/ServiceModel/SilverlightFaultElement.cs Source
Microsoft.Activities.Extensions/ServiceModel/StateMachineTrackingBehavior.cs Source
Microsoft.Activities.Extensions/ServiceModel/StateMachineTrackingElement.cs Source
Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionConfigElement.cs Source
Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionsBehavior.cs Source
Microsoft.Activities.Extensions/ServiceModel/WorkflowExtensionsElement.cs Source
Microsoft.Activities.Extensions/SR.Designer.cs Source
Microsoft.Activities.Extensions/Statements/AddToDictionary.cs Source
Microsoft.Activities.Extensions/Statements/ClearDictionary.cs Source
Microsoft.Activities.Extensions/Statements/DelayUntilDateTime.cs Source
Microsoft.Activities.Extensions/Statements/DelayUntilTime.cs Source
Microsoft.Activities.Extensions/Statements/GetFromDictionary.cs Source
Microsoft.Activities.Extensions/Statements/InvokeWorkflow.cs Source
Microsoft.Activities.Extensions/Statements/KeyExistsInDictionary.cs Source
Microsoft.Activities.Extensions/Statements/LoadActivity.cs Source
Microsoft.Activities.Extensions/Statements/LoadAndInvokeWorkflow.cs Source
Microsoft.Activities.Extensions/Statements/LoadAssembly.cs Source
Microsoft.Activities.Extensions/Statements/RemoveFromDictionary.cs Source
Microsoft.Activities.Extensions/Statements/ValueExistsInDictionary.cs Source
Microsoft.Activities.Extensions/StrictXamlHelper.cs Source
Microsoft.Activities.Extensions/Tracking/ActivityScheduledRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/ActivityStateRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/BookmarkResumptionRecord.cs Source
Microsoft.Activities.Extensions/Tracking/CancelRequestedRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/CustomTrackingRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/FaultPropagationRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/ListExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/ListTrackingParticipant.cs Source
Microsoft.Activities.Extensions/Tracking/StateMachineStateRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/StateMachineStateTracker.cs Source
Microsoft.Activities.Extensions/Tracking/StateTrackerPersistenceProvider.cs Source
Microsoft.Activities.Extensions/Tracking/TrackingHelper.cs Source
Microsoft.Activities.Extensions/Tracking/TrackingRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/WorkflowInstanceAbortedRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/WorkflowInstanceRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/WorkflowInstanceSuspendedRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/WorkflowInstanceTerminatedRecordExtensions.cs Source
Microsoft.Activities.Extensions/Tracking/WorkflowInstanceUnhandledExceptionRecordExtensions.cs Source
Microsoft.Activities.Extensions/WorkflowAbortedEpisodeResult.cs Source
Microsoft.Activities.Extensions/WorkflowApplicationExtensions.cs Source
Microsoft.Activities.Extensions/WorkflowApplicationIdleEventArgsEx.cs Source
Microsoft.Activities.Extensions/WorkflowArguments.cs Source
Microsoft.Activities.Extensions/WorkflowCompletedEpisodeResult.cs Source
Microsoft.Activities.Extensions/WorkflowEpisode.cs Source
Microsoft.Activities.Extensions/WorkflowIdleEpisodeResult.cs Source