public async Task <Either <ActionResult, LegacyReleaseViewModel> > CreateLegacyRelease( LegacyReleaseCreateViewModel legacyRelease) { return(await _persistenceHelper .CheckEntityExists <Publication>( legacyRelease.PublicationId, publication => publication.Include(p => p.LegacyReleases) ) .OnSuccess(_userService.CheckCanCreateLegacyRelease) .OnSuccess(async publication => { var saved = await _context.LegacyReleases.AddAsync(new LegacyRelease { Description = legacyRelease.Description, Url = legacyRelease.Url, Order = publication.LegacyReleases.Count > 0 ? publication.LegacyReleases.Max(release => release.Order) + 1 : 1, PublicationId = legacyRelease.PublicationId }); await _context.SaveChangesAsync(); await _publicBlobCacheService.DeleteItem(new PublicationCacheKey(publication.Slug)); return _mapper.Map <LegacyReleaseViewModel>(saved.Entity); })); }
private async Task DeleteLazilyCachedReleaseResults(string publicationSlug, string releaseSlug) { await _blobCacheService.DeleteCacheFolder(new ReleaseDataBlockResultsFolderCacheKey(publicationSlug, releaseSlug)); await _blobCacheService.DeleteItem(new ReleaseSubjectsCacheKey(publicationSlug, releaseSlug)); await _blobCacheService.DeleteCacheFolder(new ReleaseFastTrackResultsFolderCacheKey(publicationSlug, releaseSlug)); await _blobCacheService.DeleteCacheFolder(new ReleaseSubjectMetaFolderCacheKey(publicationSlug, releaseSlug)); }
public async Task PublishStagedReleaseContent(Guid releaseId, string publicationSlug) { await _publicBlobStorageService.MoveDirectory( sourceContainerName : PublicContent, sourceDirectoryPath : PublicContentStagingPath(), destinationContainerName : PublicContent, destinationDirectoryPath : string.Empty ); await _releaseService.SetPublishedDates(releaseId, DateTime.UtcNow); await _publicBlobCacheService.DeleteItem(new PublicationCacheKey(publicationSlug)); // TODO: @MarkFix EES-3149 Delete superseded publication's cache here too? }
private async Task <Either <ActionResult, MethodologyVersion> > UpdateStatus( MethodologyVersion methodologyVersionToUpdate, MethodologyApprovalUpdateRequest request) { if (!request.IsStatusUpdateForMethodology(methodologyVersionToUpdate)) { // Status unchanged return(methodologyVersionToUpdate); } return(await CheckCanUpdateStatus(methodologyVersionToUpdate, request.Status) .OnSuccessDo(methodology => CheckMethodologyCanDependOnRelease(methodology, request)) .OnSuccessDo(RemoveUnusedImages) .OnSuccess(async methodology => { methodology.Status = request.Status; methodology.PublishingStrategy = request.PublishingStrategy; methodology.ScheduledWithReleaseId = WithRelease == request.PublishingStrategy ? request.WithReleaseId : null; methodology.InternalReleaseNote = Approved == request.Status ? request.LatestInternalReleaseNote : null; methodology.Updated = DateTime.UtcNow; _context.MethodologyVersions.Update(methodology); if (await _methodologyVersionRepository.IsPubliclyAccessible(methodology.Id)) { methodology.Published = DateTime.UtcNow; await _publishingService.PublishMethodologyFiles(methodology.Id); // Invalidate the 'All Methodologies' cache item await _publicBlobCacheService.DeleteItem(new AllMethodologiesCacheKey()); } _context.MethodologyVersions.Update(methodology); await _context.SaveChangesAsync(); return methodology; })); }
public async Task <Either <ActionResult, PublicationViewModel> > UpdatePublication( Guid publicationId, PublicationSaveViewModel updatedPublication) { return(await _persistenceHelper .CheckEntityExists <Publication>(publicationId) .OnSuccess(_userService.CheckCanUpdatePublication) .OnSuccessDo(async publication => { if (publication.Title != updatedPublication.Title) { return await _userService.CheckCanUpdatePublicationTitle(); } return Unit.Instance; }) .OnSuccessDo(async publication => { if (publication.TopicId != updatedPublication.TopicId) { return await ValidateSelectedTopic(updatedPublication.TopicId); } return Unit.Instance; }) .OnSuccess(async publication => { var originalTitle = publication.Title; var originalSlug = publication.Slug; if (!publication.Live) { var slugValidation = await ValidatePublicationSlugUniqueForUpdate(publication.Id, updatedPublication.Slug); if (slugValidation.IsLeft) { return new Either <ActionResult, PublicationViewModel>(slugValidation.Left); } publication.Slug = updatedPublication.Slug; } publication.Title = updatedPublication.Title; publication.TopicId = updatedPublication.TopicId; publication.ExternalMethodology = updatedPublication.ExternalMethodology; publication.Updated = DateTime.UtcNow; // Add new contact if it doesn't exist, otherwise replace existing // contact that is shared with another publication with a new // contact, as we want each publication to have its own contact. if (publication.Contact == null || _context.Publications .Any(p => p.ContactId == publication.ContactId && p.Id != publication.Id)) { publication.Contact = new Contact(); } publication.Contact.ContactName = updatedPublication.Contact.ContactName; publication.Contact.ContactTelNo = updatedPublication.Contact.ContactTelNo; publication.Contact.TeamName = updatedPublication.Contact.TeamName; publication.Contact.TeamEmail = updatedPublication.Contact.TeamEmail; _context.Publications.Update(publication); await _context.SaveChangesAsync(); if (originalTitle != publication.Title) { await _methodologyVersionRepository.PublicationTitleChanged(publicationId, originalSlug, publication.Title, publication.Slug); } if (publication.Live) { publication.Published = DateTime.UtcNow; await _context.SaveChangesAsync(); await DeleteCachedTaxonomyBlobs(); await _publicBlobCacheService.DeleteItem(new PublicationCacheKey(publication.Slug)); // TODO: @MarkFix EES-3149 Need to handle superseded publication.json cache files here too? } return await GetPublication(publication.Id); })); }
public async Task PublishReleaseContent( [QueueTrigger(PublishReleaseContentQueue)] PublishReleaseContentMessage message, ExecutionContext executionContext, ILogger logger) { logger.LogInformation("{0} triggered at: {1}", executionContext.FunctionName, DateTime.UtcNow); await UpdateStage(message.ReleaseId, message.ReleaseStatusId, State.Started); var context = new PublishContext(DateTime.UtcNow, false); try { await _contentService.UpdateContent(context, message.ReleaseId); await _releaseService.SetPublishedDates(message.ReleaseId, context.Published); if (!EnvironmentUtils.IsLocalEnvironment()) { await _releaseService.DeletePreviousVersionsStatisticalData(message.ReleaseId); } // Invalidate the cached trees in case any methodologies/publications // are now accessible for the first time after publishing these releases await _blobCacheService.DeleteItem(new AllMethodologiesCacheKey()); await _blobCacheService.DeleteItem(new PublicationTreeCacheKey()); await _blobCacheService.DeleteItem(new PublicationTreeCacheKey(PublicationTreeFilter.AnyData)); await _blobCacheService.DeleteItem(new PublicationTreeCacheKey(PublicationTreeFilter.LatestData)); var release = await _contentDbContext.Releases .Include(r => r.Publication) .Where(r => r.Id == message.ReleaseId) .SingleAsync(); await _blobCacheService.DeleteItem(new PublicationCacheKey(release.Publication.Slug)); // TODO: @MarkFix EES-3149 Delete superseded publication's cache here too? await _contentService.DeletePreviousVersionsDownloadFiles(message.ReleaseId); await _contentService.DeletePreviousVersionsContent(message.ReleaseId); await _notificationsService.NotifySubscribersIfApplicable(message.ReleaseId); await UpdateStage(message.ReleaseId, message.ReleaseStatusId, State.Complete); } catch (Exception e) { logger.LogError(e, "Exception occured while executing {0}", executionContext.FunctionName); logger.LogError("{StackTrace}", e.StackTrace); await UpdateStage(message.ReleaseId, message.ReleaseStatusId, State.Failed, new ReleasePublishingStatusLogMessage($"Exception publishing release immediately: {e.Message}")); } logger.LogInformation("{0} completed", executionContext.FunctionName); }