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);
            }));
        }
예제 #2
0
        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));
        }
예제 #3
0
        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?
        }
예제 #4
0
        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;
            }));
        }
예제 #5
0
        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);
            }));
        }
예제 #6
0
        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);
        }