public async Task <IActionResult> SaveDefinition(JobDefinition definition) { try { Guard.ArgumentNotNull(definition, nameof(definition)); ValidationResult validationResult = await _validator.ValidateAsync(definition); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } HttpStatusCode result = await _jobDefinitionsRepositoryPolicy.ExecuteAsync(() => _jobDefinitionsRepository.SaveJobDefinition(definition)); if (!result.IsSuccess()) { int statusCode = (int)result; _logger.Error($"Failed to save json file: {definition.Id} to cosmos db with status {statusCode}"); return(new StatusCodeResult(statusCode)); } } catch (Exception exception) { _logger.Error(exception, $"Exception occurred writing job definition {definition?.Id} to cosmos db"); throw; } await _cachePolicy.ExecuteAsync(() => _cacheProvider.RemoveAsync <List <JobDefinition> >(CacheKeys.JobDefinitions)); return(new NoContentResult()); }
public async Task <IActionResult> PublishBatchProvidersFunding(string specificationId, PublishedProviderIdsRequest publishedProviderIdsRequest, Reference user, string correlationId) { ValidationResult specificationIdValidationResult = SpecificationIdValidator.Validate(specificationId); if (!specificationIdValidationResult.IsValid) { return(specificationIdValidationResult.AsBadRequest()); } ValidationResult publishedProviderIdsValidationResult = PublishedProviderIdsValidator.Validate(publishedProviderIdsRequest.PublishedProviderIds.ToArray()); if (!publishedProviderIdsValidationResult.IsValid) { return(publishedProviderIdsValidationResult.AsBadRequest()); } IActionResult actionResult = await IsSpecificationReadyForPublish(specificationId, ApprovalMode.Batches); if (!actionResult.IsOk()) { return(actionResult); } await FilterOutPublishedProvidersInError(publishedProviderIdsRequest); ApiJob job = await _createBatchPublishProviderFundingJobs.CreateJob(specificationId, user, correlationId, messageBody : JsonExtensions.AsJson(publishedProviderIdsRequest), compress : true); return(ProcessJobResponse(job, specificationId, JobConstants.DefinitionNames.PublishBatchProviderFundingJob)); }
public async Task <IActionResult> GetLatestPublishedProvidersForSpecificationId(string specificationId) { ValidationResult validationResults = _validator.Validate(specificationId); if (!validationResults.IsValid) { return(validationResults.AsBadRequest()); } SpecificationSummary specificationSummary = await _specificationService.GetSpecificationSummaryById(specificationId); List <PublishedProviderVersion> results = new List <PublishedProviderVersion>(); foreach (var fundingStream in specificationSummary.FundingStreams) { IEnumerable <PublishedProvider> publishedProviders = await _resiliencePolicy.ExecuteAsync(() => _publishedFunding.GetCurrentPublishedProviders(fundingStream.Id, specificationSummary.FundingPeriod.Id)); if (publishedProviders.AnyWithNullCheck()) { results.AddRange(publishedProviders.Select(_ => _.Current)); } } return(new OkObjectResult(results)); }
public async Task <IActionResult> SetCurrentProviderVersionForFundingStream(string fundingStreamId, string providerVersionId, int?providerSnapshotId) { ValidationResult validationResult = await _setCurrentRequestValidator.ValidateAsync(new SetFundingStreamCurrentProviderVersionRequest { FundingStreamId = fundingStreamId, ProviderVersionId = providerVersionId }); if (!validationResult.IsValid) { LogError("The set current provider version for funding stream request was invalid." + $"\n{validationResult.Errors.Select(_ => _.ErrorMessage).Join("\n")}"); return(validationResult.AsBadRequest()); } await _providerVersionMetadataPolicy.ExecuteAsync(() => _providerVersionMetadata.UpsertCurrentProviderVersion(new CurrentProviderVersion { Id = $"Current_{fundingStreamId}", ProviderVersionId = providerVersionId, ProviderSnapshotId = providerSnapshotId })); return(new NoContentResult()); }
public async Task <IActionResult> UpdateTemplateDescription(TemplateDescriptionUpdateCommand command) { ValidationResult validationResult = await _validatorFactory.Validate(command); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } Reference author = ControllerContext.HttpContext.Request?.GetUserOrDefault(); CommandResult result = await _templateBuilderService.UpdateTemplateDescription(command, author); if (result.Succeeded) { return(Ok()); } if (result.ValidationResult != null) { return(result.ValidationResult.AsBadRequest()); } return(new InternalServerErrorResult(result.ErrorMessage ?? result.Exception?.Message ?? "Unknown error occurred")); }
public async Task <IActionResult> QueueBatchUploadValidation(BatchUploadValidationRequest batchUploadValidationRequest, Reference user, string correlationId) { ValidationResult validationResult = await _requestValidation.ValidateAsync(batchUploadValidationRequest); if (!validationResult.IsValid) { BadRequestObjectResult badRequest = validationResult.AsBadRequest(); _logger.Warning($"Unable to queue batch upload validation job as validation errors.\n{badRequest.Value}"); return(badRequest); } BatchUploadValidationProperties properties = batchUploadValidationRequest; Job job = await QueueJob(new JobCreateModel { CorrelationId = correlationId, InvokerUserId = user?.Id, InvokerUserDisplayName = user?.Name, JobDefinitionId = BatchPublishedProviderValidationJob, SpecificationId = batchUploadValidationRequest.SpecificationId, Trigger = new Trigger(), Properties = (Dictionary <string, string>)properties }); return(new OkObjectResult(new { JobId = job.Id })); }
public async Task <IActionResult> ApplyCustomProfile(ApplyCustomProfileRequest request, Reference author) { Guard.ArgumentNotNull(request, nameof(request)); Guard.ArgumentNotNull(author, nameof(author)); ValidationResult validationResult = await _requestValidation.ValidateAsync(request); if (!validationResult.IsValid) { string validationErrors = validationResult.Errors.Select(_ => _.ErrorMessage).Join(", "); _logger.Information( $"Unable to process apply custom profile request. Request was invalid. \n{validationErrors}"); return(validationResult.AsBadRequest()); } string publishedProviderId = request.PublishedProviderId; string fundingLineCode = request.FundingLineCode; PublishedProvider publishedProvider = await _publishedFundingResilience.ExecuteAsync(() => _publishedFundingRepository.GetPublishedProviderById(publishedProviderId, publishedProviderId)); PublishedProviderVersion currentProviderVersion = publishedProvider.Current; foreach (IGrouping <string, ProfilePeriod> profilePeriods in request.ProfilePeriods.GroupBy(_ => _.DistributionPeriodId)) { string distributionPeriodId = profilePeriods.Key; currentProviderVersion.UpdateDistributionPeriodForFundingLine( fundingLineCode, distributionPeriodId, profilePeriods); currentProviderVersion.AddOrUpdateCustomProfile(fundingLineCode, request.CarryOver, distributionPeriodId); } if (request.HasCarryOver) { currentProviderVersion.AddCarryOver(fundingLineCode, ProfilingCarryOverType.CustomProfile, request.CarryOver.GetValueOrDefault()); } else { currentProviderVersion.RemoveCarryOver(fundingLineCode); } currentProviderVersion.AddProfilingAudit(fundingLineCode, author); await _publishedProviderVersionCreation.UpdatePublishedProviderStatus(new[] { publishedProvider }, author, currentProviderVersion.Status switch { PublishedProviderStatus.Draft => PublishedProviderStatus.Draft, _ => PublishedProviderStatus.Updated },
public async Task <IActionResult> CreateRefreshFundingJob(string specificationId, Reference user, string correlationId) { ValidationResult validationResult = SpecificationIdValidator.Validate(specificationId); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } ApiResponse <ApiSpecificationSummary> specificationIdResponse = await ResiliencePolicy.ExecuteAsync(() => Specifications.GetSpecificationSummaryById(specificationId)); ApiSpecificationSummary specificationSummary = specificationIdResponse.Content; if (specificationSummary == null) { return(new NotFoundResult()); } SpecificationFundingStatus chooseCheck = await _specificationFundingStatusService.CheckChooseForFundingStatus(specificationSummary); if (chooseCheck == SpecificationFundingStatus.SharesAlreadyChosenFundingStream) { return(new ConflictResult()); } IDictionary <string, Provider> scopedProviders = await _providerService.GetScopedProvidersForSpecification(specificationSummary.Id, specificationSummary.ProviderVersionId); // Check prerequisites for this specification to be chosen/refreshed IPrerequisiteChecker prerequisiteChecker = _prerequisiteCheckerLocator.GetPreReqChecker(PrerequisiteCheckerType.Refresh); try { await prerequisiteChecker.PerformChecks( specificationSummary, null, Array.Empty <PublishedProvider>(), scopedProviders?.Values); } catch (JobPrereqFailedException ex) { return(new BadRequestObjectResult(new [] { $"Prerequisite check for refresh failed {ex.Message}" }.ToModelStateDictionary())); } ApiJob refreshFundingJob = await _refreshFundingJobs.CreateJob(specificationId, user, correlationId); Guard.ArgumentNotNull(refreshFundingJob, nameof(refreshFundingJob), "Failed to create RefreshFundingJob"); JobCreationResponse jobCreationResponse = new JobCreationResponse() { JobId = refreshFundingJob.Id, }; return(new OkObjectResult(jobCreationResponse)); }
public async Task <IActionResult> GetTemplateVersions(FindTemplateVersionQuery query) { ValidationResult validationResult = await _validatorFactory.Validate(query); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } IEnumerable <TemplateSummaryResponse> templateVersionResponses = await _templateBuilderService.FindVersionsByFundingStreamAndPeriod(query); return(Ok(templateVersionResponses)); }
public async Task <IActionResult> ProcessProfileAllocationBatchRequest(ProfileBatchRequest profileBatchRequest) { Guard.ArgumentNotNull(profileBatchRequest, nameof(ProfileBatchRequest)); ValidationResult validationResult = await _batchRequestValidation.ValidateAsync(profileBatchRequest); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } try { FundingStreamPeriodProfilePattern profilePattern = await GetProfilePattern(profileBatchRequest); if (profilePattern == null) { _logger.Error("Unable to find profile pattern for FundingStream = {fundingStreamId}, FundingPeriodId={FundingPeriodId}, FundingLineCode={FundingLineCode}, ProfilePatternKey={ProfilePatternKey}, ProviderType={ProviderType}, ProviderSubType={ProviderSubType}", profileBatchRequest.FundingStreamId, profileBatchRequest.FundingPeriodId, profileBatchRequest.FundingLineCode, profileBatchRequest.ProfilePatternKey, profileBatchRequest.ProviderType, profileBatchRequest.ProviderSubType); } BatchProfileRequestContext batchProfileRequestContext = new BatchProfileRequestContext(profilePattern, profileBatchRequest, 5); IProducerConsumer producerConsumer = _producerConsumerFactory.CreateProducerConsumer(ProduceProviderFundingValues, ProfileProviderFundingValues, 10, 10, _logger); await producerConsumer.Run(batchProfileRequestContext); return(new OkObjectResult(batchProfileRequestContext.Responses.ToArray())); } catch (Exception ex) { LogError(ex, profileBatchRequest); throw; } }
public async Task <IActionResult> UpdateFundingStructureLastModified(UpdateFundingStructureLastModifiedRequest request) { Guard.ArgumentNotNull(request, nameof(request)); // ReSharper disable once MethodHasAsyncOverload ValidationResult validationResult = _validator.Validate(request); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } string cacheKey = GetCacheKeyFundingStructure(request.SpecificationId, request.FundingStreamId, request.FundingPeriodId); await _cacheResilience.ExecuteAsync(() => _cacheProvider.SetAsync(cacheKey, request.LastModified)); return(new OkResult()); }
public async Task <IActionResult> ValidateSpecificationForRefresh(string specificationId) { List <string> prereqErrors = new List <string>(); ValidationResult validationResult = SpecificationIdValidator.Validate(specificationId); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } ApiResponse <ApiSpecificationSummary> specificationIdResponse = await ResiliencePolicy.ExecuteAsync(() => Specifications.GetSpecificationSummaryById(specificationId)); ApiSpecificationSummary specificationSummary = specificationIdResponse.Content; if (specificationSummary == null) { return(new NotFoundResult()); } IDictionary <string, Provider> scopedProviders = await _providerService.GetScopedProvidersForSpecification(specificationSummary.Id, specificationSummary.ProviderVersionId); IPrerequisiteChecker prerequisiteChecker = _prerequisiteCheckerLocator.GetPreReqChecker(PrerequisiteCheckerType.Refresh); try { await prerequisiteChecker.PerformChecks( specificationSummary, null, Array.Empty <PublishedProvider>(), scopedProviders?.Values); } catch (JobPrereqFailedException ex) { return(new BadRequestObjectResult(ex.Errors.ToArray().ToModelStateDictionary())); } return(new NoContentResult()); }
public async Task <IActionResult> PublishAllProvidersFunding(string specificationId, Reference user, string correlationId) { ValidationResult validationResult = SpecificationIdValidator.Validate(specificationId); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } IActionResult actionResult = await IsSpecificationReadyForPublish(specificationId, ApprovalMode.All); if (!actionResult.IsOk()) { return(actionResult); } ApiJob job = await _createAllPublishProviderFundingJobs.CreateJob(specificationId, user, correlationId); return(ProcessJobResponse(job, specificationId, JobConstants.DefinitionNames.PublishAllProviderFundingJob)); }
public async Task <IActionResult> PublishIntegrityCheck(string specificationId, Reference user, string correlationId, bool publishAll = false) { ValidationResult validationResult = SpecificationIdValidator.Validate(specificationId); if (!validationResult.IsValid) { return(validationResult.AsBadRequest()); } ApiJob job = await _createPublishIntegrityJob.CreateJob(specificationId, user, correlationId, publishAll?new Dictionary <string, string> { { "publish-all", "True" } } : null); return(ProcessJobResponse(job, specificationId, JobConstants.DefinitionNames.PublishIntegrityCheckJob)); }
public async Task <IActionResult> GetProviderStatusCounts(string specificationId, string providerType, string localAuthority, string status) { ValidationResult validationResults = _validator.Validate(specificationId); if (!validationResults.IsValid) { return(validationResults.AsBadRequest()); } SpecificationSummary specificationSummary = await _specificationsRepositoryPolicy.ExecuteAsync(() => _specificationService.GetSpecificationSummaryById(specificationId)); IEnumerable <PublishedProviderFundingStreamStatus> publishedProviderFundingStreamStatuses = await _publishedFundingRepositoryResilience.ExecuteAsync(() => _publishedFundingRepository.GetPublishedProviderStatusCounts(specificationId, providerType, localAuthority, status)); List <ProviderFundingStreamStatusResponse> response = new List <ProviderFundingStreamStatusResponse>(); foreach (IGrouping <string, PublishedProviderFundingStreamStatus> publishedProviderFundingStreamGroup in publishedProviderFundingStreamStatuses.GroupBy(x => x.FundingStreamId)) { if (!specificationSummary.FundingStreams.Select(x => x.Id).Contains(publishedProviderFundingStreamGroup.Key)) { continue; } response.Add(new ProviderFundingStreamStatusResponse { FundingStreamId = publishedProviderFundingStreamGroup.Key, ProviderApprovedCount = GetCountValueOrDefault(publishedProviderFundingStreamGroup, "Approved"), ProviderDraftCount = GetCountValueOrDefault(publishedProviderFundingStreamGroup, "Draft"), ProviderReleasedCount = GetCountValueOrDefault(publishedProviderFundingStreamGroup, "Released"), ProviderUpdatedCount = GetCountValueOrDefault(publishedProviderFundingStreamGroup, "Updated"), TotalFunding = publishedProviderFundingStreamGroup.Sum(x => x.TotalFunding) }); } return(new OkObjectResult(response)); }
public async Task <IActionResult> RestoreContent(TemplateFundingLinesUpdateCommand command, [FromRoute] string templateId, [FromRoute] string version) { ValidationResult validationResult = await _validatorFactory.Validate(command); if (!validationResult.IsValid || command.TemplateId != templateId) { return(validationResult.AsBadRequest()); } Reference author = ControllerContext.HttpContext.Request?.GetUserOrDefault(); CommandResult result = await _templateBuilderService.RestoreTemplateContent(command, author); if (result.Succeeded) { return(Ok(result.Version)); } if (result.ValidationModelState != null) { return(BadRequest(result.ValidationModelState)); } return(new InternalServerErrorResult(result.ErrorMessage ?? result.Exception?.Message ?? "Unknown error occurred")); }
private async Task <IActionResult> GetProviderDataAsCsv(PublishedProviderIdsRequest providerIds, string specificationId, string csvFileSuffix, params PublishedProviderStatus[] statuses) { ValidationResult validationResults = _validator.Validate(specificationId); if (!validationResults.IsValid) { return(validationResults.AsBadRequest()); } if (providerIds.PublishedProviderIds.IsNullOrEmpty()) { return(new BadRequestObjectResult("Provider ids must be provided")); } IEnumerable <PublishedProviderFundingCsvData> publishedProviderFundingData = await _fundingCsvDataProcessor.GetFundingData( providerIds.PublishedProviderIds, specificationId, statuses); if (publishedProviderFundingData.IsNullOrEmpty()) { return(new NotFoundObjectResult("No data found for given specification and published provider ids.")); } IEnumerable <dynamic> csvRows = publishedProviderFundingData.Select(x => new { UKPRN = x.Ukprn, URN = x.Urn, UPIN = x.Upin, ProviderName = x.ProviderName, FundingAmount = x.TotalFunding }); string csvFileData = _csvUtils.AsCsv(csvRows, true); string fundingStreamId = publishedProviderFundingData.First().FundingStreamId; string fundingPeriodId = publishedProviderFundingData.First().FundingPeriodId; string csvFileName = $"{fundingStreamId}-{fundingPeriodId}-{csvFileSuffix}.csv"; string blobName = $"{csvFileName}"; string blobUrl = string.Empty; await _blobClientPolicy.ExecuteAsync(async() => { ICloudBlob blob = _blobClient.GetBlockBlobReference(blobName, BlobContainerName); blob.Properties.ContentDisposition = $"attachment; filename={csvFileName}"; using (MemoryStream stream = new MemoryStream(csvFileData.AsUTF8Bytes())) { await blob.UploadFromStreamAsync(stream); } blob.Metadata["fundingStreamId"] = fundingStreamId; blob.Metadata["fundingPeriodId"] = fundingPeriodId; blob.Metadata["specificationId"] = specificationId; blob.Metadata["fileName"] = Path.GetFileNameWithoutExtension(csvFileName); blob.SetMetadata(); blobUrl = _blobClient.GetBlobSasUrl(blobName, DateTimeOffset.Now.AddDays(1), SharedAccessBlobPermissions.Read, BlobContainerName); }); return(new OkObjectResult(new PublishedProviderDataDownload() { Url = blobUrl })); }