private async Task <IActionResult> SaveDatasetDefinition(DatasetDefinition definition, string correlationId, Reference user) { DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges(); DatasetDefinition existingDefinition = await _datasetsRepositoryPolicy.ExecuteAsync(() => _datasetsRepository.GetDatasetDefinition(definition.Id)); IEnumerable <string> relationships = null; if (existingDefinition != null) { datasetDefinitionChanges = _definitionChangesDetectionService.DetectChanges(definition, existingDefinition); relationships = await _datasetsRepositoryPolicy.ExecuteAsync(() => _datasetsRepository.GetDistinctRelationshipSpecificationIdsForDatasetDefinitionId(datasetDefinitionChanges.Id)); IEnumerable <FieldDefinitionChanges> fieldDefinitionChanges = datasetDefinitionChanges.TableDefinitionChanges.SelectMany(m => m.FieldChanges); if (!relationships.IsNullOrEmpty() && !fieldDefinitionChanges.IsNullOrEmpty()) { if (fieldDefinitionChanges.Any(m => m.ChangeTypes.Any(c => c == FieldDefinitionChangeType.RemovedField))) { return(new BadRequestObjectResult("Unable to remove a field as there are currently relationships setup against this schema")); } if (fieldDefinitionChanges.Any(m => m.ChangeTypes.Any(c => c == FieldDefinitionChangeType.IdentifierType))) { return(new BadRequestObjectResult("Unable to change provider identifier as there are currently relationships setup against this schema")); } } } try { HttpStatusCode result = await _datasetsRepositoryPolicy.ExecuteAsync(() => _datasetsRepository.SaveDefinition(definition)); if (!result.IsSuccess()) { int statusCode = (int)result; _logger.Error($"Failed to save dataset definition - {definition.Name} to cosmos db with status {statusCode}"); return(new StatusCodeResult(statusCode)); } IEnumerable <PoliciesApiModels.FundingStream> fundingStreams = await _policyRepository.GetFundingStreams(); PoliciesApiModels.FundingStream fundingStream = fundingStreams.SingleOrDefault(_ => _.Id == definition.FundingStreamId); await IndexDatasetDefinition(definition, fundingStream); } catch (Exception exception) { string errorMessage = $"Exception occurred writing dataset definition - {definition.Name} to cosmos db"; _logger.Error(exception, errorMessage); return(new InternalServerErrorResult(errorMessage)); } byte[] excelAsBytes = _excelWriter.Write(definition); if (excelAsBytes == null || excelAsBytes.Length == 0) { string errorMessage = $"Failed to generate excel file for {definition.Name}"; _logger.Error(errorMessage); return(new InternalServerErrorResult(errorMessage)); } try { await SaveToBlobStorage(excelAsBytes, definition.Name); } catch (Exception ex) { return(new InternalServerErrorResult(ex.Message)); } _logger.Information($"Successfully saved dataset definition - {definition.Name} to cosmos db"); if (existingDefinition != null && datasetDefinitionChanges.HasChanges) { if (!relationships.IsNullOrEmpty()) { Task <ApiResponse <CalcJob> >[] updateCodeContextJobs = relationships.Select(specificationId => _calculationsResilience.ExecuteAsync(() => _calculations.QueueCodeContextUpdate(specificationId))).ToArray(); await TaskHelper.WhenAllAndThrow(updateCodeContextJobs); } IDictionary <string, string> properties = MessageExtensions.BuildMessageProperties(correlationId, user); await _messengerService.SendToTopic(ServiceBusConstants.TopicNames.DataDefinitionChanges, datasetDefinitionChanges, properties); } return(new OkResult()); }