/// <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)); }