Пример #1
0
        private static async Task ActivityChanged(ProcessActivityChangedEventArgs args, WorkflowRuntime runtime)
        {
            if (!args.TransitionalProcessWasCompleted)
            {
                return;
            }

            var historyModel = await MetadataToModelConverter.GetEntityModelByModelAsync("DocumentTransitionHistory");

            var emptyHistory = (await historyModel.GetAsync(Filter.And.Equal(Null.Value, "EmployeeId").Equal(args.ProcessId, "DocumentId")
                                                            .Equal(Null.Value, "TransitionTime"))).Select(h => h.GetId()).ToList();
            await historyModel.DeleteAsync(emptyHistory);

            await runtime.PreExecuteFromCurrentActivityAsync(args.ProcessId);

            var nextState     = WorkflowInit.Runtime.GetLocalizedStateName(args.ProcessId, args.ProcessInstance.CurrentState);
            var documentModel = await MetadataToModelConverter.GetEntityModelByModelAsync("Document");

            var document = (await documentModel.GetAsync(Filter.And.Equal(args.ProcessId, "Id"))).FirstOrDefault() as dynamic;

            if (document == null)
            {
                return;
            }

            document.StateName = nextState;
            document.State     = args.ProcessInstance.CurrentState;
            await documentModel.UpdateSingleAsync(document as DynamicEntity);

            var newActors = await Runtime.GetAllActorsForDirectCommandTransitionsAsync(args.ProcessId);

            var newInboxes = new List <dynamic>();

            foreach (var newActor in newActors)
            {
                var newInboxItem = new DynamicEntity() as dynamic;
                newInboxItem.Id         = Guid.NewGuid();
                newInboxItem.IdentityId = newActor;
                newInboxItem.ProcessId  = args.ProcessId;
                newInboxes.Add(newInboxItem);
            }

            var userIdsForNotification = new List <string>();

            userIdsForNotification.AddRange(newInboxes.Select(a => (string)(a as dynamic).IdentityId));

            var inboxModel = await MetadataToModelConverter.GetEntityModelByModelAsync("WorkflowInbox");

            using (var shared = new SharedTransaction())
            {
                await shared.BeginTransactionAsync();

                var existingInbox = (await inboxModel.GetAsync(Filter.And.Equal(args.ProcessId, "ProcessId")));
                userIdsForNotification.AddRange(existingInbox.Select(a => (string)(a as dynamic).IdentityId));
                var existingInboxIds = existingInbox.Select(i => i.GetId()).ToList();
                await inboxModel.DeleteAsync(existingInboxIds);

                await inboxModel.InsertAsync(newInboxes);

                await shared.CommitAsync();
            }

            userIdsForNotification = userIdsForNotification.Distinct().ToList();
            Func <Task> task = async() => { await ClientNotifiers.NotifyClientsAboutInboxStatus(userIdsForNotification); };

            task.FireAndForgetWithDefaultExceptionLogger();
        }
Пример #2
0
        public static void Configure(IHttpContextAccessor httpContextAccessor, IConfigurationRoot configuration, string connectionstringName = "default")
        {
            #region License

            var licensefile = "license.key";
            if (File.Exists(licensefile))
            {
                try
                {
                    var licenseText = File.ReadAllText(licensefile);
                    DWKitRuntime.RegisterLicense(licenseText);
                }
                catch
                {
                    //TODO add write to log
                }
            }

            #endregion

#if (DEBUG)
            DWKitRuntime.UseMetadataCache = false;
            //CodeActionsCompiller.DebugMode = true;
#elif (RELEASE)
            DWKitRuntime.UseMetadataCache = true;
#endif

            DWKitRuntime.ConnectionStringData = configuration[$"ConnectionStrings:{connectionstringName}"];
            DWKitRuntime.DbProvider           = AutoDetectProvider();
            DWKitRuntime.Security             = new SecurityProvider(httpContextAccessor);
            DWKitRuntime.Metadata             = new DefaultMetadataProvider("Metadata/metadata.json", "Metadata/Forms", "Metadata/Localization");

            if (configuration["DWKit:BlockMetadataChanges"] == "True")
            {
                DWKitRuntime.Metadata.BlockMetadataChanges = true;
            }

            CodeActionsCompiller.RegisterAssembly(typeof(WorkflowRuntime).Assembly);
            DWKitRuntime.CompileAllCodeActionsAsync().Wait();
            //It is necessery to have this assembly for compile code with dynamic
            CodeActionsCompiller.RegisterAssembly(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly);
            DWKitRuntime.ServerActions.RegisterUsersProvider("filters", new Filters());
            DWKitRuntime.ServerActions.RegisterUsersProvider("triggers", new Triggers());

            //Initial inbox/outbox notifiers
            DWKitRuntime.AddClientNotifier(typeof(ClientNotificationHub), ClientNotifiers.NotifyClientsAboutInboxStatus);
            //Initial document count notifier
            DWKitRuntime.AddClientNotifier(typeof(ClientNotificationHub), SideMenuInitialNotifier);
            //User group classifier for notifications
            DWKitRuntime.SignalRGroupClassifier = SignalRGroupClassifier;

            //Documents count change on Insert new document or update document
            DynamicEntityOperationNotifier.SubscribeToInsertByTableName("Document", "SideMenuNotification",
                                                                        (m, c) =>
            {
                Func <Task> func = async() => { await NotifyDocumentCountChange(m, c, false); };
                func.FireAndForgetWithDefaultExceptionLogger();
            });
            DynamicEntityOperationNotifier.SubscribeToUpdateByTableName("Document", "SideMenuNotification",
                                                                        (m, c) =>
            {
                Func <Task> func = async() => { await NotifyDocumentCountChange(m, c, true); };
                func.FireAndForgetWithDefaultExceptionLogger();
            });
            //Documents count change and inbox outbox change on document deletions
            DynamicEntityOperationNotifier.SubscribeToDeleteByTableName("Document", "SideMenuNotification",
                                                                        (m, c) =>
            {
                Func <Task> func = async() =>
                {
                    await ClientNotifiers.DeleteWokflowAndNotifyClients(m, c);
                    await NotifyDocumentCountChange(m, c, false);
                };

                func.FireAndForgetWithDefaultExceptionLogger();
            });

            var runtime = WorkflowInit.Runtime;
        }
Пример #3
0
        public static void Configure(IHttpContextAccessor httpContextAccessor, IConfigurationRoot configuration, string connectionstringName = "default")
        {
            #region License

            var licensefile = "license.key";
            if (File.Exists(licensefile))
            {
                try
                {
                    var licenseText = File.ReadAllText(licensefile);
                    DWKitRuntime.RegisterLicense(licenseText);
                }
                catch
                {
                    //TODO add write to log
                }
            }

            #endregion

#if (DEBUG)
            DWKitRuntime.UseMetadataCache = false;
#elif (RELEASE)
            DWKitRuntime.UseMetadataCache = true;
#endif

            DWKitRuntime.ConnectionStringData = configuration[$"ConnectionStrings:{connectionstringName}"];
            DWKitRuntime.DbProvider           = AutoDetectProvider();
            DWKitRuntime.Security             = new SecurityProvider(httpContextAccessor);

            var path = configuration["Metadata:path"];

            if (string.IsNullOrEmpty(path))
            {
                path = "Metadata/metadata.json";
            }

            DWKitRuntime.Metadata = new DefaultMetadataProvider(path, "Metadata/Forms", "Metadata/Localization");

            if (configuration["DWKit:BlockMetadataChanges"] == "True")
            {
                DWKitRuntime.Metadata.BlockMetadataChanges = true;
            }

            if (!string.IsNullOrWhiteSpace(configuration["DWKit:CodeActionsDebugMode"]))
            {
                DWKitRuntime.CodeActionsDebugMode = bool.Parse(configuration["DWKit:CodeActionsDebugMode"]);
            }

            CodeActionsCompiler.RegisterAssembly(typeof(WorkflowRuntime).Assembly);
            //It is necessary to have this assembly for compile code with dynamic
            CodeActionsCompiler.RegisterAssembly(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly);
            DWKitRuntime.CompileAllCodeActionsAsync().Wait();
            DWKitRuntime.ServerActions.RegisterUsersProvider("filters", new Filters());
            DWKitRuntime.ServerActions.RegisterUsersProvider("triggers", new Triggers());

            //Initial inbox/outbox notifiers
            DWKitRuntime.AddClientNotifier(typeof(ClientNotificationHub), ClientNotifiers.NotifyClientsAboutInboxStatus);
            //Remove process after the document was removed
            DynamicEntityOperationNotifier.SubscribeToDeleteByTableName("Document", "WorkflowDelete", (e, c) =>
            {
                Func <Task> task = async() => { await ClientNotifiers.DeleteWokflowAndNotifyClients(e, c); };
                task.FireAndForgetWithDefaultExceptionLogger();
            });

            //Forcing the creation of a WF runtime to initialize timers and the Flow.
            try
            {
                WorkflowInit.ForceInit();
            }
            catch (Exception e)
            {
                if (Debugger.IsAttached)
                {
                    var info         = ExceptionUtils.GetExceptionInfo(e);
                    var errorBuilder = new StringBuilder();
                    errorBuilder.AppendLine("Workflow engine start failed.");
                    errorBuilder.AppendLine($"Message: {info.Message}");
                    errorBuilder.AppendLine($"Exceptions: {info.Exeptions}");
                    errorBuilder.Append($"StackTrace: {info.StackTrace}");
                    Debug.WriteLine(errorBuilder);
                }
            }
        }