public async Task ValidateDataset_GivenViewModelButResponseIsBadRequest_ReturnsStatusCode400()
        {
            // Arrange
            ValidateDatasetModel viewModel = new ValidateDatasetModel();

            ValidatedApiResponse <DatasetValidationStatusModel> response = new ValidatedApiResponse <DatasetValidationStatusModel>(HttpStatusCode.BadRequest);

            response.ModelState = new Dictionary <string, IEnumerable <string> >();

            IDatasetsApiClient apiClient = CreateApiClient();

            apiClient
            .ValidateDataset(Arg.Is(viewModel))
            .Returns(response);

            ILogger logger = CreateLogger();

            DatasetController controller = CreateController(apiClient, logger);

            // Act
            IActionResult result = await controller.ValidateDataset(viewModel);

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

            logger
            .Received(1)
            .Warning(Arg.Is("Failed to validate dataset with status code: {statusCode}"), Arg.Is(HttpStatusCode.BadRequest));
        }
Ejemplo n.º 2
0
        async public Task <IActionResult> ValidateDataset([FromBody] ValidateDatasetModel vm)
        {
            Guard.ArgumentNotNull(vm, nameof(vm));

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            ValidatedApiResponse <DatasetValidationStatusModel> apiResponse = await _datasetApiClient.ValidateDataset(vm);

            if (apiResponse == null)
            {
                _logger.Warning("Validate Dataset API response was null");
                return(new InternalServerErrorResult("Validate Dataset API response was null"));
            }

            if (!apiResponse.StatusCode.IsSuccess())
            {
                _logger.Warning("Failed to validate dataset with status code: {statusCode}", apiResponse.StatusCode);

                if (apiResponse.StatusCode == HttpStatusCode.BadRequest && !apiResponse.ModelState.Values.IsNullOrEmpty())
                {
                    return(new BadRequestObjectResult(apiResponse.ModelState));
                }

                return(new InternalServerErrorResult("Validate Dataset API response failed with status code: {statusCode}" + apiResponse.StatusCode));
            }

            DatasetValidationStatusViewModel result = _mapper.Map <DatasetValidationStatusViewModel>(apiResponse.Content);

            return(new OkObjectResult(result));
        }
Ejemplo n.º 3
0
        public async Task <IActionResult> ValidateDataset([FromBody] ValidateDatasetModel vm)
        {
            Guard.ArgumentNotNull(vm, nameof(vm));

            FundingStreamPermission permissions = await _authorizationHelper.GetUserFundingStreamPermissions(User, vm.FundingStreamId);

            if (permissions?.CanUploadDataSourceFiles != true)
            {
                _logger.Error($"User [{User?.Identity?.Name}] has insufficient permissions to upload a dataset file for {vm.FundingStreamId}");
                return(Forbid(new AuthenticationProperties()));
            }

            if (!ModelState.IsValid)
            {
                return(BadRequest(ModelState));
            }

            ValidatedApiResponse <DatasetValidationStatusModel> apiResponse = await _datasetApiClient.ValidateDataset(
                new GetDatasetBlobModel
            {
                DatasetId            = vm.DatasetId,
                Version              = vm.Version,
                Filename             = vm.Filename,
                Description          = vm.Description,
                Comment              = vm.Comment,
                FundingStreamId      = vm.FundingStreamId,
                MergeExistingVersion = vm.MergeExistingVersion
            });

            if (apiResponse == null)
            {
                _logger.Warning("Validate Dataset API response was null");
                return(new InternalServerErrorResult("Validate Dataset API response was null"));
            }

            if (!apiResponse.StatusCode.IsSuccess())
            {
                _logger.Warning("Failed to validate dataset with status code: {statusCode}", apiResponse.StatusCode);

                if (apiResponse.IsBadRequest(out BadRequestObjectResult badRequest))
                {
                    return(badRequest);
                }

                return(new InternalServerErrorResult(
                           "Validate Dataset API response failed with status code: {statusCode}" + apiResponse.StatusCode));
            }

            DatasetValidationStatusViewModel
                result = _mapper.Map <DatasetValidationStatusViewModel>(apiResponse.Content);

            return(new OkObjectResult(result));
        }
Ejemplo n.º 4
0
        public async Task ValidateDataset_GivenViewModelAndResponseIsSuccess_ReturnsStatusModel()
        {
            string fundingStreamId = Guid.NewGuid().ToString();

            // Arrange
            ValidateDatasetModel viewModel = new ValidateDatasetModel
            {
                FundingStreamId = fundingStreamId
            };

            GivenTheUserHasPermissionToUploadDataSourceFilesForFundingStream(fundingStreamId, new FundingStreamPermission
            {
                CanUploadDataSourceFiles = true
            });

            DatasetValidationStatusModel statusModel = new DatasetValidationStatusModel
            {
                ValidationFailures = new Dictionary <string, IEnumerable <string> >(),
                CurrentOperation   = DatasetValidationStatus.Processing,
                DatasetId          = "datasetId",
                ErrorMessage       = "errorMessage",
                OperationId        = "operationId"
            };

            ValidatedApiResponse <DatasetValidationStatusModel> response = new ValidatedApiResponse <DatasetValidationStatusModel>(HttpStatusCode.OK, statusModel);

            DatasetValidationStatusViewModel resultViewModel = new DatasetValidationStatusViewModel
            {
                ValidationFailures = new Dictionary <string, IEnumerable <string> >(),
                CurrentOperation   = DatasetValidationStatusOperationViewModel.Processing,
                DatasetId          = "datasetId",
                ErrorMessage       = "errorMessage",
                OperationId        = "operationId"
            };

            _apiClient
            .ValidateDataset(Arg.Any <GetDatasetBlobModel>())
            .Returns(response);

            // Act
            IActionResult result = await _controller.ValidateDataset(viewModel);

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeEquivalentTo(resultViewModel);
        }
        public void ValidateDatasett_GivenViewModelIsNull_ThowsArgumentNullException()
        {
            // Arrange
            ValidateDatasetModel viewModel = null;

            DatasetController controller = CreateController();

            // Act
            Func <Task> test = async() => await controller.ValidateDataset(viewModel);

            // Assert
            test
            .Should()
            .ThrowExactly <ArgumentNullException>();
        }
        public async Task ValidateDataset_GivenViewModelAndResponseIsSuccess_ReturnsStatusModel()
        {
            // Arrange
            ValidateDatasetModel viewModel = new ValidateDatasetModel();


            DatasetValidationStatusModel statusModel = new DatasetValidationStatusModel()
            {
                ValidationFailures = new Dictionary <string, IEnumerable <string> >(),
                CurrentOperation   = DatasetValidationStatusOperation.Processing,
                DatasetId          = "datasetId",
                ErrorMessage       = "errorMessage",
                OperationId        = "operationId",
            };

            ValidatedApiResponse <DatasetValidationStatusModel> response = new ValidatedApiResponse <DatasetValidationStatusModel>(HttpStatusCode.OK, statusModel);

            DatasetValidationStatusViewModel resultViewModel = new DatasetValidationStatusViewModel()
            {
                ValidationFailures = new Dictionary <string, IEnumerable <string> >(),
                CurrentOperation   = DatasetValidationStatusOperationViewModel.Processing,
                DatasetId          = "datasetId",
                ErrorMessage       = "errorMessage",
                OperationId        = "operationId",
            };

            IDatasetsApiClient apiClient = CreateApiClient();

            apiClient
            .ValidateDataset(Arg.Is(viewModel))
            .Returns(response);

            ILogger logger = CreateLogger();

            DatasetController controller = CreateController(apiClient, logger);

            // Act
            IActionResult result = await controller.ValidateDataset(viewModel);

            // Assert
            result
            .Should()
            .BeOfType <OkObjectResult>()
            .Which
            .Value
            .Should()
            .BeEquivalentTo(resultViewModel);
        }
Ejemplo n.º 7
0
        public async Task ValidateDataset_GivenViewModelButResponseIsBadRequestAndHasModelState_ReturnsBadRequestObjectResult()
        {
            string fundingStreamId = Guid.NewGuid().ToString();

            // Arrange
            ValidateDatasetModel viewModel = new ValidateDatasetModel
            {
                FundingStreamId = fundingStreamId
            };

            GivenTheUserHasPermissionToUploadDataSourceFilesForFundingStream(fundingStreamId, new FundingStreamPermission
            {
                CanUploadDataSourceFiles = true
            });

            IDictionary <string, IEnumerable <string> > modelState = new Dictionary <string, IEnumerable <string> >();

            modelState.Add("error",
                           new List <string>
            {
                "an error occured"
            });

            ValidatedApiResponse <DatasetValidationStatusModel> response = new ValidatedApiResponse <DatasetValidationStatusModel>(HttpStatusCode.BadRequest)
            {
                ModelState = modelState
            };

            _apiClient
            .ValidateDataset(Arg.Any <GetDatasetBlobModel>())
            .Returns(response);

            // Act
            IActionResult result = await _controller.ValidateDataset(viewModel);

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

            _logger
            .Received(1)
            .Warning(Arg.Is("Failed to validate dataset with status code: {statusCode}"), Arg.Is(HttpStatusCode.BadRequest));
        }
Ejemplo n.º 8
0
        public Task <ValidatedApiResponse <DatasetValidationStatusModel> > ValidateDataset(ValidateDatasetModel model)
        {
            Guard.ArgumentNotNull(model, nameof(model));

            return(ValidatedPostAsync <DatasetValidationStatusModel, ValidateDatasetModel>("validate-dataset", model, timeout: TimeSpan.FromSeconds(300)));
        }
Ejemplo n.º 9
0
        private async Task GenerateDataset(Specification specification, SpecGeneratorConfiguration configuration)
        {
            if (!string.IsNullOrWhiteSpace(configuration.DatasetDefinitionId) && !string.IsNullOrWhiteSpace(configuration.DatasetFilePath))
            {
                _logger.Information("Looking up Dataset with ID {DatasetDefinitionId}", configuration.DatasetDefinitionId);

                ApiResponse <DatasetDefinition> datasetDefinitionResponse = await _datasetsClient.GetDatasetDefinitionById(configuration.DatasetDefinitionId);

                if (datasetDefinitionResponse.StatusCode != HttpStatusCode.OK)
                {
                    _logger.Error("Unable to lookup Dataset Definition with ID {DatasetDefinitionId}", configuration.DatasetDefinitionId);
                    return;
                }

                _logger.Information("Found Dataset Definition '{Name}'", datasetDefinitionResponse.Content.Name);

                string filename = Path.GetFileName(configuration.DatasetFilePath);

                CreateNewDatasetModel createNewDatasetModel = new CreateNewDatasetModel()
                {
                    DefinitionId = datasetDefinitionResponse.Content.Id,
                    Description  = $"{configuration.SpecificationName} ({datasetDefinitionResponse.Content.Id})",
                    Name         = $"{configuration.SpecificationName} ({datasetDefinitionResponse.Content.Name})",
                    Filename     = filename,
                };

                _logger.Information("Creating data source with excel spreadsheet located at {DatasetFilePath}", configuration.DatasetFilePath);
                ValidatedApiResponse <NewDatasetVersionResponseModel> datasetVersionResponse = await this._datasetsClient.CreateDataset(createNewDatasetModel);

                if (datasetDefinitionResponse.StatusCode != System.Net.HttpStatusCode.OK && datasetDefinitionResponse.StatusCode != System.Net.HttpStatusCode.Created)
                {
                    _logger.Error("Unable to create data source {Content}", datasetDefinitionResponse.Content);
                    return;
                }

                // Upload file to blob storage - headers should match the TypeScript attributes to set the metadata on the blob
                using (HttpClient httpClient = new HttpClient())
                {
                    using (StreamReader sr = new StreamReader(configuration.DatasetFilePath))
                    {
                        using (StreamContent sc = new StreamContent(sr.BaseStream))
                        {
                            sc.Headers.Add("x-ms-blob-type", "BlockBlob");
                            sc.Headers.Add("x-ms-meta-dataDefinitionId", datasetVersionResponse.Content.DefinitionId);
                            sc.Headers.Add("x-ms-meta-datasetId", datasetVersionResponse.Content.DatasetId);
                            sc.Headers.Add("x-ms-meta-authorName", "Spec Generator");
                            sc.Headers.Add("x-ms-meta-authorId", "specGenerator");
                            sc.Headers.Add("x-ms-meta-filename", filename);
                            sc.Headers.Add("x-ms-meta-name", datasetVersionResponse.Content.Name);
                            sc.Headers.Add("x-ms-meta-description", datasetVersionResponse.Content.Description);

                            HttpResponseMessage fileUploadResponse = await httpClient.PutAsync(datasetVersionResponse.Content.BlobUrl, sc);

                            if (!fileUploadResponse.IsSuccessStatusCode)
                            {
                                _logger.Error("Invalid response received on data source upload {ReasonPhrase}", fileUploadResponse.ReasonPhrase);
                                return;
                            }
                            else
                            {
                                _logger.Information("Uploaded data source file to blob storage {filename}", filename);
                            }
                        }
                    }
                }

                ValidateDatasetModel validateDatasetModel = new ValidateDatasetModel()
                {
                    Comment     = "SpecGenerator",
                    DatasetId   = datasetVersionResponse.Content.DatasetId,
                    Description = "Spec Generator",
                    Filename    = filename,
                    Version     = 1,
                };

                _logger.Information("Validating data source");

                ValidatedApiResponse <DatasetValidationStatusModel> apiResponse = await _datasetsClient.ValidateDataset(validateDatasetModel);

                if (apiResponse.ModelState != null && apiResponse.ModelState.Any())
                {
                    _logger.Error("Dataset validation errors");
                    foreach (var error in apiResponse.ModelState)
                    {
                        _logger.Error("Field Key: {Key}", error.Key);
                        foreach (var errorItem in error.Value)
                        {
                            _logger.Error("Message: {errorItem}", errorItem);
                        }
                    }
                    return;
                }
                else if (apiResponse.Content != null)
                {
                    if (!string.IsNullOrWhiteSpace(apiResponse.Content.ErrorMessage))
                    {
                        _logger.Error("Data source validation failed with message: '{Message}'", apiResponse.Content.ErrorMessage);
                        return;
                    }
                }
                else
                {
                    _logger.Error("Data source validation failed with null response");
                    return;
                }


                // Check status
                int validationChecks = 0;
                while (validationChecks < 1000)
                {
                    ApiResponse <DatasetValidationStatusModel> validationStatusResponse = await _datasetsClient.GetDatasetValidateStatus(apiResponse.Content.OperationId);

                    if (validationStatusResponse.StatusCode == HttpStatusCode.OK)
                    {
                        _logger.Information("Validation status: {CurrentOperation}", validationStatusResponse.Content.CurrentOperation);

                        if (validationStatusResponse.Content.CurrentOperation == DatasetValidationStatus.Validated)
                        {
                            break;
                        }
                        else if (validationStatusResponse.Content.CurrentOperation == DatasetValidationStatus.FailedValidation)
                        {
                            _logger.Error("Validation error:", validationStatusResponse.Content.ErrorMessage);
                            return;
                        }
                    }
                    else
                    {
                        _logger.Warning("Validation response returned {StatusCode}, expected OK", validationStatusResponse.StatusCode);
                    }

                    validationChecks++;
                    Thread.Sleep(2000);
                }



                AssignDatasetSchemaModel assignDatasetSchemaModel = new AssignDatasetSchemaModel()
                {
                    DatasetDefinitionId = datasetDefinitionResponse.Content.Id,
                    Description         = $"SpecGenerator - Provider Dataset",
                    IsSetAsProviderData = true,
                    Name                   = "Provider Dataset",
                    SpecificationId        = specification.Id,
                    UsedInDataAggregations = false,
                };

                HttpStatusCode assignStatusCode = await _datasetsClient.AssignDatasetSchema(assignDatasetSchemaModel);

                _logger.Information("Creating Data Source '{Name}' for providers on specification", assignDatasetSchemaModel.Name);

                ApiResponse <IEnumerable <DatasetSchemasAssigned> > datasetSchemasAssignedResponse = await _datasetsClient.GetAssignedDatasetSchemasForSpecification(specification.Id);

                DatasetSchemasAssigned assignedSchema = datasetSchemasAssignedResponse.Content.First();


                AssignDatasetVersion assignDatasetVersion = new AssignDatasetVersion()
                {
                    DatasetId      = datasetVersionResponse.Content.DatasetId,
                    RelationshipId = assignedSchema.Id,
                    Version        = 1,
                };

                _logger.Information("Assigning uploaded data source to specification");

                HttpStatusCode assignStatusVersionToSpecCode = await _datasetsClient.AssignDataSourceVersionToRelationship(assignDatasetVersion);
            }
        }