Пример #1
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var director = directorReference.Resolve(context.ReferenceResolver);

            if (!director)
            {
                throw new NullReferenceException();
            }

            switch (control)
            {
            case ControlType.Resume:
                director.Resume();
                break;

            case ControlType.Pause:
                director.Pause();
                break;

            case ControlType.Stop:
                director.Stop();
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            handle.Complete();
        }
        public async Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default)
        {
            var remoteCode           = Code.GetRemoteCode();
            var remoteExecutionState = eventExecutionContext.WorkflowContext.CreateRemoteExecutionState(
                eventExecutionContext.EventConfiguration.Parameters, remoteCode);
            var eventRequestWorkflowMessage = new EventRequestWorkflowMessage(eventExecutionContext.WorkflowContext.WorkflowConfiguration.Id,
                                                                              eventExecutionContext.WorkflowContext.WorkflowInstance.Id, remoteCode, remoteExecutionState);

            var workflowConfiguration = eventExecutionContext.WorkflowContext.WorkflowConfiguration;
            var endpointConfiguration = workflowConfiguration.FindEndpointConfiguration(Code);

            Log.Verbose("Sending event request message [{code}::{messageId}] to {endpoint} [{workflowInstanceId}]",
                        Code, eventRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address,
                        eventExecutionContext.WorkflowContext.WorkflowInstance.Id);

            var messageTransport = eventExecutionContext.WorkflowContext
                                   .WorkflowMessageTransportFactoryProvider.CreateMessageTransportFactory(endpointConfiguration.Type)
                                   .CreateMessageTransport(endpointConfiguration.Address);
            var responseWorkflowMessage = await messageTransport.Request <IEventRequestWorkflowMessage, IEventResponseWorkflowMessage>(
                endpointConfiguration, eventRequestWorkflowMessage, cancellationToken).ConfigureAwait(false);

            Log.Verbose("Received event response message [{messageId}] from {endpoint} [{workflowInstanceId}]",
                        eventRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address,
                        eventExecutionContext.WorkflowContext.WorkflowInstance.Id);

            // merge state changes made by remote event handler during execution
            eventExecutionContext.WorkflowContext.MergeRemoteExecutionState(responseWorkflowMessage.State);
            return(responseWorkflowMessage.EventExecutionResult);
        }
Пример #3
0
        private async UniTaskVoid ExecuteAsync(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var timelineModule = context.GetModule <TimelineModule>();

            if (!timelineModule)
            {
                throw new NullReferenceException();
            }

            var cs = new UniTaskCompletionSource();

            Action <SignalAsset> onSignalNotify = signalAsset =>
            {
                if (signalAsset == target)
                {
                    cs.TrySetResult();
                }
            };

            timelineModule.OnSignalNotify += onSignalNotify;

            await PlayNestedCommands(context);

            await cs.Task;

            timelineModule.OnSignalNotify -= onSignalNotify;

            handle.Complete();
        }
Пример #4
0
        public void Play(T option)
        {
            if (!option.Ready(ScriptVariablesDatabase))
            {
                throw new ArgumentException();
            }
            EnsureInitialized();

            if (IsPlaying)
            {
                throw new InvalidOperationException("EventScriptPlayerは別のイベントを再生中です。");
            }

            var context = new EventExecutionContext(this);

            CurrentContext = context;
            Debug.Log("EventScriptPlayer: Start.");
            context.Play(option.Script, () =>
            {
                Debug.Log("EventScriptPlayer: End.");
                OnCompleteEvent(context, option);
                CurrentContext = null;
            },
                         (exception) =>
            {
                Debug.Log("EventScriptPlayer: Error.");
                CurrentContext = null;
                OnErrorEvent(context, option);
                //TODO: Modulesに対するエラー通知
            }, option.RuntimeReferenceHost, option.EventVariables, option.TemporaryVariables,
                         () => OnPlayEvent(context, option));
        }
Пример #5
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var dialog = context.GetModule <DialogModule>();

            if (dialog == default)
            {
                context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。"));
                return;
            }

            if (dialog.CurrentProvider != null)
            {
                var providerName = dialog.CurrentProvider.ProviderName;

                dialog.Close(() =>
                {
                    var script                = new EventScript();
                    script.CommandList        = commandList;
                    script.WaitForAllCommands = true;
                    context.InsertInherit(script, () => { dialog.Open(providerName, handle.Complete); });
                });
            }
            else
            {
                var script = new EventScript();
                script.CommandList        = commandList;
                script.WaitForAllCommands = true;
                context.InsertInherit(script, handle.Complete);
            }
        }
        public async Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default)
        {
            var workflowContext = eventExecutionContext.WorkflowContext;

            if (ScriptType != ScriptTypeConfiguration.CSharp)
            {
                throw new WorkflowException(string.Format(CultureInfo.InvariantCulture,
                                                          "CSharpScriptEventHandler can execute only CSharp scripts but [{0}] has been provided for workflow [ID={1:D}]",
                                                          ScriptType, eventExecutionContext.WorkflowContext.WorkflowInstance.Id));
            }

            var scriptKey = $"EVENTHANDLER::{workflowContext.WorkflowConfiguration.Id:D}::{Code}::{Script.GetHashCode():D}";

            Assembly[] assemblies = null;
            var        entity     = workflowContext.WorkflowInstance.Entity;

            if (null != entity)
            {
                assemblies = new[] { entity.GetType().Assembly };
            }

            Exception exception;

            try
            {
                var cSharpScript = WorkflowEngine.ScriptingEngine.Value.GetScript <EventHandlerExecutionContextGlobals>(scriptKey, Script, assemblies);
                var scriptState  = await cSharpScript.RunAsync(new EventHandlerExecutionContextGlobals
                {
                    context           = eventExecutionContext,
                    entity            = entity,
                    state             = eventExecutionContext.WorkflowContext.WorkflowExecutionState,
                    workflowRuntime   = workflowContext.WorkflowEngine,
                    cancellationToken = cancellationToken
                }, cancellationToken).ConfigureAwait(false);

                // if event handler returned "FALSE" --> do not move workflow instance from "AwaitingEvent"
                if (null != scriptState.ReturnValue && scriptState.ReturnValue is bool boolean && !boolean)
                {
                    return(new EventExecutionResult(EventExecutionStatus.KeepWaiting));
                }

                if (null == scriptState.Exception)
                {
                    return(new EventExecutionResult(EventExecutionStatus.Completed));
                }

                exception = scriptState.Exception;
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            Log.Error(exception, "An error has occurred during execution of scripted event [{state}, {code}] for {workflowInstanceId}]",
                      eventExecutionContext.StateEventConfiguration.Code,
                      eventExecutionContext.EventConfiguration.Code, eventExecutionContext.WorkflowContext.WorkflowInstance.Id);

            return(new EventExecutionResult(EventExecutionStatus.Failed));
        }
        public Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default)
        {
            if (string.Equals(eventExecutionContext.WorkflowContext.WorkflowInstance.CurrentStateCode, "process", StringComparison.OrdinalIgnoreCase))
            {
                throw new Exception();
            }

            return(Task.FromResult(new EventExecutionResult(EventExecutionStatus.Completed)));
        }
Пример #8
0
        private UniTask PlayNestedCommands(EventExecutionContext context)
        {
            var cs = new UniTaskCompletionSource();

            var script = new EventScript();

            script.CommandList        = nestedCommands;
            script.WaitForAllCommands = false;
            context.InsertInherit(script, () => { cs.TrySetResult(); });

            return(cs.Task);
        }
Пример #9
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var dialog = context.GetModule <DialogModule>();

            if (dialog == default)
            {
                context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。"));
                return;
            }

            dialog.Cut.Show(sprite, duration, updateMode, handle.Complete);
        }
Пример #10
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var dialog = context.GetModule <DialogModule>();

            if (dialog == default)
            {
                context.RaiseError(new ScriptExecutionException("DialogSessionが登録されていません。"));
                return;
            }


            dialog.ShowMessage(settings, () => { handle.Complete(); });
        }
Пример #11
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            Debug.Log("SampleEventCommand3: ネストされたイベントを実行します。");
            var script = new EventScript();

            script.WaitForAllCommands = false;
            script.CommandList        = commandList;

            context.InsertInherit(script, () =>
            {
                Debug.Log("SampleEventCommand3: ネストの終了。");
                handle.Complete();
            });
        }
Пример #12
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var obj = targetGameObject.Resolve(context.ReferenceResolver);

            if (obj)
            {
                Debug.Log($"シーン参照に成功しました。: {obj.name}", obj);
            }
            else
            {
                Debug.Log($"シーン参照に失敗しました。");
            }

            handle.Complete();
        }
        public void SetUp()
        {
            _workflowInstance                        = new Mock <IWorkflowInstance>();
            _runtimeWorkflowEngine                   = new Mock <IRuntimeWorkflowEngine>();
            _endpointConfiguration                   = new Mock <IEndpointConfiguration>();
            _workflowMessageTransport                = new Mock <IWorkflowMessageTransport>();
            _workflowMessageTransportFactory         = new Mock <IWorkflowMessageTransportFactory>();
            _workflowMessageTransportFactoryProvider = new Mock <IWorkflowMessageTransportFactoryProvider>();
            _workflowEngineBuilder                   = new WorkflowEngineBuilder().WithMessageTransportFactoryProvider(_workflowMessageTransportFactoryProvider.Object);

            _endpointConfiguration.Setup(f => f.Code).Returns("rabbit.mq");
            _endpointConfiguration.Setup(f => f.Address).Returns(new Uri("rabbitmq://localhost/address"));

            var workflowId = Guid.NewGuid();

            _workflowInstance.Setup(f => f.Id).Returns(workflowId);
            _workflowConfiguration = new WorkflowConfiguration(workflowId, "unit.test", "unit.test", "Unit Test", new Version(0, 0, 1))
            {
                RuntimeConfiguration = new WorkflowRuntimeConfiguration(workflowId, "unit.test", "unit.test")
                {
                    EndpointConfiguration  = _endpointConfiguration.Object,
                    EndpointConfigurations = new[] { new KeyValuePair <string, IEndpointConfiguration>("remote.*", _endpointConfiguration.Object) }
                }
            };

            _eventResponseWorkflowMessage = new EventResponseWorkflowMessage {
                EventExecutionResult = new EventExecutionResult(EventExecutionStatus.Completed)
            };
            _workflowMessageTransport
            .Setup(f => f.Request <IEventRequestWorkflowMessage, IEventResponseWorkflowMessage>(
                       It.IsAny <IEndpointConfiguration>(), It.IsAny <IEventRequestWorkflowMessage>(), It.IsAny <CancellationToken>()))
            .Returns <IEndpointConfiguration, IWorkflowMessage, CancellationToken>((epc, wm, ct) => Task.FromResult(_eventResponseWorkflowMessage));

            _workflowMessageTransportFactoryProvider
            .Setup(f => f.CreateMessageTransportFactory(It.IsAny <EndpointConfigurationType>()))
            .Returns <EndpointConfigurationType>(uri => _workflowMessageTransportFactory.Object);

            _workflowMessageTransportFactory
            .Setup(f => f.CreateMessageTransport(It.IsAny <Uri>()))
            .Returns <Uri>(uri => _workflowMessageTransport.Object);

            _event                 = new StatefulEvent("remote.{sign-event01}", workflowId, new JsonState());
            _workflowContext       = new WorkflowContext(_runtimeWorkflowEngine.Object, _workflowEngineBuilder, _workflowInstance.Object, _workflowConfiguration);
            _eventExecutionContext = new EventExecutionContext(_workflowContext, _event,
                                                               new EventConfiguration(EventTypeConfiguration.Application, _event.Code, string.Empty),
                                                               new StateEventConfiguration());
        }
Пример #14
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var dialog = context.GetModule <DialogModule>();

            if (dialog == default)
            {
                context.RaiseError(new ScriptExecutionException("DialogSessionが登録されていません。"));
                return;
            }

            string[] items    = bifurcations.Select(b => b.Label).ToArray();
            var      settings = new DialogShowMenuSettings(items);

            dialog.ShowMenu(settings, (index) =>
            {
                var script = new EventScript();
                script.WaitForAllCommands = false;
                script.CommandList        = bifurcations[index].CommandList;
                context.InsertInherit(script, handle.Complete);
            });
        }
Пример #15
0
        public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var dialog = context.GetModule <DialogModule>();

            if (dialog == default)
            {
                context.RaiseError(new ScriptExecutionException("DialogModuleが登録されていません。"));
                return;
            }

            dialog.Fade.In(inDuration, () =>
            {
                var script = new EventScript()
                {
                    CommandList        = nestedCommands,
                    WaitForAllCommands = true
                };
                context.InsertInherit(script, () =>
                {
                    dialog.Fade.Out(outDuration, handle.Complete);
                });
            });
        }
Пример #16
0
        private async UniTaskVoid ExecuteAsync(EventExecutionContext context, CommandExecutionHandle handle)
        {
            var timelineModule = context.GetModule <TimelineModule>();

            if (!timelineModule)
            {
                throw new NullReferenceException();
            }

            var director = directorReference.Resolve(context.ReferenceResolver);

            if (!director)
            {
                throw new NullReferenceException();
            }

            var timelinePlaying = PlayTimeline(director, timelineModule);

            await PlayNestedCommands(context);

            await timelinePlaying;

            handle.Complete();
        }
Пример #17
0
 public Task <EventExecutionResult> Execute(EventExecutionContext eventExecutionContext, CancellationToken cancellationToken = default)
 {
     return(Task.FromResult(new EventExecutionResult(EventExecutionStatus.Completed)));
 }
Пример #18
0
 /// <summary>
 /// イベントの再生が正常に終わったときに呼ばれる。
 /// </summary>
 /// <param name="context"></param>
 protected virtual void OnCompleteEvent(EventExecutionContext context, T option)
 {
 }
Пример #19
0
 /// <summary>
 /// イベントの再生がエラーで終了したときに呼ばれる。
 /// </summary>
 /// <param name="context"></param>
 protected virtual void OnErrorEvent(EventExecutionContext context, T option)
 {
 }
Пример #20
0
 public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
 {
     ExecuteAsync(context, handle).Forget();
 }
Пример #21
0
        private async Task <WorkflowProcessingResult> ProcessEventInternal(Guid workflowId, IEvent @event, CancellationToken cancellationToken)
        {
            var isHierarchicalEvent   = @event.IsHierarchicalEvent();
            var workflowConfiguration = await GetWorkflowConfiguration(workflowId, cancellationToken).ConfigureAwait(false);

            var eventConfiguration = workflowConfiguration.GetEventConfigurationByCode(@event.Code);

            if (null == eventConfiguration && isHierarchicalEvent)
            {
                if (!Enum.TryParse(@event.Code, out EventTypeConfiguration eventTypeConfiguration))
                {
                    throw new WorkflowException(string.Format(CultureInfo.InvariantCulture,
                                                              "System event must have code of EventType but following value have been encountered [{0}] for workflow [{1}]",
                                                              @event.Code, workflowConfiguration.Code));
                }

                eventConfiguration = workflowConfiguration.GetEventConfigurationByType(eventTypeConfiguration);
            }

            if (null == eventConfiguration)
            {
                throw new WorkflowException($"Event with code [{@event.Code}] was not found in workflow [{workflowConfiguration.Code}]");
            }

            WorkflowContext         workflowContext;
            IWorkflowInstance       workflowInstance;
            StateConfiguration      stateConfiguration;
            StateEventConfiguration stateEventConfiguration;

            if (eventConfiguration.Type == EventTypeConfiguration.Initial || eventConfiguration.Type == EventTypeConfiguration.ParentToNestedInitial)
            {
                stateConfiguration      = workflowConfiguration.GetStateConfigurationByType(StateTypeConfiguration.Initial);
                stateEventConfiguration = stateConfiguration.Events
                                          .Single(se => string.Equals(se.Code, eventConfiguration.Code, StringComparison.OrdinalIgnoreCase));

                var id = Guid.NewGuid();
                var workflowInstanceLock = CreateWorkflowInstanceLock(workflowConfiguration);
                workflowInstance = new WorkflowInstance(workflowId, id, @event.GetRootWorkflowInstanceIdOrUseCurrent(id),
                                                        @event.GetParentWorkflowInstanceIdOrUseCurrent(id), @event.GetDomainEntityTypeOrNull(),
                                                        @event.GetDomainEntityIdOrNull(), workflowInstanceLock, @event.GetDomainEntityOrNull())
                {
                    Created              = DateTime.UtcNow,
                    CurrentStateCode     = stateConfiguration.Code,
                    CurrentStateProgress = StateExecutionProgress.AwaitingEvent
                };

                await TryGetDomainEntity(workflowConfiguration, workflowInstance, cancellationToken).ConfigureAwait(false);
                await SaveWorkflowInstance(workflowInstance, cancellationToken).ConfigureAwait(false);
            }
            else
            {
                var hierarchicalEvent = @event as IHierarchicalEvent;
                if (null != hierarchicalEvent)
                {
                    // for system events:
                    //     1. intended to be used inside activities only
                    //     2. lock on a root workflow instance should have been obtained earlier
                    workflowInstance = hierarchicalEvent.TargetWorkflowInstance ?? await GetWorkflowInstanceWithNoLock(@event.WorkflowInstanceId, cancellationToken)
                                       .ConfigureAwait(false);

                    Guard.ArgumentNotNull(workflowInstance, nameof(workflowInstance));
                }
                else
                {
                    // for other events: we need to obtain a lock on a root workflow instance
                    workflowInstance = await GetWorkflowInstanceWithLock(@event.WorkflowInstanceId, cancellationToken).ConfigureAwait(false);

                    Guard.ArgumentNotNull(workflowInstance, nameof(workflowInstance));
                }

                stateConfiguration = workflowConfiguration.GetStateConfigurationByCode(workflowInstance.CurrentStateCode);
                Guard.ArgumentNotNull(stateConfiguration, nameof(stateConfiguration));

                if (null != hierarchicalEvent)
                {
                    // break cycling
                    if (stateConfiguration.Type == StateTypeConfiguration.Failed && eventConfiguration.Type.IsFailed())
                    {
                        return(new WorkflowProcessingResult(workflowInstance));
                    }

                    if (hierarchicalEvent.HierarchyEventType == WorkflowHierarchyEventType.Failed)
                    {
                        Log.Warning("Received event {code} into {workflowInstanceId}]", @event.Code, workflowInstance.Id);
                        return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false));
                    }
                }

                // workflow instance must be awaiting for the event otherwise move it to failed
                if (workflowInstance.CurrentStateProgress != StateExecutionProgress.AwaitingEvent)
                {
                    Log.Error("Can not process event {code} for {workflowInstanceId} because workflow instance is not in [{subState}], it is in [{state}] and [{stateProgress}]",
                              @event.Code, workflowInstance.Id, StateExecutionProgress.AwaitingEvent, workflowInstance.CurrentStateCode, workflowInstance.CurrentStateProgress);
                    return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false));
                }

                if (null == stateConfiguration)
                {
                    Log.Error("{workflowInstanceId} is in the {state} which does not belong to {workflow}",
                              workflowInstance.Id, workflowInstance.CurrentStateCode, workflowConfiguration.Code);
                    return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false));
                }

                if (isHierarchicalEvent)
                {
                    stateEventConfiguration = stateConfiguration.Events
                                              .SingleOrDefault(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase));
                }
                else
                {
                    if (!stateConfiguration.Events.Any(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase)))
                    {
                        Log.Error("{workflowInstanceId} is in the {state} which does not accept {event}",
                                  workflowInstance.Id, stateConfiguration.Code, @event.Code);
                        return(await TransitionToFailedStatus(@event, workflowInstance, workflowConfiguration, cancellationToken).ConfigureAwait(false));
                    }

                    stateEventConfiguration = stateConfiguration.Events.Single(e => string.Equals(e.Code, @event.Code, StringComparison.OrdinalIgnoreCase));
                }

                workflowInstance.Entity = @event.GetDomainEntityOrNull();
                await TryGetDomainEntity(workflowConfiguration, workflowInstance, cancellationToken).ConfigureAwait(false);
            }

            workflowContext = new WorkflowContext(this, WorkflowEngineBuilder, workflowInstance, workflowConfiguration, @event.GetEventStateOrDefault());
            var eventExecutionContext = new EventExecutionContext(workflowContext, @event, eventConfiguration, stateEventConfiguration);
            var eventExecutionResult  = await _eventProcessorLazy.Value.Process(eventExecutionContext, cancellationToken).ConfigureAwait(false);

            switch (eventExecutionResult.Status)
            {
            case EventExecutionStatus.KeepWaiting:
            {
                Log.Information("After processing event [{code}] the {workflowInstanceId} keeps waiting in for another event of {nextCode}",
                                @event.Code, workflowInstance.Id, @event.Code);

                break;
            }

            case EventExecutionStatus.Failed:
            case EventExecutionStatus.FailedNoRetry:
            {
                Log.Error("An error has occurred during processing event [{code}] for {workflowInstanceId}]", @event.Code, workflowInstance.Id);

                await TransitionToState(workflowContext, workflowConfiguration.GetFailedStateConfiguration(), null, cancellationToken).ConfigureAwait(false);

                break;
            }

            default:
            {
                workflowContext.WorkflowInstance.CurrentStateProgress = StateExecutionProgress.AfterEventProcessed;
                await ProcessState(workflowContext, stateConfiguration, cancellationToken).ConfigureAwait(false);

                break;
            }
            }

            return(new WorkflowProcessingResult(workflowInstance, workflowContext.WorkflowExecutionState));
        }
Пример #22
0
 public override void Execute(EventExecutionContext context, CommandExecutionHandle handle)
 {
     Debug.Log("SampleEventCommand1 executed!");
     handle.Complete();
 }