public async Task <IActionResult> UploadOutput([Required] int inputId, [Required] string email, [FromBody, Required] OutputContent result) { try { _logger.LogInformation(LoggingEvents.UPLOAD_OUTPUT, "Uploading result for input {inputId} and email {email}", inputId, email); // Validations if (string.IsNullOrEmpty(email)) { return(GetBadRequest("Parameter email is required")); } if (string.IsNullOrEmpty(result?.Content)) { return(GetBadRequest("Parameter result is required")); } email = email.Trim(); // Get the input var input = await _context.Inputs.FirstOrDefaultAsync(i => i.InputId == inputId); if (input == null) { return(GetNotFound($"The input {inputId} was not found")); } // Get the user var user = await _context.LabUsers.FirstOrDefaultAsync(u => u.EMail == email); if (user == null) { return(GetNotFound($"The user {email} was not found")); } // Security check if (input.AssignedTo?.LabUserId != user.LabUserId) { return(GetForbid($"The user {email} can't update the input {inputId} result value")); } // Parse the output var parsedOutput = await OutputParser.ParseAsync(result.Content); // Upload the result to blob storage var blobName = await UploadOutputResultToStorageAsync(result.Content, input); // Update the output status var tuple = await UpdateOuputAsync(blobName, input, parsedOutput); var output = tuple.Item1; var firstUpdate = tuple.Item2; _telemetry.TrackEvent("OutputUploaded"); // Notify event hub, but only if was the first update to avoid dashboard hacks if (firstUpdate) { await SendEventHubNotificationAsync(input, user, output, parsedOutput); } return(Ok(new UploadOutputResult { OutputId = output.OutputId })); } catch (OutputParsingException ex) { _telemetry.TrackException(ex); _logger.LogError(LoggingEvents.UPLOAD_OUTPUT_SERVER_ERROR, ex, "Output parse error"); return(BadRequest(ex.Message)); } catch (Exception ex) { _telemetry.TrackException(ex); _logger.LogError(LoggingEvents.UPLOAD_OUTPUT_SERVER_ERROR, ex, ex.Message); return(StatusCode(500)); } }