Example #1
0
        /// <summary>
        /// Start a new workflow
        /// </summary>
        /// <param name="json">The entire message body from the request</param>
        /// <returns></returns>
        public string StartWorkflow(string json)
        {
            // This presently uses the Event as the body of the start message because it's convenient
            //
            var workflowName    = "";
            var workflowVersion = "";
            var executionId     = Guid.NewGuid();

            try
            {
                // Neither of these operation should ever fail as they cannot be conflicted
                var wfStartData = JsonConvert.DeserializeObject <WorkflowExecutionStartedEvent>(json);
                workflowName    = wfStartData.WorkflowName;
                workflowVersion = wfStartData.WorkflowVersion;
                var wf = GetWorkflow(workflowName, workflowVersion);
                if (wf == null)
                {
                    log.Error($"Unknown workflow definition - {workflowName} v {workflowVersion} ");
                    throw new ApplicationException($"Unknown workflow definition - {workflowName} v {workflowVersion} ");
                }
                var wfDefinition = JsonConvert.DeserializeObject <WorkflowObj>(wf.Json);

                Executions.InsertOnSubmit(new Execution
                {
                    ExecutionId  = executionId,
                    JobId        = (string)wfStartData.Input.SelectToken("_jobId"),
                    Workflow     = wf,
                    DecisionList = wfStartData.DecisionList ?? wfDefinition.DecisionList ?? "decider",
                    ExecutionStartToCloseTimeout = (int?)(wfStartData.ExecutionStartToCloseTimeout ?? wfDefinition.DefaultExecutionStartToCloseTimeout),
                    TaskStartToCloseTimeout      = (int?)(wfStartData.TaskStartToCloseTimeout ?? wfDefinition.DefaultTaskStartToCloseTimeout),
                    TaskScheduleToCloseTimeout   = null, // What goes here?
                    TaskScheduleToStartTimeout   = null, // and here?
                    HistorySeen      = 0,
                    AwaitingDecision = true,
                    LastSeen         = DateTime.UtcNow,
                    ExecutionState   = new ExecutionState {
                        State = ExState.Running
                    }
                });

                wfStartData.ExecutionId = executionId;
                wfStartData.Id          = 0;
                wfStartData.Timestamp   = DateTime.UtcNow;

                Histories.InsertOnSubmit(wfStartData);

                SubmitChanges(ConflictMode.FailOnFirstConflict);
            }
            catch (ChangeConflictException ex)
            {
                log.Error("Failed to create new workflow execution", ex);
                throw new ApplicationException($"Failed to create new workflow execution - {workflowName} v {workflowVersion} ");
            }
            return(new JObject(new JProperty("executionId", executionId.ToString())).ToString(Formatting.None));
        }