示例#1
0
        //todo: don't want to do this for embedded items
        private async Task <IEnumerable <INodeWithOutgoingRelationships> > GetIncomingPreviewContentPickerRelationshipsWhenPublishing(
            IGraphReplicaSet graphReplicaSet,
            dynamic graphSyncPartContent,
            string contentItemId)
        {
            // we only need to recreate incoming relationships
            // if we're publishing and there isn't currently a published version
            if (graphReplicaSet.Name != GraphReplicaSetNames.Published ||
                await _contentItemsService.HasExistingPublishedVersion(contentItemId))
            {
                return(Enumerable.Empty <INodeWithOutgoingRelationships>());
            }

            // allow sync is called concurrently for preview and published
            // so we could get the before or after incoming relationships
            // either should do, but perhaps we should do it serially to consistently fetch the _before_ incoming relationships?
            IGetIncomingContentPickerRelationshipsQuery getDraftRelationshipsQuery =
                _serviceProvider.GetRequiredService <IGetIncomingContentPickerRelationshipsQuery>();

            getDraftRelationshipsQuery.NodeLabels      = MergeNodeCommand.NodeLabels;
            getDraftRelationshipsQuery.IdPropertyName  = MergeNodeCommand.IdPropertyName;
            getDraftRelationshipsQuery.IdPropertyValue = _syncNameProvider.GetNodeIdPropertyValue(
                graphSyncPartContent, _previewContentItemVersion);

            IEnumerable <INodeWithOutgoingRelationships?> incomingContentPickerRelationshipsOrDefault =
                await _graphCluster.Run(_previewContentItemVersion.GraphReplicaSetName, getDraftRelationshipsQuery);

            #pragma warning disable S1905 // Sonar needs updating to know about nullable references
            return(incomingContentPickerRelationshipsOrDefault
                   .Where(n => n != null)
                   .Cast <INodeWithOutgoingRelationships>());

            #pragma warning restore S1905
        }
示例#2
0
        public GraphMergeContext(
            IMergeGraphSyncer mergeGraphSyncer,
            ISyncNameProvider syncNameProvider,
            IGraphReplicaSet graphReplicaSet,
            IMergeNodeCommand mergeNodeCommand,
            IReplaceRelationshipsCommand replaceRelationshipsCommand,
            ContentItem contentItem,
            IContentManager contentManager,
            IContentItemVersionFactory contentItemVersionFactory,
            IGraphMergeContext?parentGraphMergeContext,
            IServiceProvider serviceProvider)
            : base(
                contentItem,
                syncNameProvider,
                contentManager,
                contentItemVersionFactory.Get(graphReplicaSet.Name),
                parentGraphMergeContext,
                serviceProvider.GetRequiredService <ILogger <GraphMergeContext> >())
        {
            MergeGraphSyncer            = mergeGraphSyncer;
            GraphReplicaSet             = graphReplicaSet;
            MergeNodeCommand            = mergeNodeCommand;
            ReplaceRelationshipsCommand = replaceRelationshipsCommand;

            ExtraCommands = new List <ICommand>();
        }
        private async Task Sync(IEnumerable <ContentItem> contentItems, IGraphReplicaSet graphReplicaSet)
        {
            foreach (ContentItem contentItem in contentItems)
            {
                IMergeGraphSyncer mergeGraphSyncer = _serviceProvider.GetRequiredService <IMergeGraphSyncer>();

                //todo: we need to better handle disallowed and failed syncs
                // can we cancel the part/field detachment?
                //todo: support many items being updated in a transaction
                await mergeGraphSyncer.SyncToGraphReplicaSetIfAllowed(graphReplicaSet, contentItem, _contentManager);
            }
        }
示例#4
0
        public async Task <IAllowSync> SyncToGraphReplicaSetIfAllowed(
            IGraphReplicaSet graphReplicaSet,
            ContentItem contentItem,
            IContentManager contentManager,
            IGraphMergeContext?parentGraphMergeContext = null)
        {
            IAllowSync allowSync = await SyncAllowed(graphReplicaSet, contentItem, contentManager, parentGraphMergeContext);

            if (allowSync.Result == AllowSyncResult.Allowed)
            {
                await SyncToGraphReplicaSet();
            }

            return(allowSync);
        }
示例#5
0
        public async Task <IAllowSync> SyncAllowed(
            IGraphReplicaSet graphReplicaSet,
            ContentItem contentItem,
            IContentManager contentManager,
            IGraphMergeContext?parentGraphMergeContext = null)
        {
            _logger.LogDebug("SyncAllowed to {GraphReplicaSetName} for '{ContentItem}' {ContentType}?",
                             graphReplicaSet.Name, contentItem.ToString(), contentItem.ContentType);

            _logger.LogDebug("ContentItem content: {Content}", ((JObject)contentItem.Content).ToString());

            // we use the existence of a GraphSync content part as a marker to indicate that the content item should be synced
            JObject?graphSyncPartContent = (JObject?)contentItem.Content[nameof(GraphSyncPart)];

            if (graphSyncPartContent == null)
            {
                return(AllowSync.NotRequired);
            }

            //todo: ContentType belongs in the context, either combine helper & context, or supply context to helper?
            _syncNameProvider.ContentType = contentItem.ContentType;

            _graphMergeContext = new GraphMergeContext(
                this, _syncNameProvider, graphReplicaSet, MergeNodeCommand, _replaceRelationshipsCommand,
                contentItem, contentManager, _contentItemVersionFactory, parentGraphMergeContext, _serviceProvider);

            await PopulateMergeNodeCommand(graphSyncPartContent);

            SetSourceNodeInReplaceRelationshipsCommand();

            //should it go in the context?
            _incomingPreviewContentPickerRelationships = await GetIncomingPreviewContentPickerRelationshipsWhenPublishing(
                graphReplicaSet,
                graphSyncPartContent,
                contentItem.ContentItemId);

            return(await SyncAllowed());
        }
示例#6
0
        private async Task AttemptMergeRepair(
            ContentTypeDefinition contentTypeDefinition,
            IContentItemVersion contentItemVersion,
            ValidateAndRepairResult result,
            ValidationFailure failure)
        {
            var mergeGraphSyncer             = _serviceProvider.GetRequiredService <IMergeGraphSyncer>();
            IGraphReplicaSet graphReplicaSet = _currentGraph !.GetReplicaSetLimitedToThisGraph();

            try
            {
                await mergeGraphSyncer.SyncToGraphReplicaSetIfAllowed(graphReplicaSet, failure.ContentItem, _contentManager);
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "Repair of {ContentItem} in {GraphReplicaSet} failed.",
                                   failure.ContentItem, graphReplicaSet);
            }

            (bool validated, string?validationFailureReason) =
                await ValidateContentItem(failure.ContentItem, contentTypeDefinition, contentItemVersion);

            if (validated)
            {
                _logger.LogInformation("Repair was successful on {ContentType} {ContentItemId} in {CurrentGraph}.",
                                       failure.ContentItem.ContentType,
                                       failure.ContentItem.ContentItemId,
                                       GraphDescription(_currentGraph !));
                result.Repaired.Add(new ValidatedContentItem(failure.ContentItem));
            }
            else
            {
                string message = $"Repair was unsuccessful.{Environment.NewLine}{{ValidationFailureReason}}.";
                _logger.LogWarning(message, validationFailureReason);
                result.RepairFailures.Add(new RepairFailure(failure.ContentItem, validationFailureReason !));
            }
        }