Esempio n. 1
0
        public void TestPersistWithWrongStoreThrows()
        {
            var a = new Multiply()
            {
                X = 3,
                Y = 7,
            };


            AutoResetEvent syncEvent = new AutoResetEvent(false);

            var app = new WorkflowApplication(a);

            app.InstanceStore   = new SqlWorkflowInstanceStore("Server =localhost; Initial Catalog = WFXXX; Integrated Security = SSPI");
            app.PersistableIdle = (eventArgs) =>
            {
                Assert.True(false, "quick action no need to persist");//lazy
                return(PersistableIdleAction.Persist);
            };

            //None of the handlers should be running
            app.OnUnhandledException = (e) =>
            {
                return(UnhandledExceptionAction.Abort);
            };

            var ex = Assert.Throws <System.Runtime.DurableInstancing.InstancePersistenceCommandException>
                         (() => app.Persist(TimeSpan.FromSeconds(2)));

            Assert.NotNull(ex.InnerException);
            //            Assert.Equal(typeof(TimeoutException), ex.InnerException.GetType()); sometimes is SqlException.
        }
Esempio n. 2
0
        static void StartAndUnloadInstance()
        {
            WorkflowApplication application = new WorkflowApplication(activity);

            application.InstanceStore = instanceStore;

            //returning IdleAction.Unload instructs the WorkflowApplication to persists application state and remove it from memory
            application.PersistableIdle = (e) =>
            {
                return(PersistableIdleAction.Unload);
            };

            application.Unloaded = (e) =>
            {
                instanceUnloaded.Set();
            };


            //This call is not required
            //Calling persist here captures the application durably before it has been started
            application.Persist();
            id = application.Id;
            application.Run();

            instanceUnloaded.WaitOne();
        }
Esempio n. 3
0
        public WorkflowApplication CreateWorkflow(Activity activity, IDictionary <string, object> inputs, Guid instanceId, bool notUseActivityStackTrace, bool usePersistAndLog)
        {
            if (_instances.Value.ContainsKey(instanceId))
            {
                throw new DeveloperException("Процесс с кодом '{0}' уже существует.", instanceId);
            }

            var result = new WorkflowApplication(activity, inputs)
            {
                SynchronizationContext = SynchronizationContext.Current
            };

            //Настраиваем Activity StackTrace
            ClearTrackingSource();
            if (!notUseActivityStackTrace)
            {
                _trackingSource = new ActivityStackTrace();
                result.Extensions.Add(CreateActivityTrackingParticipant());
            }

            var traceExtension = new TraceExtension
            {
                NotUseActivityStackTrace = notUseActivityStackTrace,
                UsePersistAndLog         = usePersistAndLog
            };

            traceExtension.Set(TraceExtension.ParentWfInstanceIdPropertyName, instanceId);
            traceExtension.Set(TraceExtension.ActivityTrackingSourcePropertyName, _trackingSource);
            result.Extensions.Add(traceExtension);

            if (usePersistAndLog)
            {
                result.InstanceStore = new XmlWorkflowInstanceStore(result.Id);
                //Create the persistence Participant and add it to the workflow instance
                result.Extensions.Add(new XmlPersistenceParticipant(instanceId, result.Id));
                //Add a tracking participant
                result.Extensions.Add(new SaveAllEventsToFileTrackingParticipant());
            }

            _instances.Value.Add(instanceId, result);
            _keyLink.Value.Add(result.Id, instanceId);

            // пропишем события
            SubscribeEvents(result);

            if (usePersistAndLog)
            {
                result.Persist();
            }

            return(result);
        }
Esempio n. 4
0
        public void TestPersistNonPersistable()
        {
            var a = new Multiply()
            {
                X = 3,
                Y = 7,
            };

            bool           completed1 = false;
            AutoResetEvent syncEvent  = new AutoResetEvent(false);

            var app = new WorkflowApplication(a);

            app.InstanceStore   = WFDefinitionStore.Instance.Store;
            app.PersistableIdle = (eventArgs) =>
            {
                Assert.True(false, "quick action no need to persist");//lazy
                return(PersistableIdleAction.Persist);
            };

            //None of the handlers should be running
            app.OnUnhandledException = (e) =>
            {
                return(UnhandledExceptionAction.Abort);
            };

            app.Completed = (e) =>
            {
                completed1 = true;
                syncEvent.Set();
            };

            app.Unloaded = (e) =>
            {
                Assert.True(false, "Nothing to persist");
            };

            app.Idle = e =>
            {
            };

            app.Persist();
            var id = app.Id;

            app.Run();
            syncEvent.WaitOne();

            Assert.True(completed1);
        }
Esempio n. 5
0
        public void StartAndPersistInstance(Guid _documentId, DocumentState _state, IDictionary <string, object> documentData)
        {
            try
            {
                var documentTable = _DocumentService.Find(_documentId);
                IDictionary <string, object> inputArguments = new Dictionary <string, object>();
                inputArguments.Add("inputStep", _state);
                inputArguments.Add("inputDocumentId", _documentId);
                inputArguments.Add("inputCurrentUser", HttpContext.Current.User.Identity.Name);
                inputArguments.Add("documentData", documentData);

                WorkflowApplication application = new WorkflowApplication(activity, inputArguments);
                application.InstanceStore = instanceStore;
                application.Extensions.Add(new WFTrackingParticipant());

                #region Workflow Delegates

                application.PersistableIdle = (e) =>
                {
                    var ex = e.GetInstanceExtensions <WFTrackingParticipant>();
                    outputParameters = ex.First().Outputs;
                    //instanceUnloaded.Set();
                    return(PersistableIdleAction.Unload);
                };
                application.Unloaded = (e) =>
                {
                    instanceUnloaded.Set();
                };

                #endregion Workflow Delegates

                application.Persist();
                application.Run();
                instanceUnloaded.WaitOne();

                documentTable.WWFInstanceId = application.Id;
                documentTable.DocumentState = (DocumentState)outputParameters["outputStep"];
                _DocumentService.UpdateDocument(documentTable);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 创建并启动一个工作流,在申请时候触发
        /// </summary>
        /// <param name="meeting">申请时所填表单的数据</param>
        /// <returns>返回一个Guid</returns>
        public static Guid CreateAndRun(Model.Meeting meeting, Dictionary <int, int> d_EquipmentCount, Dictionary <string, string> MeetingUserNameAndEmail, Model.MeetingRoom MeetingRoomIDAndName)
        {
            SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore(connectionString);
            InstanceView             view          = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromDays(30));

            instanceStore.DefaultInstanceOwner = view.InstanceOwner;

            IDictionary <string, object> input = new Dictionary <string, object>();

            input.Add("Request", meeting);
            input.Add("EquipmentCount", d_EquipmentCount);
            input.Add("MeetingUserEmailFrom", MeetingUserNameAndEmail);
            input.Add("MeetingRoomIDAndName", MeetingRoomIDAndName);
            WorkflowApplication application = new WorkflowApplication(new MeetingApply(), input);

            application.InstanceStore   = instanceStore;
            application.PersistableIdle = (e) =>
            {
                instanceUnloaded.Set();
                return(PersistableIdleAction.Unload);
            };

            application.Unloaded = (e) =>
            {
                instanceUnloaded.Set();
            };

            application.OnUnhandledException = (ex) =>
            {
                return(UnhandledExceptionAction.Terminate);
            };

            Guid id = application.Id;

            application.Persist();
            application.Run();
            instanceUnloaded.WaitOne();
            return(id);
        }
Esempio n. 7
0
        /// <summary>
        ///     Starts processing the given activity via the WorkflowApplication.
        /// </summary>
        /// <param name="command">The command to be ran.</param>
        /// <param name="firstParameter">The first parameter to include (if any).</param>
        /// <param name="secondParameter">The second parameter to include (if any).</param>
        /// <param name="thirdParameter">The third parameter to include (if any).</param>
        private void StartWorkflowScience(string command, string firstParameter, string secondParameter, string thirdParameter /* future use */)
        {
            // Now stage the WorkflowApplication, using the SQL instance, wrapped in using to dispose all of the things when done.
            using (AutoResetEvent syncEvent = new AutoResetEvent(false))
            {
                // NOTE: If the string doesn't - explicitly - match, the .ctor() of the
                // SwedishCodeActivity will throw, since the string is the key. Also,
                // no boxing/unboxing required for Dictionary<T,T>; which saves overhead.
                Dictionary <string, SwedishCodeActivity <object> > newDictionary = new Dictionary <string, SwedishCodeActivity <object> >
                {
                    // See the 'Activities' folder for examples of Activities that you can use here.
                    { "CheckFreeDiskSpaceActivity", new CheckFreeDiskSpaceActivity() },
                    { "CopyFilesActivity", new CopyFilesActivity() },
                    { "CopyNIsAndDLLsActivity", new CopyImagesAndLibrariesActivity() },
                    { "DateTimeActivity", new UtcDateTimeActivity() },
                    { "DumpProcessThreadsActivity", new DumpProcessThreadsActivity() },
                    { "FileExistsActivity", new CheckIfFileExistsActivity() },
                    { "ForceBlueScreenActivity", new ForceBlueScreenActivity() },
                    { "GetLoggedOnUsersActivity", new GetCurrentLoggedOnUsersActivity() },
                    { "GetOsFileVersionActivity", new GetOsFileVersionActivity() },
                    { "GetProcessIdActivity", new GetProcessIdsActivity() },
                    { "GetSystemUptimeActivity", new GetSystemUptimeActivity() },
                    { "GetTimeSkewActivity", new GetSystemTimeSkewActivity() },
                    { "InstallSysInternalsActivity", new InstallSysInternalsActivity() },
                    { "ModifyConfigurationFileActivity", new EditConfigurationFileActivity() },
                    { "PingActivity", new PingResponseActivity() },
                    { "PortConnectivityActivity", new PortConnectivityActivity() },
                    { "ReadFileContentsActivity", new ReadFileContentsActivity() },
                    { "RenameMachineActivity", new RenameMachineActivity() },
                    { "RestartServiceActivity", new RestartServiceActivity() },
                    { "SetSymbolsEnvironmentPath", new SetSymbolServerEnvironmentPathActivity() },
                    { "StartSecureDeleteActivity", new StartSecureDeleteActivity() },
                    { "WindowsUpdateActivity", new WindowsUpdateActivity() },
                    { "WebStringActivity", new WebStringActivity() }
                };

                SwedishCodeActivity <object> newSwedishCodeActivity = (SwedishCodeActivity <object>)newDictionary[command];
                if (!string.IsNullOrWhiteSpace(firstParameter))
                {
                    newSwedishCodeActivity.FirstInArgument = firstParameter;
                }

                if (!string.IsNullOrWhiteSpace(secondParameter))
                {
                    newSwedishCodeActivity.SecondInArgument = secondParameter;
                }

                if (!string.IsNullOrWhiteSpace(thirdParameter))
                {
                    newSwedishCodeActivity.ThirdInArgument = thirdParameter;
                }

                SqlWorkflowInstanceStore newSqlWorkflowInstanceStore = new SqlWorkflowInstanceStore("Server=192.168.0.252,1433\\SQL2008EXPRESS;Initial Catalog=WorkflowInstanceStore;Integrated Security=SSPI")
                {
                    HostLockRenewalPeriod            = TimeSpan.FromSeconds(1),
                    InstanceCompletionAction         = InstanceCompletionAction.DeleteNothing,
                    InstanceLockedExceptionAction    = InstanceLockedExceptionAction.AggressiveRetry,
                    RunnableInstancesDetectionPeriod = TimeSpan.FromSeconds(1) // Minimum allowed value.
                };

                InstanceHandle             workflowInstanceStoreHandle = newSqlWorkflowInstanceStore.CreateInstanceHandle();
                CreateWorkflowOwnerCommand createWorkflowOwnerCommand  = new CreateWorkflowOwnerCommand();
                InstanceView newInstanceView = newSqlWorkflowInstanceStore.Execute(workflowInstanceStoreHandle, createWorkflowOwnerCommand, TimeSpan.FromSeconds(30));
                newSqlWorkflowInstanceStore.DefaultInstanceOwner = newInstanceView.InstanceOwner;

                WorkflowApplication newWorkflowApplication = new WorkflowApplication(newSwedishCodeActivity, new WorkflowIdentity
                {
                    // The Dictionary will throw for non-found key before we ever get here, so no need to validate input.
                    Name    = command,
                    Version = new Version(0, 1, 0, 0)
                })
                {
                    InstanceStore          = newSqlWorkflowInstanceStore,
                    SynchronizationContext = SynchronizationContext.Current
                };

                newWorkflowApplication.Persist();
                ResultObject = new object();
                newWorkflowApplication.Completed += delegate(WorkflowApplicationCompletedEventArgs e)
                {
                    if (e.CompletionState == ActivityInstanceState.Faulted)
                    {
                        EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has faulted.\nException: {e.TerminationException.GetType().FullName}\nMessage:{e.TerminationException.Message}");
                        syncEvent.Set();
                    }
                    else if (e.CompletionState == ActivityInstanceState.Canceled)
                    {
                        EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has been canceled.");
                        syncEvent.Set();
                    }
                    else
                    {
                        // Since the result can be *anything*, let's not treat it like a string.
                        EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} completed. Result: {e.Outputs["Result"]}");
                        ResultObject = e.Outputs["Result"];
                        syncEvent.Set();
                    }
                };

                newWorkflowApplication.Aborted = delegate(WorkflowApplicationAbortedEventArgs e)
                {
                    // The workflow aborted, so let's find out why.
                    EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has been aborted.\nException: {e.Reason.GetType().FullName}\nMessage:{e.Reason.Message}");
                    syncEvent.Set();
                };

                newWorkflowApplication.Idle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                    // TODO: [FUTURE] Need to handle future persistence maintenance.
                    EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has entered the Idle state.");
                    syncEvent.Set();
                };

                newWorkflowApplication.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
                {
                    EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has entered PersistableIdle.");
                    syncEvent.Set();

                    // Runtime will persist.
                    return(PersistableIdleAction.Persist);
                };

                newWorkflowApplication.Unloaded = delegate(WorkflowApplicationEventArgs e)
                {
                    EventLog.WriteEntry("Felsökning.Tomte.AdminService", $"Workflow {e.InstanceId} has been unloaded.");
                    syncEvent.Set();
                };

                newWorkflowApplication.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
                {
                    // Log the unhandled exception.
                    EventLog.WriteEntry("Felsökning.Tomte.AdminService",
                                        !string.IsNullOrWhiteSpace(e.UnhandledException.InnerException?.Message)
                            ? $"Workflow {e.InstanceId} has reached an AggregateException in OnUnhandledException.\nException Source: {e.ExceptionSource.DisplayName}\nException Instance ID: {e.ExceptionSourceInstanceId}\nException: {e.UnhandledException.InnerException.GetType().FullName}\nMessage: {e.UnhandledException.InnerException.Message}\nFirstArgument: {firstParameter}\nSecondArgument: {secondParameter}"
                            : $"Workflow {e.InstanceId} has reached OnUnhandledException.\nException Source: {e.ExceptionSource.DisplayName}\nException Instance ID: {e.ExceptionSourceInstanceId}\nException: {e.UnhandledException.GetType().FullName}\nMessage: {e.UnhandledException.Message}\nFirstArgument: {firstParameter}\nSecondArgument: {secondParameter}");

                    syncEvent.Set();

                    // Instruct the runtime to terminate the workflow.
                    // The other viable choices here are 'Abort' or 'Cancel'
                    return(UnhandledExceptionAction.Terminate);
                };

                newWorkflowApplication.Run();

                // Because a new thread is spawned, we need to wait for it to complete before we can move on.
                syncEvent.WaitOne();

                // Instance MUST be unloaded to update the SQL record. One would think this would happen on the overridden delegate methods (e.g.: Completed,OnUnhandledException, etc.)
                // but testing has proven this to not be the case.
                newWorkflowApplication.Unload(TimeSpan.FromSeconds(30));

                // Now, we dump the instance owner.
                DeleteWorkflowOwnerCommand newDeleteWorkflowOwnerCommand = new DeleteWorkflowOwnerCommand();
                newSqlWorkflowInstanceStore.Execute(
                    workflowInstanceStoreHandle,
                    newDeleteWorkflowOwnerCommand,
                    TimeSpan.FromSeconds(30));
            }

            GC.Collect();
        }
Esempio n. 8
0
        public void LoadAOrCompleteInstance(Guid _documentId, DocumentState _state, TrackerType _trackerType, IDictionary <string, object> documentData)
        {
            var documentTable = _DocumentService.Find(_documentId);
            IEnumerable <WFTrackerTable> bookmarks;

            IDictionary <string, object> inputArguments = new Dictionary <string, object>();

            inputArguments.Add("inputStep", _state);
            inputArguments.Add("inputCurrentUser", HttpContext.Current.User.Identity.Name);
            inputArguments.Add("documentData", documentData);

            WorkflowApplication application = new WorkflowApplication(activity);

            application.InstanceStore = instanceStore;
            application.Extensions.Add(new WFTrackingParticipant());

            #region Workflow Delegates

            application.PersistableIdle = (e) =>
            {
                var ex = e.GetInstanceExtensions <WFTrackingParticipant>();
                outputParameters = ex.Last().Outputs;
                //instanceUnloaded.Set();
                return(PersistableIdleAction.Unload);
            };

            application.Completed = (e) =>
            {
                outputParameters = e.Outputs;
            };

            application.Unloaded = (workflowApplicationEventArgs) =>
            {
                instanceUnloaded.Set();
            };

            #endregion Workflow Delegates

            application.Load(documentTable.WWFInstanceId);

            bookmarks = _DocumentService.GetCurrentSignStep(_documentId, HttpContext.Current.User.Identity.Name);

            if (bookmarks != null)
            {
                foreach (var bookmark in bookmarks)
                {
                    application.ResumeBookmark(bookmark.ActivityName, inputArguments);

                    application.Persist();
                    instanceUnloaded.WaitOne();
                }
            }
            _DocumentService.SaveSignData(bookmarks, _trackerType);

            documentTable.WWFInstanceId = application.Id;
            documentTable.DocumentState = (DocumentState)outputParameters["outputStep"];
            _DocumentService.UpdateDocument(documentTable);

            if (documentTable.DocumentState == DocumentState.Closed)
            {
                _EmailService.SendInitiatorClosedEmail(documentTable.Id);
            }
        }