public async Task <IActionResult> UpdateExecutionStatusAsync([Required] string executionId, [Required, FromBody] UpdateExecutionStatusApiModel updateApiModel) { // Try to get the execution... var execution = await execRepository.GetExecutionAsync(executionId, userContext.Executor.TenantId); // If we can't find it, respond with [404 Not Found]... if (execution == null) { return(NotFound($"[{ErrorCodes.ExecutionNotFound}]: Execution [{executionId}] not found.")); } // Make sure that the provided [statusUpdateKey] matches that of the execution. If it doesn't, respond with a [403 Forbidden]. // For more information on the execution pipeline and the role of the status update key, see /doc/architecture/execution-pipeline.md. if (execution.StatusUpdateKey != updateApiModel.StatusUpdateKey) { return(Forbid()); } // Update the core execution model with the provided execution status update... execution = ApplyExecutionUpdate(updateApiModel, execution); // Check that the status update makes sense. // Specifically, check that the provided status itself is valid and the status transition makes sense. if (string.IsNullOrEmpty(updateApiModel.Status) == false) { if (Enum.TryParse <ExecutionStatus>(updateApiModel.Status, out var execStatus)) { if (execution.Status.CanTransitionTo(execStatus)) { execution.Status = execStatus; } else { return(BadRequest($"[{ErrorCodes.InvalidExecutionStatusTransition}]: " + $"Unable to update execution state to [{updateApiModel.Status}]; " + $"execution is already [{updateApiModel.Status}].")); } } else { return(BadRequest($"[{ErrorCodes.InvalidExecutionStatus}]: Execution status [{updateApiModel.Status}] is invalid.")); } } // sSave the updated execution... await UpdateExecutionAsync(execution); // Respond with [200 OK] and let the caller know that the update was successfully processed... return(Ok(await ToExecutionUpdateApiModelAsync(execution))); }
private Core.Models.Execution ApplyExecutionUpdate(UpdateExecutionStatusApiModel updateApiModel, Core.Models.Execution execution) { execution.LastUpdatedDateTimeUtc = (updateApiModel.LastUpdatedDateTimeUtc ?? DateTime.UtcNow); execution.PercentComplete = updateApiModel.PercentComplete; execution.ProvidedOutputObjects.AddRange(updateApiModel.ProvidedOutputObjects.Except(execution.ProvidedOutputObjects)); execution.ResultData = (updateApiModel.ResultData ?? execution.ResultData); execution.StatusMessage = updateApiModel.StatusMessage; execution.ExecutionTimeoutDateTimeUtc = updateApiModel.ExecutionTimeoutDateTimeUtc.GetValueOrDefault(); execution.ValidationErrors.AddRange( updateApiModel.ValidationErrors .Where(ve => execution.ValidationErrors.None(eve => (ve.ErrorId == eve.ErrorId))) .Select(ve => ve.ToCoreModel())); return(execution); }