public async Task <TransitionEvaluationResult> Evaluate(TransitionEvaluationContext transitionEvaluationContext, CancellationToken cancellationToken)
        {
            var remoteCode           = Code.GetRemoteCode();
            var remoteExecutionState = transitionEvaluationContext.StateExecutionContext.WorkflowContext
                                       .CreateRemoteExecutionState(transitionEvaluationContext.TransitionConfiguration.Parameters, remoteCode);
            var activityRequestWorkflowMessage = new TransitionEvaluationRequestWorkflowMessage(remoteCode)
            {
                WorkflowMessageId  = Guid.NewGuid(),
                WorkflowInstanceId = transitionEvaluationContext.StateExecutionContext.WorkflowContext.WorkflowInstance.Id,
                WorkflowId         = transitionEvaluationContext.StateExecutionContext.WorkflowContext.WorkflowConfiguration.Id,
                State = new WorkflowMessageState(remoteExecutionState)
            };

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

            Log.Verbose("Sending transition evaluation request message [{code}::{messageId}] to {endpoint} [{workflowInstanceId}]",
                        Code, activityRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address,
                        transitionEvaluationContext.StateExecutionContext.WorkflowContext.WorkflowInstance.Id);

            var messageTransport = transitionEvaluationContext.StateExecutionContext.WorkflowContext
                                   .WorkflowMessageTransportFactoryProvider.CreateMessageTransportFactory(endpointConfiguration.Type)
                                   .CreateMessageTransport(endpointConfiguration.Address);
            var responseWorkflowMessage = await messageTransport.Request <ITransitionEvaluationRequestWorkflowMessage, ITransitionEvaluationResponseWorkflowMessage>(
                endpointConfiguration, activityRequestWorkflowMessage, cancellationToken).ConfigureAwait(false);

            Log.Verbose("Received transition evaluation response message [{messageId}] from {endpoint} [{workflowInstanceId}]",
                        activityRequestWorkflowMessage.WorkflowMessageId, endpointConfiguration.Address,
                        transitionEvaluationContext.StateExecutionContext.WorkflowContext.WorkflowInstance.Id);

            // merge state changes made by remote transition handler during execution
            transitionEvaluationContext.StateExecutionContext.WorkflowContext.MergeRemoteExecutionState(responseWorkflowMessage.State);
            return(new TransitionEvaluationResult(responseWorkflowMessage.TransitionEvaluationStatus));
        }
Beispiel #2
0
        public async Task <TransitionEvaluationResult> Evaluate(StateExecutionContext stateExecutionContext, TransitionConfiguration transitionConfiguration, CancellationToken cancellationToken)
        {
            ITransition transition = null;

            if (!string.IsNullOrEmpty(transitionConfiguration.Code))
            {
                transition = _workflowEngine.WorkflowEngineBuilder
                             .TransitionFactory.CreateTransition(transitionConfiguration.Code);
            }

            if (null == transition && !string.IsNullOrEmpty(transitionConfiguration.ConditionScript) &&
                transitionConfiguration.ConditionScriptType == ScriptTypeConfiguration.CSharp)
            {
                transition = new CSharpScriptTransition(stateExecutionContext.StateConfiguration.Code,
                                                        transitionConfiguration.ConditionScriptType, transitionConfiguration.ConditionScript);
            }

            if (null == transition)
            {
                // there is neither code nor condition for transition
                //     ==> assume transition always evaluates to true
                return(new TransitionEvaluationResult(TransitionEvaluationStatus.EvaluatedTrue));
            }

            Log.Verbose("Starting evaluation of transition [{code}] [{condition}] for [{workflowInstanceId}]",
                        transitionConfiguration.Code, transitionConfiguration.ConditionScriptType,
                        stateExecutionContext.WorkflowContext.WorkflowInstance.Id);

            try
            {
                var transitionEvaluationContext = new TransitionEvaluationContext(stateExecutionContext, transitionConfiguration);
                var transitionEvaluationResult  = await transition.Evaluate(transitionEvaluationContext, cancellationToken).ConfigureAwait(false);

                if (transitionEvaluationResult.Status == TransitionEvaluationStatus.EvaluationFailed)
                {
                    throw new WorkflowException(string.Format(CultureInfo.InvariantCulture,
                                                              "Evaluation of an transition [code={0}], [condition={1}] returns [EvaluationFailed] for workflow instance [{2:D}]",
                                                              transitionConfiguration.Code, transitionConfiguration.ConditionScript,
                                                              stateExecutionContext.WorkflowContext.WorkflowInstance.Id));
                }

                return(transitionEvaluationResult);
            }
            catch (Exception ex)
            {
                throw new WorkflowException(string.Format(CultureInfo.InvariantCulture,
                                                          "An error has occurred during evaluation of an transition [code={0}], [condition={1}] for workflow instance [{2:D}]",
                                                          transitionConfiguration.Code, transitionConfiguration.ConditionScript,
                                                          stateExecutionContext.WorkflowContext.WorkflowInstance.Id), ex);
            }
        }
        public async Task <TransitionEvaluationResult> Evaluate(TransitionEvaluationContext transitionEvaluationContext, CancellationToken cancellationToken)
        {
            var workflowContext = transitionEvaluationContext.StateExecutionContext.WorkflowContext;

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

            var scriptKey = string.Format(CultureInfo.InvariantCulture, "TRANSITION::{0:D}::{1}::{2}::{3:D}",
                                          workflowContext.WorkflowConfiguration.Id, transitionEvaluationContext.StateExecutionContext.StateConfiguration.Code, Code,
                                          Script.GetHashCode());

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

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

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

            if (null == scriptState.Exception)
            {
                return((bool)scriptState.ReturnValue
                    ? new TransitionEvaluationResult(TransitionEvaluationStatus.EvaluatedTrue)
                    : new TransitionEvaluationResult(TransitionEvaluationStatus.EvaluatedFalse));
            }

            Log.Error(scriptState.Exception, "An error has occurred during evaluation of transition [{state}, {code}] for {workflowInstanceId}]",
                      transitionEvaluationContext.StateExecutionContext.StateConfiguration.Code,
                      transitionEvaluationContext.TransitionConfiguration.Code,
                      transitionEvaluationContext.StateExecutionContext.WorkflowContext.WorkflowInstance.Id);

            return(new TransitionEvaluationResult(TransitionEvaluationStatus.EvaluationFailed));
        }