Esempio n. 1
0
        public async Task <IActionResult> GetJobById(string jobId, bool includeChildJobs)
        {
            Guard.IsNullOrWhiteSpace(jobId, nameof(jobId));

            Job job = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.GetJobById(jobId));

            if (job == null)
            {
                return(new NotFoundResult());
            }

            JobViewModel jobViewModel = _mapper.Map <JobViewModel>(job);

            IEnumerable <Job> childJobs = _jobsRepositoryNonAsyncPolicy.Execute(() => _jobRepository.GetChildJobsForParent(jobId));

            if (!childJobs.IsNullOrEmpty())
            {
                foreach (Job childJob in childJobs)
                {
                    jobViewModel.ChildJobs.Add(_mapper.Map <JobViewModel>(childJob));
                }
            }

            return(new OkObjectResult(jobViewModel));
        }
        public async Task <IActionResult> SaveDefinition(HttpRequest request)
        {
            string json = await request.GetRawBodyStringAsync();

            string jsonFilename = request.GetJsonFileNameFromRequest();

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

            JobDefinition definition = null;

            try
            {
                definition = JsonConvert.DeserializeObject <JobDefinition>(json);
            }
            catch (Exception exception)
            {
                _logger.Error(exception, $"Invalid json was provided for file: {jsonFilename}");
                return(new BadRequestObjectResult($"Invalid json was provided for file: {jsonFilename}"));
            }

            try
            {
                HttpStatusCode result = await _jobDefinitionsRepositoryPolicy.ExecuteAsync(() => _jobDefinitionsRepository.SaveJobDefinition(definition));

                if (!result.IsSuccess())
                {
                    int statusCode = (int)result;

                    _logger.Error($"Failed to save json file: {jsonFilename} to cosmos db with status {statusCode}");

                    return(new StatusCodeResult(statusCode));
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception, $"Exception occurred writing json file: {jsonFilename} to cosmos db");

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

            await _cachePolicy.ExecuteAsync(() => _cacheProvider.RemoveAsync <List <JobDefinition> >(CacheKeys.JobDefinitions));

            return(new NoContentResult());
        }
Esempio n. 3
0
        public async Task GenerateCalculationResultsCsv(Message message)
        {
            string specificationId = message.GetUserProperty <string>("specification-id");

            if (specificationId == null)
            {
                string error = "Specification id missing";

                _logger.Error(error);
                throw new NonRetriableException(error);
            }

            IEnumerable <ProviderResult> results = await ProviderResultsBySpecificationId(specificationId);

            IEnumerable <ExpandoObject> resultsForOutput = ProcessProviderResultsForCsvOutput(results).ToList();

            string csv = new CsvUtils().CreateCsvExpando(resultsForOutput);

            ICloudBlob blob = _blobClient.GetBlockBlobReference($"calculation-results-{specificationId}.csv");

            using (MemoryStream memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(csv)))
            {
                await _blobClientPolicy.ExecuteAsync(() => blob.UploadFromStreamAsync(memoryStream));
            }
        }
Esempio n. 4
0
        public async Task <IActionResult> HasCalculationResults(string calculationId)
        {
            Guard.IsNullOrWhiteSpace(calculationId, nameof(calculationId));

            Models.Calcs.Calculation calculation = await _calculationsRepositoryPolicy.ExecuteAsync(() => _calculationRepository.GetCalculationById(calculationId));

            if (calculation == null)
            {
                _logger.Error($"Calculation could not be found for calculation id '{calculationId}'");

                return(new NotFoundObjectResult($"Calculation could not be found for calculation id '{calculationId}'"));
            }

            ProviderResult providerResult = await _resultsRepositoryPolicy.ExecuteAsync(() => _resultsRepository.GetSingleProviderResultBySpecificationId(calculation.SpecificationId));

            if (providerResult != null)
            {
                CalculationResult calculationResult = providerResult.CalculationResults?.FirstOrDefault(m => string.Equals(m.Calculation.Id, calculationId, StringComparison.InvariantCultureIgnoreCase));

                if (calculationResult != null)
                {
                    return(new OkObjectResult(true));
                }
            }

            return(new OkObjectResult(false));
        }
Esempio n. 5
0
        private async Task <Job> CreateJob(JobCreateModel job)
        {
            Job newJob = new Job()
            {
                JobDefinitionId        = job.JobDefinitionId,
                InvokerUserId          = job.InvokerUserId,
                InvokerUserDisplayName = job.InvokerUserDisplayName,
                ItemCount       = job.ItemCount,
                SpecificationId = job.SpecificationId,
                Trigger         = job.Trigger,
                ParentJobId     = job.ParentJobId,
                CorrelationId   = job.CorrelationId,
                Properties      = job.Properties,
                MessageBody     = job.MessageBody
            };

            Job newJobResult = null;

            try
            {
                newJobResult = await _jobDefinitionsRepositoryPolicy.ExecuteAsync(() => _jobRepository.CreateJob(newJob));
            }
            catch (Exception ex)
            {
                _logger.Error(ex, $"Failed to save new job with definition id {job.JobDefinitionId}");
            }

            return(newJobResult);
        }
        public async Task <SearchFeed <AllocationNotificationFeedIndex> > GetFeeds(int pageRef, int top = 500, IEnumerable <string> statuses = null)
        {
            if (pageRef < 1)
            {
                throw new ArgumentException("Page ref cannot be less than one", nameof(pageRef));
            }

            if (top < 1)
            {
                top = 500;
            }

            int skip = (pageRef - 1) * top;

            IList <string> filter = new List <string>();

            if (!statuses.IsNullOrEmpty())
            {
                if (!statuses.Contains("All"))
                {
                    foreach (string status in statuses)
                    {
                        filter.Add($"allocationStatus eq '{status}'");
                    }
                }
            }

            SearchResults <AllocationNotificationFeedIndex> searchResults = await _allocationNotificationsSearchRepositoryPolicy.ExecuteAsync(
                () => _allocationNotificationsSearchRepository.Search("", new SearchParameters
            {
                Skip       = skip,
                Top        = top,
                SearchMode = Microsoft.Azure.Search.Models.SearchMode.Any,
                IncludeTotalResultCount = true,
                Filter    = filter.IsNullOrEmpty() ? "" : string.Join(" or ", filter),
                OrderBy   = DefaultOrderBy.ToList(),
                QueryType = QueryType.Full
            }));

            return(new SearchFeed <AllocationNotificationFeedIndex>
            {
                PageRef = pageRef,
                Top = top,
                TotalCount = searchResults != null && searchResults.TotalCount.HasValue ? (int)searchResults?.TotalCount : 0,
                Entries = searchResults?.Results.Select(m => m.Result)
            });
        }
        private async Task <BuildProject> GenerateBuildProject(string specificationId)
        {
            BuildProject buildproject = new BuildProject
            {
                SpecificationId = specificationId,
                Id   = Guid.NewGuid().ToString(),
                Name = specificationId,
                DatasetRelationships = new List <DatasetRelationshipSummary>(),
                Build = new Build()
            };

            IEnumerable <DatasetSpecificationRelationshipViewModel> datasetRelationshipModels = await _datasetRepositoryPolicy.ExecuteAsync(() => _datasetRepository.GetCurrentRelationshipsBySpecificationId(specificationId));

            if (!datasetRelationshipModels.IsNullOrEmpty())
            {
                ConcurrentBag <DatasetDefinition> datasetDefinitions = new ConcurrentBag <DatasetDefinition>();

                IList <Task> definitionTasks = new List <Task>();

                IEnumerable <string> definitionIds = datasetRelationshipModels.Select(m => m.Definition?.Id);

                foreach (string definitionId in definitionIds)
                {
                    Task task = Task.Run(async() =>
                    {
                        DatasetDefinition datasetDefinition = await _datasetRepositoryPolicy.ExecuteAsync(() => _datasetRepository.GetDatasetDefinitionById(definitionId));

                        if (datasetDefinition != null)
                        {
                            datasetDefinitions.Add(datasetDefinition);
                        }
                    });

                    definitionTasks.Add(task);
                }

                await TaskHelper.WhenAllAndThrow(definitionTasks.ToArray());

                foreach (DatasetSpecificationRelationshipViewModel datasetRelationshipModel in datasetRelationshipModels)
                {
                    buildproject.DatasetRelationships.Add(new DatasetRelationshipSummary
                    {
                        DatasetDefinitionId = datasetRelationshipModel.Definition.Id,
                        DatasetId           = datasetRelationshipModel.DatasetId,
                        Relationship        = new Common.Models.Reference(datasetRelationshipModel.Id, datasetRelationshipModel.Name),
                        DefinesScope        = datasetRelationshipModel.IsProviderData,
                        Id   = datasetRelationshipModel.Id,
                        Name = datasetRelationshipModel.Name,
                        DatasetDefinition = datasetDefinitions.FirstOrDefault(m => m.Id == datasetRelationshipModel.Definition.Id)
                    });
                }
            }

            return(buildproject);
        }
Esempio n. 8
0
        public async Task ResetScenarioForFieldDefinitionChanges(IEnumerable <DatasetSpecificationRelationshipViewModel> relationships, string specificationId, IEnumerable <string> currentFieldDefinitionNames)
        {
            Guard.ArgumentNotNull(relationships, nameof(relationships));
            Guard.IsNullOrWhiteSpace(specificationId, nameof(specificationId));
            Guard.ArgumentNotNull(currentFieldDefinitionNames, nameof(currentFieldDefinitionNames));

            IEnumerable <TestScenario> scenarios = await _scenariosRepositoryPolicy.ExecuteAsync(() => _scenariosRepository.GetTestScenariosBySpecificationId(specificationId));

            if (scenarios.IsNullOrEmpty())
            {
                _logger.Information($"No scenarios found for specification id '{specificationId}'");
                return;
            }

            List <string> fieldIdentifiers = new List <string>();

            foreach (DatasetSpecificationRelationshipViewModel datasetSpecificationRelationshipViewModel in relationships)
            {
                fieldIdentifiers.AddRange(currentFieldDefinitionNames.Select(m => $"dataset {datasetSpecificationRelationshipViewModel.Name} field {VisualBasicTypeGenerator.GenerateIdentifier(m)}"));
            }

            IEnumerable <TestScenario> scenariosToUpdate = scenarios.Where(m => SourceCodeHelpers.CodeContainsFullyQualifiedDatasetFieldIdentifier(m.Current.Gherkin.RemoveAllQuotes(), fieldIdentifiers));

            if (scenariosToUpdate.IsNullOrEmpty())
            {
                _logger.Information($"No test scenarios required resetting for specification id '{specificationId}'");
                return;
            }

            const string reasonForCommenting = "The dataset definition referenced by this scenario/spec has been updated and subsequently the code has been commented out";

            foreach (TestScenario scenario in scenariosToUpdate)
            {
                string gherkin = scenario.Current.Gherkin;

                string updatedGherkin = SourceCodeHelpers.CommentOutCode(gherkin, reasonForCommenting, commentSymbol: "#");

                await SaveVersion(scenario, updatedGherkin);
            }
        }
        public async Task <IActionResult> UpdateBuildProjectRelationships(HttpRequest request)
        {
            request.Query.TryGetValue("specificationId", out Microsoft.Extensions.Primitives.StringValues specId);

            string specificationId = specId.FirstOrDefault();

            if (string.IsNullOrWhiteSpace(specificationId))
            {
                _logger.Error("No specification Id was provided to UpdateBuildProjectRelationships");

                return(new BadRequestObjectResult("Null or empty specification Id provided"));
            }

            string json = await request.GetRawBodyStringAsync();

            DatasetRelationshipSummary relationship = JsonConvert.DeserializeObject <DatasetRelationshipSummary>(json);

            if (relationship == null)
            {
                _logger.Error("A null relationship message was provided to UpdateBuildProjectRelationships");

                return(new BadRequestObjectResult("Null relationship provided"));
            }

            BuildProject buildProject = await GetBuildProjectForSpecificationId(specificationId);

            IEnumerable <Models.Calcs.Calculation> calculations = await _calculationsRepository.GetCalculationsBySpecificationId(specificationId);

            buildProject.Build = _sourceCodeService.Compile(buildProject, calculations ?? Enumerable.Empty <Models.Calcs.Calculation>());

            if (!_featureToggle.IsDynamicBuildProjectEnabled())
            {
                await _buildProjectsRepositoryPolicy.ExecuteAsync(() => _buildProjectsRepository.UpdateBuildProject(buildProject));
            }

            await _sourceCodeService.SaveAssembly(buildProject);

            return(new OkObjectResult(buildProject));
        }
        public async Task OnSpecificationUpdate(Message message)
        {
            SpecificationVersionComparisonModel versionComparison = message.GetPayloadAsInstanceOf <SpecificationVersionComparisonModel>();

            if (versionComparison == null || versionComparison.Current == null || versionComparison.Previous == null)
            {
                _logger.Error($"A null versionComparison was provided to users {nameof(OnSpecificationUpdate)}");

                throw new InvalidModelException(nameof(SpecificationVersionComparisonModel), new[] { "Null or invalid model provided" });
            }

            string specificationId = versionComparison.Id;

            if (string.IsNullOrWhiteSpace(specificationId))
            {
                _logger.Error($"A null specificationId was provided to users {nameof(OnSpecificationUpdate)} in model");

                throw new InvalidModelException(nameof(SpecificationVersionComparisonModel), new[] { "Null or invalid specificationId on model" });
            }

            IEnumerable <string> previousFundingStreams = versionComparison.Previous.FundingStreams.OrderBy(c => c.Id).Select(f => f.Id);
            IEnumerable <string> currentFundingStreams  = versionComparison.Current.FundingStreams.OrderBy(c => c.Id).Select(f => f.Id);

            if (!previousFundingStreams.SequenceEqual(currentFundingStreams))
            {
                _logger.Information("Found changed funding streams for specification '{SpecificationId}' Previous: {PreviousFundingStreams} Current {CurrentFundingStreams}", specificationId, previousFundingStreams, currentFundingStreams);

                Dictionary <string, bool> userIds = new Dictionary <string, bool>();

                IEnumerable <string> allFundingStreamIds = previousFundingStreams.Union(currentFundingStreams);

                foreach (string fundingStreamId in allFundingStreamIds)
                {
                    IEnumerable <FundingStreamPermission> userPermissions = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetUsersWithFundingStreamPermissions(fundingStreamId));

                    foreach (FundingStreamPermission permission in userPermissions)
                    {
                        if (!userIds.ContainsKey(permission.UserId))
                        {
                            userIds.Add(permission.UserId, true);
                        }
                    }
                }

                foreach (string userId in userIds.Keys)
                {
                    _logger.Information("Clearing effective permissions for userId '{UserId}' for specification '{SpecificationId}'", userId, specificationId);
                    await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.DeleteHashKey <EffectiveSpecificationPermission>($"{CacheKeys.EffectivePermissions}:{userId}", specificationId));
                }
            }
            else
            {
                _logger.Information("No funding streams have changed for specification '{SpecificationId}' which require effective permission clearing.", specificationId);
            }
        }
        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);
        }
Esempio n. 12
0
        private async Task <Job> SendInstructAllocationsToJobService(string specificationId, Reference user, Trigger trigger, string correlationId, bool generateAggregations = false)
        {
            JobCreateModel job = new JobCreateModel
            {
                InvokerUserDisplayName = user.Name,
                InvokerUserId          = user.Id,
                JobDefinitionId        = generateAggregations ? JobConstants.DefinitionNames.CreateInstructGenerateAggregationsAllocationJob : JobConstants.DefinitionNames.CreateInstructAllocationJob,
                SpecificationId        = specificationId,
                Properties             = new Dictionary <string, string>
                {
                    { "specification-id", specificationId },
                    { "ignore-save-provider-results", "true" }
                },
                Trigger       = trigger,
                CorrelationId = correlationId
            };

            return(await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.CreateJob(job)));
        }
        public async Task <IActionResult> GetFundingStreamPermissionsForUser(string userId, HttpRequest request)
        {
            if (string.IsNullOrWhiteSpace(userId))
            {
                return(new BadRequestObjectResult($"{nameof(userId)} is null or empty"));
            }

            List <FundingStreamPermissionCurrent> results = new List <FundingStreamPermissionCurrent>();

            IEnumerable <FundingStreamPermission> permissions = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetFundingStreamPermissions(userId));

            if (permissions.AnyWithNullCheck())
            {
                foreach (FundingStreamPermission permission in permissions)
                {
                    results.Add(_mapper.Map <FundingStreamPermissionCurrent>(permission));
                }
            }

            return(new OkObjectResult(results));
        }
        public async Task <IActionResult> AssignDatasourceVersionToRelationship(HttpRequest request)
        {
            string json = await request.GetRawBodyStringAsync();

            AssignDatasourceModel model = JsonConvert.DeserializeObject <AssignDatasourceModel>(json);

            if (model == null)
            {
                _logger.Error("Null AssignDatasourceModel was provided to AssignDatasourceVersionToRelationship");
                return(new BadRequestObjectResult("Null AssignDatasourceModel was provided"));
            }

            Dataset dataset = await _datasetRepository.GetDatasetByDatasetId(model.DatasetId);

            if (dataset == null)
            {
                _logger.Error($"Dataset not found for dataset id: {model.DatasetId}");
                return(new StatusCodeResult(412));
            }

            DefinitionSpecificationRelationship relationship = await _datasetRepository.GetDefinitionSpecificationRelationshipById(model.RelationshipId);

            if (relationship == null)
            {
                _logger.Error($"Relationship not found for relationship id: {model.RelationshipId}");
                return(new StatusCodeResult(412));
            }

            relationship.DatasetVersion = new DatasetRelationshipVersion
            {
                Id      = model.DatasetId,
                Version = model.Version
            };

            HttpStatusCode statusCode = await _datasetRepository.UpdateDefinitionSpecificationRelationship(relationship);

            if (!statusCode.IsSuccess())
            {
                _logger.Error($"Failed to assign data source to relationship : {model.RelationshipId} with status code {statusCode.ToString()}");

                return(new StatusCodeResult((int)statusCode));
            }

            Reference user = request.GetUser();

            Trigger trigger = new Trigger
            {
                EntityId   = dataset.Id,
                EntityType = nameof(Dataset),
                Message    = $"Mapping dataset: '{dataset.Id}'"
            };

            string correlationId = request.GetCorrelationId();

            JobCreateModel job = new JobCreateModel
            {
                InvokerUserDisplayName = user.Name,
                InvokerUserId          = user.Id,
                JobDefinitionId        = JobConstants.DefinitionNames.MapDatasetJob,
                MessageBody            = JsonConvert.SerializeObject(dataset),
                Properties             = new Dictionary <string, string>
                {
                    { "specification-id", relationship.Specification.Id },
                    { "relationship-id", relationship.Id }
                },
                SpecificationId = relationship.Specification.Id,
                Trigger         = trigger,
                CorrelationId   = correlationId
            };

            await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.CreateJob(job));

            return(new NoContentResult());
        }
Esempio n. 15
0
        public async Task ProcessDeadLetteredMessage(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            if (!message.UserProperties.ContainsKey("jobId"))
            {
                _logger.Error("Missing job id from dead lettered message");
                return;
            }

            string jobId = message.UserProperties["jobId"].ToString();

            Common.ApiClient.Jobs.Models.JobLogUpdateModel jobLogUpdateModel = new Common.ApiClient.Jobs.Models.JobLogUpdateModel
            {
                CompletedSuccessfully = false,
                Outcome = $"The job has exceeded its maximum retry count and failed to complete successfully"
            };

            try
            {
                ApiResponse <Common.ApiClient.Jobs.Models.JobLog> jobLogResponse = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, jobLogUpdateModel));

                if (jobLogResponse == null || jobLogResponse.Content == null)
                {
                    _logger.Error($"Failed to add a job log for job id '{jobId}'");
                }
                else
                {
                    _logger.Information($"A new job log was added to inform of a dead lettered message with job log id '{jobLogResponse.Content.Id}' on job with id '{jobId}'");
                }
            }
            catch (Exception exception)
            {
                _logger.Error(exception, $"Failed to add a job log for job id '{jobId}'");
            }
        }
Esempio n. 16
0
        public async Task <IActionResult> SaveVersion(HttpRequest request)
        {
            string json = await request.GetRawBodyStringAsync();

            CreateNewTestScenarioVersion scenarioVersion = JsonConvert.DeserializeObject <CreateNewTestScenarioVersion>(json);

            if (scenarioVersion == null)
            {
                _logger.Error("A null scenario version was provided");

                return(new BadRequestObjectResult("Null or empty calculation Id provided"));
            }

            BadRequestObjectResult validationResult = (await _createNewTestScenarioVersionValidator.ValidateAsync(scenarioVersion)).PopulateModelState();

            if (validationResult != null)
            {
                return(validationResult);
            }

            TestScenario testScenario = null;

            if (!string.IsNullOrEmpty(scenarioVersion.Id))
            {
                testScenario = await _scenariosRepository.GetTestScenarioById(scenarioVersion.Id);
            }

            bool saveAsVersion = true;

            SpecificationSummary specification = await _specificationsRepository.GetSpecificationSummaryById(scenarioVersion.SpecificationId);

            if (specification == null)
            {
                _logger.Error($"Unable to find a specification for specification id : {scenarioVersion.SpecificationId}");

                return(new StatusCodeResult(412));
            }

            Reference user = request.GetUserOrDefault();

            if (testScenario == null)
            {
                string Id = Guid.NewGuid().ToString();

                testScenario = new TestScenario
                {
                    Id = Id,
                    SpecificationId = specification.Id,
                    Name            = scenarioVersion.Name,
                    Current         = new TestScenarioVersion
                    {
                        Date             = DateTimeOffset.Now.ToLocalTime(),
                        TestScenarioId   = Id,
                        PublishStatus    = PublishStatus.Draft,
                        Version          = 1,
                        Author           = user,
                        Gherkin          = scenarioVersion.Scenario,
                        Description      = scenarioVersion.Description,
                        FundingPeriodId  = specification.FundingPeriod.Id,
                        FundingStreamIds = specification.FundingStreams.Select(s => s.Id).ToArraySafe(),
                    }
                };
            }
            else
            {
                testScenario.Name = scenarioVersion.Name;

                saveAsVersion = !string.Equals(scenarioVersion.Scenario, testScenario.Current.Gherkin) ||
                                scenarioVersion.Description != testScenario.Current.Description;

                TestScenarioVersion newVersion = testScenario.Current.Clone() as TestScenarioVersion;

                if (saveAsVersion == true)
                {
                    newVersion.Author           = user;
                    newVersion.Gherkin          = scenarioVersion.Scenario;
                    newVersion.Description      = scenarioVersion.Description;
                    newVersion.FundingStreamIds = specification.FundingStreams.Select(s => s.Id).ToArraySafe();
                    newVersion.FundingPeriodId  = specification.FundingPeriod.Id;

                    newVersion = await _versionRepository.CreateVersion(newVersion, testScenario.Current);

                    testScenario.Current = newVersion;
                }
            }

            HttpStatusCode statusCode = await _scenariosRepository.SaveTestScenario(testScenario);

            if (!statusCode.IsSuccess())
            {
                _logger.Error($"Failed to save test scenario with status code: {statusCode.ToString()}");

                return(new StatusCodeResult((int)statusCode));
            }

            await _versionRepository.SaveVersion(testScenario.Current);

            ScenarioIndex scenarioIndex = CreateScenarioIndexFromScenario(testScenario, specification);

            await _searchRepository.Index(new List <ScenarioIndex> {
                scenarioIndex
            });

            await _cacheProvider.RemoveAsync <List <TestScenario> >($"{CacheKeys.TestScenarios}{testScenario.SpecificationId}");

            await _cacheProvider.RemoveAsync <GherkinParseResult>($"{CacheKeys.GherkinParseResult}{testScenario.Id}");

            IEnumerable <Models.Calcs.CalculationCurrentVersion> calculations = await _calcsRepositoryPolicy.ExecuteAsync(() => _calcsRepository.GetCurrentCalculationsBySpecificationId(specification.Id));

            if (calculations.IsNullOrEmpty())
            {
                _logger.Information($"No calculations found to test for specification id: '{specification.Id}'");
            }
            else
            {
                string correlationId = request.GetCorrelationId();

                try
                {
                    Trigger trigger = new Trigger
                    {
                        EntityId   = testScenario.Id,
                        EntityType = nameof(TestScenario),
                        Message    = $"Saving test scenario: '{testScenario.Id}'"
                    };

                    bool generateCalculationAggregations = SourceCodeHelpers.HasCalculationAggregateFunctionParameters(calculations.Select(m => m.SourceCode));

                    Job job = await SendInstructAllocationsToJobService(specification.Id, user, trigger, correlationId, generateCalculationAggregations);

                    _logger.Information($"New job of type '{job.JobDefinitionId}' created with id: '{job.Id}'");
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, $"Failed to create job of type '{JobConstants.DefinitionNames.CreateInstructAllocationJob}' on specification '{specification.Id}'");

                    return(new InternalServerErrorResult($"An error occurred attempting to execute calculations prior to running tests on specification '{specification.Id}'"));
                }
            }

            CurrentTestScenario testScenarioResult = await _scenariosRepository.GetCurrentTestScenarioById(testScenario.Id);

            return(new OkObjectResult(testScenarioResult));
        }
Esempio n. 17
0
        public async Task ReIndexCalculationResults(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            Reference user = message.GetUserDetails();

            _logger.Information($"{nameof(ReIndexCalculationResults)} initiated by: '{user.Name}'");

            IEnumerable <SpecificationSummary> specifications = await _specificationsRepositoryPolicy.ExecuteAsync(() => _specificationsRepository.GetSpecificationSummaries());

            foreach (SpecificationSummary specification in specifications)
            {
                await _resultsRepositoryPolicy.ExecuteAsync(() => _resultsRepository.ProviderResultsBatchProcessing(specification.Id, async(x) => {
                    IList <ProviderCalculationResultsIndex> results = new List <ProviderCalculationResultsIndex>();

                    foreach (ProviderResult providerResult in x)
                    {
                        if (!providerResult.CalculationResults.IsNullOrEmpty())
                        {
                            ProviderCalculationResultsIndex calculationResult = new ProviderCalculationResultsIndex
                            {
                                SpecificationId   = providerResult.SpecificationId,
                                SpecificationName = specification?.Name,
                                ProviderId        = providerResult.Provider?.Id,
                                ProviderName      = providerResult.Provider?.Name,
                                ProviderType      = providerResult.Provider?.ProviderType,
                                ProviderSubType   = providerResult.Provider?.ProviderSubType,
                                LocalAuthority    = providerResult.Provider?.Authority,
                                LastUpdatedDate   = providerResult.CreatedAt,
                                UKPRN             = providerResult.Provider?.UKPRN,
                                URN  = providerResult.Provider?.URN,
                                UPIN = providerResult.Provider?.UPIN,
                                EstablishmentNumber = providerResult.Provider?.EstablishmentNumber,
                                OpenDate            = providerResult.Provider?.DateOpened,
                                CalculationId       = providerResult.CalculationResults.Select(m => m.Calculation.Id).ToArraySafe(),
                                CalculationName     = providerResult.CalculationResults.Select(m => m.Calculation.Name).ToArraySafe(),
                                CalculationResult   = providerResult.CalculationResults.Select(m => m.Value.HasValue ? m.Value.ToString() : "null").ToArraySafe()
                            };

                            if (_featureToggle.IsExceptionMessagesEnabled())
                            {
                                calculationResult.CalculationException = providerResult.CalculationResults
                                                                         .Where(m => !string.IsNullOrWhiteSpace(m.ExceptionType))
                                                                         .Select(e => e.Calculation.Id)
                                                                         .ToArraySafe();

                                calculationResult.CalculationExceptionType = providerResult.CalculationResults
                                                                             .Select(m => m.ExceptionType ?? string.Empty)
                                                                             .ToArraySafe();

                                calculationResult.CalculationExceptionMessage = providerResult.CalculationResults
                                                                                .Select(m => m.ExceptionMessage ?? string.Empty)
                                                                                .ToArraySafe();
                            }

                            results.Add(calculationResult);
                        }
                    }

                    IEnumerable <IndexError> errors = await _resultsSearchRepositoryPolicy.ExecuteAsync(() => _providerCalculationResultsSearchRepository.Index(results));

                    if (errors.Any())
                    {
                        string errorMessage = $"Failed to index calculation provider result documents with errors: { string.Join(";", errors.Select(m => m.ErrorMessage)) }";

                        _logger.Error(errorMessage);

                        throw new RetriableException(errorMessage);
                    }
                }));
            }
        }
        private async Task ProcessFieldChanges(string datasetDefinitionId, IEnumerable <FieldDefinitionChanges> fieldChanges, IEnumerable <string> relationshipSpecificationIds)
        {
            Guard.IsNullOrWhiteSpace(datasetDefinitionId, nameof(datasetDefinitionId));
            Guard.ArgumentNotNull(fieldChanges, nameof(fieldChanges));
            Guard.ArgumentNotNull(relationshipSpecificationIds, nameof(relationshipSpecificationIds));

            IEnumerable <IGrouping <string, FieldDefinitionChanges> > groupedFieldChanges = fieldChanges.GroupBy(f => f.FieldDefinition.Id);

            IList <FieldDefinitionChanges> fieldDefinitionChanges = new List <FieldDefinitionChanges>();

            bool shouldResetCalculation = false;

            foreach (IGrouping <string, FieldDefinitionChanges> grouping in groupedFieldChanges)
            {
                FieldDefinitionChanges fieldDefinitionChange = grouping.FirstOrDefault(m => m.ChangeTypes.Any(
                                                                                           c => c == FieldDefinitionChangeType.FieldName) || m.RequiresRemap);

                if (fieldDefinitionChange != null)
                {
                    fieldDefinitionChanges.Add(fieldDefinitionChange);
                }

                shouldResetCalculation = true;
            }

            if (!shouldResetCalculation)
            {
                return;
            }

            foreach (string specificationId in relationshipSpecificationIds)
            {
                IEnumerable <DatasetSpecificationRelationshipViewModel> relationships = await _datasetRepositoryPolicy.ExecuteAsync(() => _datasetRepository.GetCurrentRelationshipsBySpecificationIdAndDatasetDefinitionId(specificationId, datasetDefinitionId));

                if (relationships.IsNullOrEmpty())
                {
                    throw new RetriableException($"No relationships found for specificationId '{specificationId}' and dataset definition id '{datasetDefinitionId}'");
                }

                IEnumerable <Calculation> calculations = (await _calculationsRepositoryPolicy.ExecuteAsync(() => _calculationsRepository.GetCalculationsBySpecificationId(specificationId))).ToList();

                IEnumerable <string> aggregateParameters = calculations.SelectMany(m => SourceCodeHelpers.GetDatasetAggregateFunctionParameters(m.Current.SourceCode));

                HashSet <string> fieldNames = new HashSet <string>();

                foreach (FieldDefinitionChanges changes in fieldDefinitionChanges)
                {
                    //Check if only aggregable changes
                    if (!changes.ChangeTypes.Contains(FieldDefinitionChangeType.FieldType) && !changes.ChangeTypes.Contains(FieldDefinitionChangeType.FieldName))
                    {
                        foreach (DatasetSpecificationRelationshipViewModel datasetSpecificationRelationshipViewModel in relationships)
                        {
                            if (aggregateParameters.Contains($"Datasets.{VisualBasicTypeGenerator.GenerateIdentifier(datasetSpecificationRelationshipViewModel.Name)}.{VisualBasicTypeGenerator.GenerateIdentifier(changes.ExistingFieldDefinition.Name)}"))
                            {
                                fieldNames.Add(changes.ExistingFieldDefinition.Name);
                            }
                        }
                    }
                    else
                    {
                        fieldNames.Add(changes.ExistingFieldDefinition.Name);
                    }
                }

                if (fieldNames.Any())
                {
                    await _calculationService.ResetCalculationForFieldDefinitionChanges(relationships, specificationId, fieldNames);
                }
            }
        }
Esempio n. 19
0
        public async Task UpdateAllocations(Message message)
        {
            Guard.ArgumentNotNull(message, nameof(message));

            JobViewModel job = null;

            if (!message.UserProperties.ContainsKey("jobId"))
            {
                _logger.Error("Missing parent job id to instruct generating allocations");

                return;
            }

            string jobId = message.UserProperties["jobId"].ToString();

            ApiResponse <JobViewModel> response = await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.GetJobById(jobId));

            if (response == null || response.Content == null)
            {
                _logger.Error($"Could not find the parent job with job id: '{jobId}'");

                throw new Exception($"Could not find the parent job with job id: '{jobId}'");
            }

            job = response.Content;

            if (job.CompletionStatus.HasValue)
            {
                _logger.Information($"Received job with id: '{job.Id}' is already in a completed state with status {job.CompletionStatus.ToString()}");

                return;
            }

            await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(jobId, new Common.ApiClient.Jobs.Models.JobLogUpdateModel()));

            IDictionary <string, string> properties = message.BuildMessageProperties();

            string specificationId = message.UserProperties["specification-id"].ToString();

            BuildProject buildProject = await GetBuildProjectForSpecificationId(specificationId);

            if (message.UserProperties.ContainsKey("ignore-save-provider-results"))
            {
                properties.Add("ignore-save-provider-results", "true");
            }

            string cacheKey = "";

            if (message.UserProperties.ContainsKey("provider-cache-key"))
            {
                cacheKey = message.UserProperties["provider-cache-key"].ToString();
            }
            else
            {
                cacheKey = $"{CacheKeys.ScopedProviderSummariesPrefix}{specificationId}";
            }

            bool summariesExist = await _cacheProvider.KeyExists <ProviderSummary>(cacheKey);

            long totalCount = await _cacheProvider.ListLengthAsync <ProviderSummary>(cacheKey);

            bool refreshCachedScopedProviders = false;

            if (summariesExist)
            {
                IEnumerable <string> scopedProviderIds = await _providerResultsRepository.GetScopedProviderIds(specificationId);

                if (scopedProviderIds.Count() != totalCount)
                {
                    refreshCachedScopedProviders = true;
                }
                else
                {
                    IEnumerable <ProviderSummary> cachedScopedSummaries = await _cacheProvider.ListRangeAsync <ProviderSummary>(cacheKey, 0, (int)totalCount);

                    IEnumerable <string> differences = scopedProviderIds.Except(cachedScopedSummaries.Select(m => m.Id));

                    refreshCachedScopedProviders = differences.AnyWithNullCheck();
                }
            }

            if (!summariesExist || refreshCachedScopedProviders)
            {
                totalCount = await _providerResultsRepository.PopulateProviderSummariesForSpecification(specificationId);
            }

            const string providerSummariesPartitionIndex = "provider-summaries-partition-index";

            const string providerSummariesPartitionSize = "provider-summaries-partition-size";

            properties.Add(providerSummariesPartitionSize, _engineSettings.MaxPartitionSize.ToString());

            properties.Add("provider-cache-key", cacheKey);

            properties.Add("specification-id", specificationId);

            IList <IDictionary <string, string> > allJobProperties = new List <IDictionary <string, string> >();

            for (int partitionIndex = 0; partitionIndex < totalCount; partitionIndex += _engineSettings.MaxPartitionSize)
            {
                if (properties.ContainsKey(providerSummariesPartitionIndex))
                {
                    properties[providerSummariesPartitionIndex] = partitionIndex.ToString();
                }
                else
                {
                    properties.Add(providerSummariesPartitionIndex, partitionIndex.ToString());
                }

                IDictionary <string, string> jobProperties = new Dictionary <string, string>();

                foreach (KeyValuePair <string, string> item in properties)
                {
                    jobProperties.Add(item.Key, item.Value);
                }
                allJobProperties.Add(jobProperties);
            }

            await _specificationsRepository.UpdateCalculationLastUpdatedDate(specificationId);

            try
            {
                if (!allJobProperties.Any())
                {
                    _logger.Information($"No scoped providers set for specification '{specificationId}'");

                    JobLogUpdateModel jobCompletedLog = new JobLogUpdateModel
                    {
                        CompletedSuccessfully = true,
                        Outcome = "Calculations not run as no scoped providers set for specification"
                    };
                    await _jobsApiClientPolicy.ExecuteAsync(() => _jobsApiClient.AddJobLog(job.Id, jobCompletedLog));

                    return;
                }

                IEnumerable <Job> newJobs = await CreateGenerateAllocationJobs(job, allJobProperties);

                int newJobsCount = newJobs.Count();
                int batchCount   = allJobProperties.Count();

                if (newJobsCount != batchCount)
                {
                    throw new Exception($"Only {newJobsCount} child jobs from {batchCount} were created with parent id: '{job.Id}'");
                }
                else
                {
                    _logger.Information($"{newJobsCount} child jobs were created for parent id: '{job.Id}'");
                }
            }
            catch (Exception ex)
            {
                _logger.Error(ex.Message);

                throw new Exception($"Failed to create child jobs for parent job: '{job.Id}'");
            }
        }
Esempio n. 20
0
        public async Task <IActionResult> GetProviderById(HttpRequest request)
        {
            string providerId = request.GetParameter("providerId");

            if (string.IsNullOrWhiteSpace(providerId))
            {
                _logger.Error("No provider Id was provided to GetProviderById");
                return(new BadRequestObjectResult("Null or empty provider Id provided"));
            }

            ProviderIndex provider = await _resultsRepositoryPolicy.ExecuteAsync(() => _searchRepository.SearchById(providerId, IdFieldOverride: "providerId"));

            if (provider == null)
            {
                return(new NotFoundResult());
            }

            return(new OkObjectResult(provider));
        }
        public async Task <IActionResult> GetEffectivePermissionsForUser(string userId, string specificationId, HttpRequest request)
        {
            if (string.IsNullOrWhiteSpace(userId))
            {
                return(new BadRequestObjectResult($"{nameof(userId)} is empty or null"));
            }

            if (string.IsNullOrWhiteSpace(specificationId))
            {
                return(new BadRequestObjectResult($"{nameof(specificationId)} is empty or null"));
            }

            EffectiveSpecificationPermission cachedPermissions = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.GetHashValue <EffectiveSpecificationPermission>($"{CacheKeys.EffectivePermissions}:{userId}", specificationId));

            if (cachedPermissions != null)
            {
                return(new OkObjectResult(cachedPermissions));
            }
            else
            {
                SpecificationSummary specification = await _specificationsRepositoryPolicy.ExecuteAsync(() => _specificationsRepository.GetSpecificationSummaryById(specificationId));

                if (specification == null)
                {
                    return(new PreconditionFailedResult("Specification not found"));
                }

                List <FundingStreamPermission> permissionsForUser = new List <FundingStreamPermission>();
                foreach (Reference fundingStream in specification.FundingStreams)
                {
                    FundingStreamPermission permission = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetFundingStreamPermission(userId, fundingStream.Id));

                    if (permission != null)
                    {
                        permissionsForUser.Add(permission);
                    }
                    else
                    {
                        // Add permission for this funding stream with no permissions - used further down to calculate permissions (required for pessimistic permissions)
                        permissionsForUser.Add(new FundingStreamPermission()
                        {
                            UserId                     = userId,
                            FundingStreamId            = fundingStream.Id,
                            CanApproveFunding          = false,
                            CanChooseFunding           = false,
                            CanCreateSpecification     = false,
                            CanEditCalculations        = false,
                            CanEditSpecification       = false,
                            CanMapDatasets             = false,
                            CanPublishFunding          = false,
                            CanAdministerFundingStream = false,
                            CanApproveSpecification    = false,
                            CanCreateQaTests           = false,
                            CanDeleteCalculations      = false,
                            CanDeleteSpecification     = false,
                            CanDeleteQaTests           = false,
                            CanEditQaTests             = false,
                            CanRefreshFunding          = false,
                        });
                    }
                }

                EffectiveSpecificationPermission specificationPermissions = GeneratePermissions(permissionsForUser, specificationId, userId);

                string userPermissionHashKey = $"{CacheKeys.EffectivePermissions}:{userId}";

                // Does the hash set for this user already exist - used to determine the timeout for the hash set below
                bool existingHashSetExists = await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.HashSetExists(userPermissionHashKey));

                // Cache effective permissions for the specification / user
                await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetHashValue(userPermissionHashKey, specificationId, specificationPermissions));

                // If the hash set does not exist, then set an expiry for the whole hash set. This stops the users permissions being stored indefinitely
                if (!existingHashSetExists)
                {
                    await _cacheProviderPolicy.ExecuteAsync(() => _cacheProvider.SetHashExpiry(userPermissionHashKey, DateTime.UtcNow.AddHours(12)));
                }

                return(new OkObjectResult(specificationPermissions));
            }
        }
Esempio n. 22
0
        public async Task <IActionResult> ReIndexCalculationProviderResults()
        {
            IEnumerable <DocumentEntity <ProviderResult> > providerResults = await _resultsRepositoryPolicy.ExecuteAsync(() => _resultsRepository.GetAllProviderResults());

            IList <ProviderCalculationResultsIndex> searchItems = new List <ProviderCalculationResultsIndex>();

            Dictionary <string, SpecificationSummary> specifications = new Dictionary <string, SpecificationSummary>();

            foreach (DocumentEntity <ProviderResult> documentEntity in providerResults)
            {
                ProviderResult providerResult = documentEntity.Content;

                foreach (CalculationResult calculationResult in providerResult.CalculationResults)
                {
                    SpecificationSummary specificationSummary = null;
                    if (!specifications.ContainsKey(providerResult.SpecificationId))
                    {
                        specificationSummary = await _specificationsRepositoryPolicy.ExecuteAsync(() => _specificationsRepository.GetSpecificationSummaryById(providerResult.SpecificationId));

                        if (specificationSummary == null)
                        {
                            throw new InvalidOperationException($"Specification Summary returned null for specification ID '{providerResult.SpecificationId}'");
                        }

                        specifications.Add(providerResult.SpecificationId, specificationSummary);
                    }
                    else
                    {
                        specificationSummary = specifications[providerResult.SpecificationId];
                    }

                    ProviderCalculationResultsIndex searchItem = new ProviderCalculationResultsIndex
                    {
                        SpecificationId   = providerResult.SpecificationId,
                        SpecificationName = specificationSummary?.Name,
                        CalculationName   = providerResult.CalculationResults.Select(x => x.Calculation.Name).ToArraySafe(),
                        CalculationId     = providerResult.CalculationResults.Select(x => x.Calculation.Id).ToArraySafe(),
                        ProviderId        = providerResult.Provider.Id,
                        ProviderName      = providerResult.Provider.Name,
                        ProviderType      = providerResult.Provider.ProviderType,
                        ProviderSubType   = providerResult.Provider.ProviderSubType,
                        LocalAuthority    = providerResult.Provider.Authority,
                        LastUpdatedDate   = documentEntity.UpdatedAt,
                        UKPRN             = providerResult.Provider.UKPRN,
                        URN  = providerResult.Provider.URN,
                        UPIN = providerResult.Provider.UPIN,
                        EstablishmentNumber = providerResult.Provider.EstablishmentNumber,
                        OpenDate            = providerResult.Provider.DateOpened,
                        CalculationResult   = providerResult.CalculationResults.Select(m => m.Value.HasValue ? m.Value.ToString() : "null").ToArraySafe()
                    };

                    if (_featureToggle.IsExceptionMessagesEnabled())
                    {
                        searchItem.CalculationException = providerResult.CalculationResults
                                                          .Where(m => !string.IsNullOrWhiteSpace(m.ExceptionType))
                                                          .Select(e => e.Calculation.Id)
                                                          .ToArraySafe();

                        searchItem.CalculationExceptionType = providerResult.CalculationResults
                                                              .Select(m => m.ExceptionType ?? string.Empty)
                                                              .ToArraySafe();

                        searchItem.CalculationExceptionMessage = providerResult.CalculationResults
                                                                 .Select(m => m.ExceptionMessage ?? string.Empty)
                                                                 .ToArraySafe();
                    }

                    searchItems.Add(searchItem);
                }
            }

            const int partitionSize = 500;

            for (int i = 0; i < searchItems.Count; i += partitionSize)
            {
                IEnumerable <ProviderCalculationResultsIndex> partitionedResults = searchItems.Skip(i).Take(partitionSize);

                IEnumerable <IndexError> errors = await _resultsSearchRepositoryPolicy.ExecuteAsync(() => _calculationProviderResultsSearchRepository.Index(partitionedResults));

                if (errors.Any())
                {
                    _logger.Error($"Failed to index calculation provider result documents with errors: { string.Join(";", errors.Select(m => m.ErrorMessage)) }");

                    return(new InternalServerErrorResult(null));
                }
            }

            return(new NoContentResult());
        }
Esempio n. 23
0
        public async Task <IActionResult> AddJobLog(string jobId, JobLogUpdateModel jobLogUpdateModel)
        {
            Guard.IsNullOrWhiteSpace(jobId, nameof(jobId));
            Guard.ArgumentNotNull(jobLogUpdateModel, nameof(jobLogUpdateModel));

            Job job = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.GetJobById(jobId));

            if (job == null)
            {
                _logger.Error($"A job could not be found for job id: '{jobId}'");

                return(new NotFoundObjectResult($"A job could not be found for job id: '{jobId}'"));
            }

            bool saveJob = false;

            if (jobLogUpdateModel.CompletedSuccessfully.HasValue)
            {
                job.Completed        = DateTimeOffset.UtcNow;
                job.RunningStatus    = RunningStatus.Completed;
                job.CompletionStatus = jobLogUpdateModel.CompletedSuccessfully.Value ? CompletionStatus.Succeeded : CompletionStatus.Failed;
                job.Outcome          = jobLogUpdateModel.Outcome;
                saveJob = true;
            }
            else
            {
                if (job.RunningStatus != RunningStatus.InProgress)
                {
                    job.RunningStatus = RunningStatus.InProgress;
                    saveJob           = true;
                }
            }

            if (saveJob)
            {
                HttpStatusCode statusCode = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.UpdateJob(job));

                if (!statusCode.IsSuccess())
                {
                    _logger.Error($"Failed to update job id: '{jobId}' with status code '{(int)statusCode}'");
                    return(new InternalServerErrorResult($"Failed to update job id: '{jobId}' with status code '{(int)statusCode}'"));
                }
            }

            JobLog jobLog = new JobLog
            {
                Id                    = Guid.NewGuid().ToString(),
                JobId                 = jobId,
                ItemsProcessed        = jobLogUpdateModel.ItemsProcessed,
                ItemsSucceeded        = jobLogUpdateModel.ItemsSucceeded,
                ItemsFailed           = jobLogUpdateModel.ItemsFailed,
                Outcome               = jobLogUpdateModel.Outcome,
                CompletedSuccessfully = jobLogUpdateModel.CompletedSuccessfully,
                Timestamp             = DateTimeOffset.UtcNow
            };

            HttpStatusCode createJobLogStatus = await _jobsRepositoryPolicy.ExecuteAsync(() => _jobRepository.CreateJobLog(jobLog));

            if (!createJobLogStatus.IsSuccess())
            {
                _logger.Error($"Failed to create a job log for job id: '{jobId}'");
                throw new Exception($"Failed to create a job log for job id: '{jobId}'");
            }

            await SendJobLogNotification(job, jobLog);

            return(new OkObjectResult(jobLog));
        }
Esempio n. 24
0
        public async Task <HttpStatusCode> SaveTestProviderResults(IEnumerable <TestScenarioResult> testResults, IEnumerable <ProviderResult> providerResults)
        {
            Guard.ArgumentNotNull(testResults, nameof(testResults));

            if (!testResults.Any())
            {
                return(HttpStatusCode.NotModified);
            }

            Stopwatch stopwatch = Stopwatch.StartNew();

            Task <HttpStatusCode> repoUpdateTask = _testResultsPolicy.ExecuteAsync(() => _testResultsRepository.SaveTestProviderResults(testResults));

            IEnumerable <TestScenarioResultIndex> searchIndexItems = _mapper.Map <IEnumerable <TestScenarioResultIndex> >(testResults);

            foreach (TestScenarioResultIndex testScenarioResult in searchIndexItems)
            {
                ProviderResult providerResult = providerResults.FirstOrDefault(m => m.Provider.Id == testScenarioResult.ProviderId);

                if (providerResult != null)
                {
                    testScenarioResult.EstablishmentNumber = providerResult.Provider.EstablishmentNumber;
                    testScenarioResult.UKPRN           = providerResult.Provider.UKPRN;
                    testScenarioResult.UPIN            = providerResult.Provider.UPIN;
                    testScenarioResult.URN             = providerResult.Provider.URN;
                    testScenarioResult.LocalAuthority  = providerResult.Provider.Authority;
                    testScenarioResult.ProviderType    = providerResult.Provider.ProviderType;
                    testScenarioResult.ProviderSubType = providerResult.Provider.ProviderSubType;
                    testScenarioResult.OpenDate        = providerResult.Provider.DateOpened;
                }
            }

            Task <IEnumerable <IndexError> > searchUpdateTask = _testResultsSearchPolicy.ExecuteAsync(() => _searchRepository.Index(searchIndexItems));

            await TaskHelper.WhenAllAndThrow(searchUpdateTask, repoUpdateTask);

            IEnumerable <IndexError> indexErrors = searchUpdateTask.Result;
            HttpStatusCode           repositoryUpdateStatusCode = repoUpdateTask.Result;

            stopwatch.Stop();

            if (!indexErrors.Any() && (repoUpdateTask.Result == HttpStatusCode.Created || repoUpdateTask.Result == HttpStatusCode.NotModified))
            {
                _telemetry.TrackEvent("UpdateTestScenario",
                                      new Dictionary <string, string>()
                {
                    { "SpecificationId", testResults.First().Specification.Id }
                },
                                      new Dictionary <string, double>()
                {
                    { "update-testscenario-elapsedMilliseconds", stopwatch.ElapsedMilliseconds },
                    { "update-testscenario-recordsUpdated", testResults.Count() },
                }
                                      );

                return(HttpStatusCode.Created);
            }

            foreach (IndexError indexError in indexErrors)
            {
                _logger.Error($"SaveTestProviderResults index error {{key}}: {indexError.ErrorMessage}", indexError.Key);
            }

            if (repositoryUpdateStatusCode == default(HttpStatusCode))
            {
                _logger.Error("SaveTestProviderResults repository failed with no response code");
            }
            else
            {
                _logger.Error("SaveTestProviderResults repository failed with response code: {repositoryUpdateStatusCode}", repositoryUpdateStatusCode);
            }

            return(HttpStatusCode.InternalServerError);
        }
        public async Task <IActionResult> UpdatePermissionForUser(string userId, string fundingStreamId, HttpRequest request)
        {
            if (string.IsNullOrWhiteSpace(userId))
            {
                return(new BadRequestObjectResult($"{nameof(userId)} is empty or null"));
            }

            if (string.IsNullOrWhiteSpace(fundingStreamId))
            {
                return(new BadRequestObjectResult($"{nameof(fundingStreamId)} is empty or null"));
            }

            Guard.ArgumentNotNull(request, nameof(request));

            User user = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetUserById(userId));

            if (user == null)
            {
                return(new PreconditionFailedResult("userId not found"));
            }

            string json = await request.GetRawBodyStringAsync();

            FundingStreamPermissionUpdateModel updateModel = JsonConvert.DeserializeObject <FundingStreamPermissionUpdateModel>(json);

            FundingStreamPermission existingPermissions = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.GetFundingStreamPermission(userId, fundingStreamId));

            FundingStreamPermission newPermissions = _mapper.Map <FundingStreamPermissionUpdateModel, FundingStreamPermission>(updateModel);

            newPermissions.FundingStreamId = fundingStreamId;
            newPermissions.UserId          = userId;

            if (existingPermissions == null || !existingPermissions.HasSamePermissions(newPermissions))
            {
                HttpStatusCode saveResult = await _userRepositoryPolicy.ExecuteAsync(() => _userRepository.UpdateFundingStreamPermission(newPermissions));

                if (saveResult != HttpStatusCode.OK && saveResult != HttpStatusCode.Created)
                {
                    return(new InternalServerErrorResult($"Saving funding stream permission to repository returned '{saveResult}'"));
                }

                Reference author = request.GetUserOrDefault();

                FundingStreamPermissionVersion version = new FundingStreamPermissionVersion()
                {
                    Author        = author,
                    Permission    = newPermissions,
                    PublishStatus = Models.Versioning.PublishStatus.Updated,
                    Date          = DateTimeOffset.Now,
                    UserId        = userId,
                };

                version.Version = await _fundingStreamPermissionVersionRepositoryPolicy.ExecuteAsync(() => _fundingStreamPermissionVersionRepository.GetNextVersionNumber(version, partitionKeyId: userId));

                await _fundingStreamPermissionVersionRepositoryPolicy.ExecuteAsync(() => _fundingStreamPermissionVersionRepository.SaveVersion(version, userId));

                await ClearEffectivePermissionsForUser(userId);
            }

            return(new OkObjectResult(_mapper.Map <FundingStreamPermissionCurrent>(newPermissions)));
        }