public async Task ProcessChanges_GivenChangeModelButHasNoFieldChanges_LogsAndReturns()
        {
            //Arrange
            string definitionId = "df-id-1";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            datasetDefinitionChanges.DefinitionChanges.Add(DefinitionChangeType.DefinitionName);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(logger: logger);

            //Act
            await processor.ProcessChanges(message);

            //Assert
            logger
            .Received(1)
            .Information(Arg.Is($"No dataset definition field changes for definition id '{definitionId}'"));
        }
        public async Task ProcessChange_GivenMessageWithNoDefinitionChanges_LogsAndReturns()
        {
            //Arrange
            const string definitionId = "123456";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId
            };

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            DatasetDefinitionNameChangeProcessor processor = CreateProcessor(logger: logger);

            //Act
            await processor.Process(message);

            //Assert
            logger
            .Received(1)
            .Information(Arg.Is($"No dataset definition name change for definition id '{definitionId}'"));
        }
        public DatasetDefinitionChanges DetectChanges(DatasetDefinition newDatasetDefinition, DatasetDefinition existingDatasetDefinition)
        {
            Guard.ArgumentNotNull(newDatasetDefinition, nameof(newDatasetDefinition));
            Guard.ArgumentNotNull(existingDatasetDefinition, nameof(existingDatasetDefinition));

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = newDatasetDefinition.Id
            };

            string newDatasetDefinitionAsJson      = JsonConvert.SerializeObject(newDatasetDefinition);
            string existingDatasetDefinitionAsJson = JsonConvert.SerializeObject(existingDatasetDefinition);

            if (string.Equals(newDatasetDefinitionAsJson, existingDatasetDefinitionAsJson))
            {
                return(datasetDefinitionChanges);
            }

            if (newDatasetDefinition.Name != existingDatasetDefinition.Name)
            {
                datasetDefinitionChanges.DefinitionChanges.Add(DefinitionChangeType.DefinitionName);
                datasetDefinitionChanges.NewName = newDatasetDefinition.Name;
            }

            datasetDefinitionChanges.TableDefinitionChanges.AddRange(DetectTableDefinitionChanges(existingDatasetDefinition.TableDefinitions, newDatasetDefinition.TableDefinitions));

            return(datasetDefinitionChanges);
        }
        public override async Task Process(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            if (!_featureToggle.IsProcessDatasetDefinitionNameChangesEnabled())
            {
                return;
            }

            DatasetDefinitionChanges datasetDefinitionChanges = message.GetPayloadAsInstanceOf <DatasetDefinitionChanges>();

            _logger.Information("Checking for changes before proceeding");

            if (datasetDefinitionChanges == null)
            {
                throw new NonRetriableException("Message does not contain a valid dataset definition change model");
            }

            if (datasetDefinitionChanges.DefinitionChanges.IsNullOrEmpty())
            {
                _logger.Information($"No dataset definition name change for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            Reference reference = new Reference(datasetDefinitionChanges.Id, datasetDefinitionChanges.NewName);

            _logger.Information($"Updating relationships for updated definition name with definition id '{datasetDefinitionChanges.Id}'");

            await _definitionSpecificationRelationshipService.UpdateRelationshipDatasetDefinitionName(reference);

            _logger.Information($"Updating datasets for updated definition name with definition id '{datasetDefinitionChanges.Id}'");

            await _datasetService.UpdateDatasetAndVersionDefinitionName(reference);
        }
Beispiel #5
0
        public void ProcessChanges_GivenChangeModelWithFieldNameChangesButNoRelationshipsFound_ThrowsRetriableException()
        {
            //Arrange
            string definitionId    = "df-id-1";
            string specificationId = "spec-1";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges = new FieldDefinitionChanges
            {
                FieldDefinition = new FieldDefinition
                {
                    Id = "field1"
                }
            };

            fieldDefinitionChanges.ChangeTypes.Add(FieldDefinitionChangeType.FieldName);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.Add(fieldDefinitionChanges);

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IEnumerable <string> relationshipSpecificationIds = new[] { specificationId };

            IDatasetsApiClient datasetRepository = CreateDatasetRepository();

            datasetRepository
            .GetSpecificationIdsForRelationshipDefinitionId(Arg.Is(definitionId))
            .Returns(new ApiResponse <IEnumerable <string> >(HttpStatusCode.OK, relationshipSpecificationIds));
            datasetRepository
            .GetCurrentRelationshipsBySpecificationIdAndDatasetDefinitionId(Arg.Is(specificationId), Arg.Is(definitionId))
            .Returns(new ApiResponse <IEnumerable <Common.ApiClient.DataSets.Models.DatasetSpecificationRelationshipViewModel> >(HttpStatusCode.OK, Enumerable.Empty <Common.ApiClient.DataSets.Models.DatasetSpecificationRelationshipViewModel>()));


            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(logger: logger, datasetRepository: datasetRepository);

            //Act
            Func <Task> test = async() => await processor.Run(message);

            //Assert
            test
            .Should()
            .ThrowExactly <RetriableException>()
            .Which
            .Message
            .Should()
            .Be($"No relationships found for specificationId '{specificationId}' and dataset definition id '{definitionId}'");
        }
Beispiel #6
0
        public void DetectChanges_GivenTableDefinitionNameChange_ReturnsModelWithChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name2", FieldDefinitions = new List <FieldDefinition>()
                    }
                }
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition>()
                    }
                }
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .ChangeTypes
            .First()
            .Should()
            .Be(TableDefinitionChangeType.DefinitionName);

            changes
            .TableDefinitionChanges
            .First()
            .TableDefinition
            .Name
            .Should()
            .Be("name2");
        }
Beispiel #7
0
        async public Task SaveDefinition_GivenValidYamlButSavingToDatabaseThrowsException_ReturnsInternalServerError()
        {
            //Arrange
            string yaml = CreateRawDefinition();

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            IDatasetRepository dataSetsRepository = CreateDataSetsRepository();

            dataSetsRepository
            .When(x => x.SaveDefinition(Arg.Any <DatasetDefinition>()))
            .Do(x => { throw new Exception(); });

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, dataSetsRepository, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <InternalServerErrorResult>()
            .Which
            .Value
            .Should()
            .Be("Exception occurred writing to yaml file: 12345.yaml to cosmos db");

            logger
            .Received(1)
            .Error(Arg.Any <Exception>(), Arg.Is($"Exception occurred writing to yaml file: {yamlFile} to cosmos db"));
        }
Beispiel #8
0
        public override async Task Process(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            if (!_featureToggle.IsProcessDatasetDefinitionFieldChangesEnabled())
            {
                return;
            }

            DatasetDefinitionChanges datasetDefinitionChanges = message.GetPayloadAsInstanceOf <DatasetDefinitionChanges>();

            _logger.Information("Checking for dataset definition changes before proceeding");

            if (datasetDefinitionChanges == null)
            {
                throw new NonRetriableException("Message does not contain a valid dataset definition change model");
            }

            if (!datasetDefinitionChanges.HasChanges)
            {
                _logger.Information($"No dataset definition field changes for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            IEnumerable <FieldDefinitionChanges> fieldChanges = datasetDefinitionChanges.TableDefinitionChanges.SelectMany(m => m.FieldChanges);

            if (fieldChanges.IsNullOrEmpty())
            {
                _logger.Information($"No dataset definition field changes for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            ApiResponse <IEnumerable <string> > datasetsApiClientResponse = await _datasetsApiClientPolicy.ExecuteAsync(() => _datasetsApiClient.GetSpecificationIdsForRelationshipDefinitionId(datasetDefinitionChanges.Id));

            if (!datasetsApiClientResponse.StatusCode.IsSuccess())
            {
                string errorMessage = $"No Specification ids for relationship definition id {datasetDefinitionChanges.Id} were returned from the repository, result came back null";
                _logger.Error(errorMessage);

                throw new RetriableException(errorMessage);
            }

            IEnumerable <string> relationshipSpecificationIds = datasetsApiClientResponse.Content;

            if (relationshipSpecificationIds.IsNullOrEmpty())
            {
                _logger.Information($"No dataset definition specification relationships exists for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            await ProcessFieldChanges(datasetDefinitionChanges.Id, fieldChanges, relationshipSpecificationIds);
        }
        public async Task ProcessChange_GivenMessageWithDefinitionChanges_CallsServices()
        {
            //Arrange
            const string definitionId   = "123456";
            const string definitionName = "New def name";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id      = definitionId,
                NewName = definitionName
            };

            datasetDefinitionChanges.DefinitionChanges.Add(DefinitionChangeType.DefinitionName);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IDefinitionSpecificationRelationshipService definitionSpecificationRelationshipService = CreateDefinitionSpecificationRelationshipService();

            IDatasetService datasetService = CreateDataService();

            DatasetDefinitionNameChangeProcessor processor = CreateProcessor(definitionSpecificationRelationshipService, datasetService, logger);

            //Act
            await processor.Process(message);

            //Assert
            await
            definitionSpecificationRelationshipService
            .Received(1)
            .UpdateRelationshipDatasetDefinitionName(Arg.Is <Reference>(m => m.Id == definitionId && m.Name == definitionName));

            await
            datasetService
            .Received(1)
            .UpdateDatasetAndVersionDefinitionName(Arg.Is <Reference>(m => m.Id == definitionId && m.Name == definitionName));

            logger
            .Received()
            .Information(Arg.Is($"Updating relationships for updated definition name with definition id '{definitionId}'"));

            logger
            .Received(1)
            .Information(Arg.Is($"Updating datasets for updated definition name with definition id '{definitionId}'"));
        }
        public async Task ProcessChanges(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            if (!_featureToggle.IsProcessDatasetDefinitionFieldChangesEnabled())
            {
                return;
            }

            DatasetDefinitionChanges datasetDefinitionChanges = message.GetPayloadAsInstanceOf <DatasetDefinitionChanges>();

            _logger.Information("Checking for dataset definition changes before proceeding");

            if (datasetDefinitionChanges == null)
            {
                throw new NonRetriableException("Message does not contain a valid dataset definition change model");
            }

            if (!datasetDefinitionChanges.HasChanges)
            {
                _logger.Information($"No dataset definition field changes for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            IEnumerable <FieldDefinitionChanges> fieldChanges = datasetDefinitionChanges.TableDefinitionChanges.SelectMany(m => m.FieldChanges);

            if (fieldChanges.IsNullOrEmpty())
            {
                _logger.Information($"No dataset definition field changes for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            IEnumerable <string> relationshipSpecificationIds = await _datasetRepositoryPolicy.ExecuteAsync(() => _datasetRepository.GetRelationshipSpecificationIdsByDatasetDefinitionId(datasetDefinitionChanges.Id));

            if (relationshipSpecificationIds.IsNullOrEmpty())
            {
                _logger.Information($"No dataset definition specification relationships exists for definition id '{datasetDefinitionChanges.Id}'");

                return;
            }

            await ProcessFieldChanges(datasetDefinitionChanges.Id, fieldChanges, relationshipSpecificationIds);
        }
        public async Task ProcessChanges_GivenChangeModelWithFieldChangesButNoRelationshipsExist_LogsAndReturns()
        {
            //Arrange
            string definitionId = "df-id-1";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges = new FieldDefinitionChanges();

            fieldDefinitionChanges.ChangeTypes.Add(FieldDefinitionChangeType.FieldName);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.Add(fieldDefinitionChanges);

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IDatasetsApiClient datasetRepository = CreateDatasetRepository();

            datasetRepository
            .GetSpecificationIdsForRelationshipDefinitionId(Arg.Is(definitionId))
            //.Returns(Enumerable.Empty<string>());
            .Returns(new ApiResponse <IEnumerable <string> >(HttpStatusCode.OK, Enumerable.Empty <string>()));

            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(logger: logger, datasetRepository: datasetRepository);

            //Act
            await processor.Process(message);

            //Assert
            logger
            .Received(1)
            .Information(Arg.Is($"No dataset definition specification relationships exists for definition id '{definitionId}'"));
        }
Beispiel #12
0
        public void DetectChanges_GivenNoChanges_ReturnsModelWithNoChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name = "name"
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name = "name"
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeFalse();
        }
Beispiel #13
0
        async public Task SaveDefinition_GivenValidYamlAndSearchDoesNotContainExistingItem_ThenSaveWasSuccesfulAndReturnsOK()
        {
            //Arrange
            string yaml         = CreateRawDefinition();
            string definitionId = "9183";

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.Created;

            IDatasetRepository datasetsRepository = CreateDataSetsRepository();

            datasetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(statusCode);

            ISearchRepository <DatasetDefinitionIndex> searchRepository = CreateDatasetDefinitionSearchRepository();

            searchRepository
            .SearchById(Arg.Is(definitionId))
            .Returns((DatasetDefinitionIndex)null);

            byte[] excelAsBytes = new byte[100];

            IExcelWriter <DatasetDefinition> excelWriter = CreateExcelWriter();

            excelWriter
            .Write(Arg.Any <DatasetDefinition>())
            .Returns(excelAsBytes);

            ICloudBlob blob = Substitute.For <ICloudBlob>();

            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .GetBlockBlobReference(Arg.Any <string>())
            .Returns(blob);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, datasetsRepository, searchRepository,
                                                                  excelWriter: excelWriter, blobClient: blobClient, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <OkResult>();

            await searchRepository
            .Received(1)
            .SearchById(Arg.Is(definitionId));

            await searchRepository
            .Received(1)
            .Index(Arg.Is <IEnumerable <DatasetDefinitionIndex> >(
                       i => i.First().Description == "14/15 description" &&
                       i.First().Id == "9183" &&
                       !string.IsNullOrWhiteSpace(i.First().ModelHash) &&
                       i.First().Name == "14/15" &&
                       i.First().ProviderIdentifier == "None"
                       ));

            await datasetsRepository
            .Received(1)
            .SaveDefinition(Arg.Is <DatasetDefinition>(
                                i => i.Description == "14/15 description" &&
                                i.Id == "9183" &&
                                i.Name == "14/15"
                                ));

            logger
            .Received(1)
            .Information(Arg.Is($"Successfully saved file: {yamlFile} to cosmos db"));
        }
Beispiel #14
0
        async public Task SaveDefinition_GivenValidYamlButFailsToUploadToBlobStorage_ReturnsInvalidServerError()
        {
            //Arrange
            string yaml         = CreateRawDefinition();
            string definitionId = "9183";

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.Created;

            IDatasetRepository datasetsRepository = CreateDataSetsRepository();

            datasetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(statusCode);

            ISearchRepository <DatasetDefinitionIndex> searchRepository = CreateDatasetDefinitionSearchRepository();

            searchRepository
            .SearchById(Arg.Is(definitionId))
            .Returns((DatasetDefinitionIndex)null);

            byte[] excelAsBytes = new byte[100];

            IExcelWriter <DatasetDefinition> excelWriter = CreateExcelWriter();

            excelWriter
            .Write(Arg.Any <DatasetDefinition>())
            .Returns(excelAsBytes);

            ICloudBlob blob = Substitute.For <ICloudBlob>();

            blob
            .When(x => x.UploadFromStreamAsync(Arg.Any <Stream>()))
            .Do(x => { throw new Exception($"Failed to upload 14/15 blob storage"); });

            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .GetBlockBlobReference(Arg.Is("schemas/14_15.xlsx"))
            .Returns(blob);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, datasetsRepository, searchRepository,
                                                                  excelWriter: excelWriter, blobClient: blobClient, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <InternalServerErrorResult>()
            .Which
            .Value
            .Should()
            .Be($"Failed to upload 14/15 blob storage");
        }
Beispiel #15
0
        async public Task SaveDefinition_GivenValidYamlButFailsToGenerateExcelFile_ReturnsInvalidServerError()
        {
            //Arrange
            string yaml         = CreateRawDefinition();
            string definitionId = "9183";

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.Created;

            IDatasetRepository datasetsRepository = CreateDataSetsRepository();

            datasetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(statusCode);

            ISearchRepository <DatasetDefinitionIndex> searchRepository = CreateDatasetDefinitionSearchRepository();

            searchRepository
            .SearchById(Arg.Is(definitionId))
            .Returns((DatasetDefinitionIndex)null);

            byte[] excelAsBytes = new byte[0];

            IExcelWriter <DatasetDefinition> excelWriter = CreateExcelWriter();

            excelWriter
            .Write(Arg.Any <DatasetDefinition>())
            .Returns(excelAsBytes);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, datasetsRepository, searchRepository, excelWriter: excelWriter, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <InternalServerErrorResult>()
            .Which
            .Value
            .Should()
            .Be($"Failed to generate excel file for 14/15");

            logger
            .Received(1)
            .Error(Arg.Is($"Failed to generate excel file for 14/15"));
        }
Beispiel #16
0
        public async Task ProcessChanges_GivenChangeModelWithAggregableFieldChanges_CallsResetCalculationForFieldDefinitionChanges(FieldDefinitionChangeType fieldDefinitionChangeType)
        {
            //Arrange
            string definitionId    = "df-id-1";
            string specificationId = "spec-1";

            IEnumerable <Calculation> calculations = new[]
            {
                new Calculation
                {
                    Current = new CalculationVersion
                    {
                        SourceCode = "return Sum(Datasets.TestRelationship.TestField1)"
                    }
                }
            };

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges = new FieldDefinitionChanges
            {
                FieldDefinition = new FieldDefinition
                {
                    Id = "field1"
                },
                ExistingFieldDefinition = new FieldDefinition {
                    Name = "test field 1"
                }
            };

            fieldDefinitionChanges.ChangeTypes.Add(fieldDefinitionChangeType);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.Add(fieldDefinitionChanges);

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IEnumerable <string> relationshipSpecificationIds = new[] { specificationId };

            IEnumerable <Common.ApiClient.DataSets.Models.DatasetSpecificationRelationshipViewModel> relationshipViewModels = new[]
            {
                new Common.ApiClient.DataSets.Models.DatasetSpecificationRelationshipViewModel
                {
                    Name = "Test Relationship"
                }
            };

            IEnumerable <DatasetSpecificationRelationshipViewModel> relationshipViewModel = new[]
            {
                new DatasetSpecificationRelationshipViewModel
                {
                    Name = "Test Relationship"
                }
            };

            IDatasetsApiClient datasetRepository = CreateDatasetRepository();

            datasetRepository
            .GetSpecificationIdsForRelationshipDefinitionId(Arg.Is(definitionId))
            .Returns(new ApiResponse <IEnumerable <string> >(HttpStatusCode.OK, relationshipSpecificationIds));
            datasetRepository
            .GetCurrentRelationshipsBySpecificationIdAndDatasetDefinitionId(Arg.Is(specificationId), Arg.Is(definitionId))
            .Returns(new ApiResponse <IEnumerable <Common.ApiClient.DataSets.Models.DatasetSpecificationRelationshipViewModel> >(HttpStatusCode.OK, relationshipViewModels));


            ICalculationService calculationService = CreateCalculationService();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();

            calculationsRepository
            .GetCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(calculations);

            IMapper mapper = CreateMapper();

            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(
                logger: logger,
                datasetRepository: datasetRepository,
                calculationService: calculationService,
                calculationsRepository: calculationsRepository,
                mapper: mapper);

            //Act
            await processor.Run(message);

            //Assert
            await
            calculationService
            .Received(1)
            .ResetCalculationForFieldDefinitionChanges(Arg.Is <IEnumerable <Models.Datasets.ViewModels.DatasetSpecificationRelationshipViewModel> >(_ => _.First().Id == relationshipViewModel.First().Id), Arg.Is(specificationId), Arg.Is <IEnumerable <string> >(m => m.First() == "test field 1"));
        }
Beispiel #17
0
        async public Task SaveDefinition_GivenValidYamlButFailedToSaveToDatabase_ReturnsStatusCode()
        {
            //Arrange
            string yaml = CreateRawDefinition();

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode failedCode = HttpStatusCode.BadGateway;

            IDatasetRepository dataSetsRepository = CreateDataSetsRepository();

            dataSetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(failedCode);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, dataSetsRepository, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <StatusCodeResult>();

            StatusCodeResult statusCodeResult = (StatusCodeResult)result;

            statusCodeResult
            .StatusCode
            .Should()
            .Be(502);

            logger
            .Received(1)
            .Error(Arg.Is($"Failed to save yaml file: {yamlFile} to cosmos db with status 502"));
        }
Beispiel #18
0
        async public Task SaveDefinition_GivenUpdatedYamlWithChangedIdentifierTypeFieldButAlreadyUsedInRelationship_ReturnsBadRequest()
        {
            //Arrange
            IEnumerable <string> specificationIds = new[] { "spec-1" };
            string definitionId = "9183";
            string yaml         = CreateRawDefinition();

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            IDatasetRepository datasetRepository = CreateDataSetsRepository();

            datasetRepository
            .GetDistinctRelationshipSpecificationIdsForDatasetDefinitionId(Arg.Is(definitionId))
            .Returns(specificationIds);
            datasetRepository
            .GetDatasetDefinition(Arg.Is(definitionId))
            .Returns(new DatasetDefinition());

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges = new FieldDefinitionChanges();

            fieldDefinitionChanges.ChangeTypes.Add(FieldDefinitionChangeType.IdentifierType);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.Add(fieldDefinitionChanges);

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, definitionChangesDetectionService: definitionChangesDetectionService, datasetsRepository: datasetRepository);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <BadRequestObjectResult>()
            .Which
            .Value
            .Should()
            .Be("Unable to change provider identifier as there are currently relationships setup against this schema");
        }
        async public Task <IActionResult> SaveDefinition(HttpRequest request)
        {
            string yaml = await request.GetRawBodyStringAsync();

            string yamlFilename = request.GetYamlFileNameFromRequest();

            if (string.IsNullOrEmpty(yaml))
            {
                _logger.Error($"Null or empty yaml provided for file: {yamlFilename}");
                return(new BadRequestObjectResult($"Invalid yaml was provided for file: {yamlFilename}"));
            }

            var deserializer = new DeserializerBuilder()
                               .WithNamingConvention(new CamelCaseNamingConvention())
                               .Build();

            DatasetDefinition definition = null;

            try
            {
                definition = deserializer.Deserialize <DatasetDefinition>(yaml);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, $"Invalid yaml was provided for file: {yamlFilename}");
                return(new BadRequestObjectResult($"Invalid yaml was provided for file: {yamlFilename}"));
            }

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            DatasetDefinition existingDefinition = await _datasetsRepositoryPolicy.ExecuteAsync(() => _datasetsRepository.GetDatasetDefinition(definition.Id));

            if (existingDefinition != null)
            {
                datasetDefinitionChanges = _definitionChangesDetectionService.DetectChanges(definition, existingDefinition);

                IEnumerable <string> 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 yaml file: {yamlFilename} to cosmos db with status {statusCode}");

                    return(new StatusCodeResult(statusCode));
                }

                await IndexDatasetDefinition(definition);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, $"Exception occurred writing to yaml file: {yamlFilename} to cosmos db");

                return(new InternalServerErrorResult($"Exception occurred writing to yaml file: {yamlFilename} to cosmos db"));
            }

            byte[] excelAsBytes = _excelWriter.Write(definition);

            if (excelAsBytes == null || excelAsBytes.Length == 0)
            {
                _logger.Error($"Failed to generate excel file for {definition.Name}");

                return(new InternalServerErrorResult($"Failed to generate excel file for {definition.Name}"));
            }

            try
            {
                await SaveToBlobStorage(excelAsBytes, definition.Name);
            }
            catch (Exception ex)
            {
                return(new InternalServerErrorResult(ex.Message));
            }

            _logger.Information($"Successfully saved file: {yamlFilename} to cosmos db");

            if (existingDefinition != null && datasetDefinitionChanges.HasChanges)
            {
                IDictionary <string, string> properties = request.BuildMessageProperties();

                await _messengerService.SendToTopic(ServiceBusConstants.TopicNames.DataDefinitionChanges, datasetDefinitionChanges, properties);
            }

            return(new OkResult());
        }
Beispiel #20
0
        public void DetectChanges_GivenNewTableDefinitionHasChangedFieldAggrgableFalse_ReturnsModelWithChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field1", IsAggregable = false
                            }
                        }
                    }
                }
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field1", IsAggregable = true
                            },
                        }
                    }
                }
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .First()
            .ChangeTypes
            .First()
            .Should()
            .Be(FieldDefinitionChangeType.IsNotAggregable);
        }
Beispiel #21
0
        public void DetectChanges_GivenNewTableDefinitionHasLessFields_ReturnsModelWithChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123"
                            }
                        }
                    }
                }
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123"
                            },
                            new FieldDefinition {
                                Id = "456"
                            }
                        }
                    }
                }
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .First()
            .ChangeTypes
            .First()
            .Should()
            .Be(FieldDefinitionChangeType.RemovedField);

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .First()
            .FieldDefinition
            .Id
            .Should()
            .Be("456");
        }
        public async Task ProcessChanges_GivenChangeModelWithMultipleFieldNameChanges_CallsResetCalculationForFieldDefinitionChanges()
        {
            //Arrange
            string definitionId    = "df-id-1";
            string specificationId = "spec-1";

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges1 = new FieldDefinitionChanges
            {
                FieldDefinition = new FieldDefinition
                {
                    Id = "field1"
                },
                ExistingFieldDefinition = new FieldDefinition {
                    Name = "test field 1"
                }
            };

            FieldDefinitionChanges fieldDefinitionChanges2 = new FieldDefinitionChanges
            {
                FieldDefinition = new FieldDefinition
                {
                    Id = "field2"
                },
                ExistingFieldDefinition = new FieldDefinition {
                    Name = "test field 2"
                }
            };

            fieldDefinitionChanges1.ChangeTypes.Add(FieldDefinitionChangeType.FieldName);
            fieldDefinitionChanges2.ChangeTypes.Add(FieldDefinitionChangeType.FieldName);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.AddRange(new[] { fieldDefinitionChanges1, fieldDefinitionChanges2 });

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IEnumerable <string> relationshipSpecificationIds = new[] { specificationId };

            IEnumerable <DatasetSpecificationRelationshipViewModel> relationshipViewModels = new[]
            {
                new DatasetSpecificationRelationshipViewModel()
            };

            IDatasetRepository datasetRepository = CreateDatasetRepository();

            datasetRepository
            .GetRelationshipSpecificationIdsByDatasetDefinitionId(Arg.Is(definitionId))
            .Returns(relationshipSpecificationIds);
            datasetRepository
            .GetCurrentRelationshipsBySpecificationIdAndDatasetDefinitionId(Arg.Is(specificationId), Arg.Is(definitionId))
            .Returns(relationshipViewModels);

            ICalculationService calculationService = CreateCalculationService();

            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(
                logger: logger,
                datasetRepository: datasetRepository,
                calculationService: calculationService);

            //Act
            await processor.ProcessChanges(message);

            //Assert
            await
            calculationService
            .Received(1)
            .ResetCalculationForFieldDefinitionChanges(Arg.Is(relationshipViewModels), Arg.Is(specificationId),
                                                       Arg.Is <IEnumerable <string> >(
                                                           m =>
                                                           m.Count() == 2 &&
                                                           m.ElementAt(0) == "test field 1" &&
                                                           m.ElementAt(1) == "test field 2"));
        }
Beispiel #23
0
        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());
        }
Beispiel #24
0
        public async Task SaveDefinition_GivenValidYamlAndSearchDoesContainsExistingItemWithNoUpdates_ThenDatasetDefinitionSavedInCosmosAndSearchNotUpdatedAndReturnsOK()
        {
            //Arrange
            string yaml         = CreateRawDefinition();
            string definitionId = "9183";

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.Created;

            IDatasetRepository datasetsRepository = CreateDataSetsRepository();

            datasetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(statusCode);

            DatasetDefinitionIndex existingIndex = new DatasetDefinitionIndex()
            {
                Description        = "14/15 description",
                Id                 = "9183",
                LastUpdatedDate    = new DateTimeOffset(2018, 6, 19, 14, 10, 2, TimeSpan.Zero),
                ModelHash          = "DFBD0E1ACD29CEBCF5AD45674688D3780D916294C4DF878074AFD01B67BF129C",
                Name               = "14/15",
                ProviderIdentifier = "None",
            };

            ISearchRepository <DatasetDefinitionIndex> searchRepository = CreateDatasetDefinitionSearchRepository();

            searchRepository
            .SearchById(Arg.Is(definitionId))
            .Returns(existingIndex);

            byte[] excelAsBytes = new byte[100];

            IExcelWriter <DatasetDefinition> excelWriter = CreateExcelWriter();

            excelWriter
            .Write(Arg.Any <DatasetDefinition>())
            .Returns(excelAsBytes);

            ICloudBlob blob = Substitute.For <ICloudBlob>();

            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .GetBlockBlobReference(Arg.Any <string>())
            .Returns(blob);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Any <DatasetDefinition>())
            .Returns(datasetDefinitionChanges);

            DefinitionsService service = CreateDefinitionsService(logger, datasetsRepository, searchRepository, excelWriter: excelWriter, blobClient: blobClient, definitionChangesDetectionService: definitionChangesDetectionService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <OkResult>();

            await searchRepository
            .Received(1)
            .SearchById(Arg.Is(definitionId));

            await searchRepository
            .Received(0)
            .Index(Arg.Any <IEnumerable <DatasetDefinitionIndex> >());

            await datasetsRepository
            .Received(1)
            .SaveDefinition(Arg.Is <DatasetDefinition>(
                                i => i.Description == "14/15 description" &&
                                i.Id == "9183" &&
                                i.Name == "14/15"
                                ));

            logger
            .Received(1)
            .Information(Arg.Is($"Successfully saved file: {yamlFile} to cosmos db"));
        }
Beispiel #25
0
        public void DetectChanges_GivenNewTableDefinitionHasMultipleChanges_ReturnsModelWithChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field2", IsAggregable = false
                            },
                            new FieldDefinition {
                                Id = "456", Name = "field3", IsAggregable = false
                            },
                            new FieldDefinition {
                                Id = "789", Name = "field4", IsAggregable = false
                            }
                        }
                    }
                }
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field1", IsAggregable = true
                            },
                        }
                    }
                }
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .Should()
            .HaveCount(3);

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .Count(m => m.ChangeTypes.First() == FieldDefinitionChangeType.AddedField)
            .Should()
            .Be(2);

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .Count(m => m.ChangeTypes.First() == FieldDefinitionChangeType.FieldName)
            .Should()
            .Be(1);
        }
Beispiel #26
0
        public void DetectChanges_GivenNewTableDefinitionHasFieldTypeChange_ReturnsModelWithChanges()
        {
            //Arrange
            DatasetDefinition newDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field1", Type = FieldType.String
                            }
                        }
                    }
                }
            };

            DatasetDefinition existingDefinition = new DatasetDefinition
            {
                Name             = "name2",
                TableDefinitions = new List <TableDefinition>
                {
                    new TableDefinition {
                        Name = "name1", FieldDefinitions = new List <FieldDefinition> {
                            new FieldDefinition {
                                Id = "123", Name = "field1", Type = FieldType.Decimal
                            },
                        }
                    }
                }
            };

            DefinitionChangesDetectionService service = new DefinitionChangesDetectionService();

            //Act
            DatasetDefinitionChanges changes = service.DetectChanges(newDefinition, existingDefinition);

            //Assert
            changes
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .HasChanges
            .Should()
            .BeTrue();

            changes
            .TableDefinitionChanges
            .First()
            .FieldChanges
            .First()
            .ChangeTypes
            .First()
            .Should()
            .Be(FieldDefinitionChangeType.FieldType);
        }
Beispiel #27
0
        public async Task SaveDefinition_GivenValidYamlAndDoesContainsExistingItemWithNoModelUpdates_ThenDoesNotAddMessageToTopicAndReturnsOK()
        {
            //Arrange
            string yaml         = CreateRawDefinition();
            string definitionId = "9183";

            byte[]       byteArray = Encoding.UTF8.GetBytes(yaml);
            MemoryStream stream    = new MemoryStream(byteArray);

            IHeaderDictionary headerDictionary = new HeaderDictionary();

            headerDictionary
            .Add("yaml-file", new StringValues(yamlFile));

            HttpRequest request = Substitute.For <HttpRequest>();

            request
            .Headers
            .Returns(headerDictionary);

            request
            .Body
            .Returns(stream);

            ILogger logger = CreateLogger();

            HttpStatusCode statusCode = HttpStatusCode.Created;

            DatasetDefinition existingDatasetDefinition = new DatasetDefinition
            {
                Id = definitionId
            };

            IDatasetRepository datasetsRepository = CreateDataSetsRepository();

            datasetsRepository
            .SaveDefinition(Arg.Any <DatasetDefinition>())
            .Returns(statusCode);

            datasetsRepository
            .GetDatasetDefinition(Arg.Is(definitionId))
            .Returns(existingDatasetDefinition);

            byte[] excelAsBytes = new byte[100];

            IExcelWriter <DatasetDefinition> excelWriter = CreateExcelWriter();

            excelWriter
            .Write(Arg.Any <DatasetDefinition>())
            .Returns(excelAsBytes);

            ICloudBlob blob = Substitute.For <ICloudBlob>();

            IBlobClient blobClient = CreateBlobClient();

            blobClient
            .GetBlockBlobReference(Arg.Any <string>())
            .Returns(blob);

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges();

            IDefinitionChangesDetectionService definitionChangesDetectionService = CreateChangesDetectionService();

            definitionChangesDetectionService
            .DetectChanges(Arg.Any <DatasetDefinition>(), Arg.Is(existingDatasetDefinition))
            .Returns(datasetDefinitionChanges);

            IMessengerService messengerService = CreateMessengerService();

            DefinitionsService service = CreateDefinitionsService(
                logger,
                datasetsRepository,
                excelWriter: excelWriter,
                blobClient: blobClient,
                definitionChangesDetectionService: definitionChangesDetectionService,
                messengerService: messengerService);

            //Act
            IActionResult result = await service.SaveDefinition(request);

            //Assert
            result
            .Should()
            .BeOfType <OkResult>();

            await
            messengerService
            .DidNotReceive()
            .SendToTopic(
                Arg.Is(ServiceBusConstants.TopicNames.DataDefinitionChanges),
                Arg.Any <DatasetDefinitionChanges>(),
                Arg.Any <IDictionary <string, string> >());
        }
        public async Task ProcessChanges_GivenChangeModelWithAggregableFieldChangesButNoAggregateParanetersFound_DoesNotResetCalculationForFieldDefinitionChanges(FieldDefinitionChangeType fieldDefinitionChangeType)
        {
            //Arrange
            string definitionId    = "df-id-1";
            string specificationId = "spec-1";

            IEnumerable <Calculation> calculations = new[]
            {
                new Calculation
                {
                    Current = new CalculationVersion
                    {
                        SourceCode = "return 2 + Datasets.TestRelationship.TestField1"
                    }
                }
            };

            DatasetDefinitionChanges datasetDefinitionChanges = new DatasetDefinitionChanges
            {
                Id = definitionId,
            };

            FieldDefinitionChanges fieldDefinitionChanges = new FieldDefinitionChanges
            {
                FieldDefinition = new FieldDefinition
                {
                    Id = "field1"
                },
                ExistingFieldDefinition = new FieldDefinition {
                    Name = "test field 1"
                }
            };

            fieldDefinitionChanges.ChangeTypes.Add(fieldDefinitionChangeType);

            TableDefinitionChanges tableDefinitionChanges = new TableDefinitionChanges();

            tableDefinitionChanges.FieldChanges.Add(fieldDefinitionChanges);

            datasetDefinitionChanges.TableDefinitionChanges.Add(tableDefinitionChanges);

            string json = JsonConvert.SerializeObject(datasetDefinitionChanges);

            Message message = new Message(Encoding.UTF8.GetBytes(json));

            ILogger logger = CreateLogger();

            IEnumerable <string> relationshipSpecificationIds = new[] { specificationId };

            IEnumerable <DatasetSpecificationRelationshipViewModel> relationshipViewModels = new[]
            {
                new DatasetSpecificationRelationshipViewModel
                {
                    Name = "Test Relationship"
                }
            };

            IDatasetRepository datasetRepository = CreateDatasetRepository();

            datasetRepository
            .GetRelationshipSpecificationIdsByDatasetDefinitionId(Arg.Is(definitionId))
            .Returns(relationshipSpecificationIds);
            datasetRepository
            .GetCurrentRelationshipsBySpecificationIdAndDatasetDefinitionId(Arg.Is(specificationId), Arg.Is(definitionId))
            .Returns(relationshipViewModels);

            ICalculationService calculationService = CreateCalculationService();

            ICalculationsRepository calculationsRepository = CreateCalculationsRepository();

            calculationsRepository
            .GetCalculationsBySpecificationId(Arg.Is(specificationId))
            .Returns(calculations);

            DatasetDefinitionFieldChangesProcessor processor = CreateProcessor(
                logger: logger,
                datasetRepository: datasetRepository,
                calculationService: calculationService,
                calculationsRepository: calculationsRepository);

            //Act
            await processor.ProcessChanges(message);

            //Assert
            await
            calculationService
            .DidNotReceive()
            .ResetCalculationForFieldDefinitionChanges(Arg.Any <IEnumerable <DatasetSpecificationRelationshipViewModel> >(), Arg.Any <string>(), Arg.Any <IEnumerable <string> >());
        }