Exemple #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
        }
        public async Task<IActionResult> SearchLookupNodes(string part, string content, string query)
        {
            if (string.IsNullOrWhiteSpace(part) || string.IsNullOrWhiteSpace(content))
            {
                return BadRequest("Part and content are required parameters");
            }

            var settings = _contentDefinitionManager
                .GetTypeDefinition(content)
                ?.Parts?.FirstOrDefault(p => p.Name == part)
                ?.GetSettings<GraphLookupPartSettings>();
            if (settings == null)
            {
                return BadRequest("Unable to find field settings");
            }

            //todo: interface and get from service provider
            //todo: add lookup graph to settings
            var results = await _neoGraphCluster.Run(GraphReplicaSetNames.Published, new LookupQuery(
                    query,
                    settings.NodeLabel!,        //todo: check can these be null (when no values entered in settings)?
                    settings.DisplayFieldName!,
                    settings.ValueFieldName!));

            return new ObjectResult(results);
        }
Exemple #3
0
        public async Task DeleteNodesByType(string graphReplicaSetName, string contentType)
        {
            if (string.IsNullOrWhiteSpace(contentType))
            {
                return;
            }

            _logger.LogInformation("Sync: deleting all nodes of {ContentType}", contentType);

            _syncNameProvider.ContentType = contentType;

            _deleteNodesByTypeCommand.NodeLabels.UnionWith(await _syncNameProvider.NodeLabels(contentType));

            try
            {
                await _graphCluster.Run(graphReplicaSetName, _deleteNodesByTypeCommand);
            }
            //todo: specify which exceptions to handle?
            catch
            {
                // this forces a rollback of the current OC db transaction
                _session.Cancel();
                throw;
            }
        }
Exemple #4
0
        public async Task <IQueryResults?> ExecuteQueryAsync(Query query, IDictionary <string, object> parameters)
        {
            if (!(query is CypherQuery cypherQuery))
            {
                return(null);
            }

            var parameterValues = BuildParameters(cypherQuery.Parameters, parameters);
            var result          = new CypherQueryResult();
            //todo: need to handle nulls
            var genericCypherQuery = new GenericCypherQuery(cypherQuery.Template !, parameterValues !);
            //todo: allow user to run queries against either graph. new story
            var cypherResult = await _neoGraphCluster.Run(GraphReplicaSetNames.Published, genericCypherQuery);

            if (cypherResult.Any())
            {
                var collections = cypherResult.FirstOrDefault();

                if (collections != null)
                {
                    result.Items = TransformResults(cypherQuery.ResultModelType, collections);
                }
            }

            return(result);
        }
        public async Task GraphConnectorRunReturnsSuccess(GraphReplicaSet graphReplicaSet)
        {
            // arrange
            var commands = new List <string>
            {
                "command one",
                "command two",
            };

            A.CallTo(() => fakeServiceProvider.GetService(typeof(ICustomCommand))).Returns(new CustomCommand());

            // act
            await graphConnector.RunAsync(commands, graphReplicaSet).ConfigureAwait(false);

            // assert
            A.CallTo(() => fakeServiceProvider.GetService(typeof(ICustomCommand))).MustHaveHappened(commands.Count, Times.Exactly);
            A.CallTo(() => fakeGraphCluster.Run(A <string> .Ignored, A <ICommand[]> .Ignored)).MustHaveHappenedOnceExactly();
            Assert.True(true);
        }
Exemple #6
0
        private async Task <IEnumerable <string> > ExecuteSynonymQueryAsync(MatchSynonymsQuery query)
        {
            List <IRecord> result = await _neoGraphCluster.Run(GraphReplicaSetNames.Published, query);

            //todo: (at least some of) this code belongs in the queries ProcessRecord()
            //todo: revisit null handling
            IReadOnlyDictionary <string, object>?synonymResults = (IReadOnlyDictionary <string, object>?)result.FirstOrDefault()?.Values["results"];

            return(((List <object>?)synonymResults?.Values.FirstOrDefault())?.OfType <string>() ?? Enumerable.Empty <string>());
        }
        private async Task <IEnumerable <string> > ExecuteSynonymQueryAsync(MatchSynonymsQuery query)
        {
            var result = await _neoGraphCluster.Run(GraphReplicaSetNames.Published, query);

            IReadOnlyDictionary <string, object> synonymResults = (IReadOnlyDictionary <string, object>)result.FirstOrDefault().Values["results"];

            var synonymList = ((List <object>)synonymResults.Values.FirstOrDefault()).OfType <string>();

            return(synonymList);
        }
        private async Task <string?> GetNodeValue(string id, GraphLookupPartSettings settings)
        {
            //todo: check if settings can be null
            //todo: interface and get from service provider
            //todo: add which graph to lookup to settings
            var results = await _graphCluster.Run(GraphReplicaSetNames.Published, new GetPropertyOnNodeQuery(
                                                      settings.NodeLabel !,
                                                      settings.ValueFieldName !,
                                                      id,
                                                      settings.DisplayFieldName !));

            return(results.First());
        }
        private async Task <IEnumerable <IRecord> > ExecuteCypherQuery(string query, ILogger log)
        {
            log.LogInformation($"Attempting to query neo4j with the following query: {query}");

            try
            {
                return(await _graphCluster.Run("target", new GenericCypherQuery(query)));
            }
            catch (Exception ex)
            {
                throw ApiFunctionException.InternalServerError("Unable To run query", ex);
            }
        }
Exemple #10
0
        public async Task <List <TModel> > ExecuteCypherQuery <TModel>(GraphReplicaSet graphReplicaSet, string query)
            where TModel : class, new()
        {
            string replicaSetName = graphReplicaSet switch
            {
                GraphReplicaSet.Published => graphOptions.PublishedReplicaSetName,
                GraphReplicaSet.Draft => graphOptions.DraftReplicaSetName,
                _ => throw new NotImplementedException(),
            };

            var result = await graphCluster.Run(replicaSetName, new GenericCypherQueryModel <TModel>(query)).ConfigureAwait(false);

            return(result);
        }
Exemple #11
0
        public async Task Execute_GetAllPages_ReturnsCorrectJsonResponse()
        {
            var recordJsonInput    = File.ReadAllText(Directory.GetCurrentDirectory() + "/Files/Input/PageRecordInput_GetAll.json");
            var expectedJsonOutput = File.ReadAllText(Directory.GetCurrentDirectory() + "/Files/Output/PageRecordOutput_GetAll.json");

            A.CallTo(() => _graphCluster.Run(A <string> .Ignored, A <GenericCypherQuery> .Ignored)).Returns(new List <IRecord>()
            {
                new Api.Content.UnitTests.Models.Record(new string[] { "data.properties" }, new object[] { JsonConvert.DeserializeObject <Dictionary <string, object> >(recordJsonInput.ToString()) })
            });

            var result = await RunFunction("test1", null);

            var okObjectResult = result as OkObjectResult;

            // Assert
            Assert.True(result is OkObjectResult);

            var resultJson = JsonConvert.SerializeObject(okObjectResult.Value);

            var equal = JToken.DeepEquals(JToken.Parse(expectedJsonOutput), JToken.Parse(resultJson));

            Assert.True(equal);
        }
Exemple #12
0
        public async Task RunAsync(IList <string>?commands)
        {
            _ = commands ?? throw new ArgumentNullException(nameof(commands));

            var customCommands = new List <ICustomCommand>();

            foreach (var command in commands)
            {
                var customCommand = serviceProvider.GetRequiredService <ICustomCommand>();
                customCommand.Command = command;
                customCommands.Add(customCommand);
            }

            await graphCluster.Run(graphOptions.ReplicaSetName, customCommands.ToArray()).ConfigureAwait(false);
        }
        public async Task <Subgraph> GetVisualisationSubgraph(
            string contentItemId,
            string graphName,
            IContentItemVersion contentItemVersion)
        {
            var relationshipCommands = await BuildVisualisationCommands(contentItemId, contentItemVersion !);

            // get all results atomically
            var result = await _neoGraphCluster.Run(graphName, relationshipCommands.ToArray());

            var inAndOutResults =
                result.OfType <INodeAndOutRelationshipsAndTheirInRelationships?>();

            //todo: should really always return the source node (until then, the subgraph will pull it if the main results don't)
            Subgraph subgraph;

            if (inAndOutResults.Any())
            {
                // get all outgoing relationships from the query and add in any source nodes

                subgraph = new Subgraph(
                    inAndOutResults
                    .SelectMany(x => x !.OutgoingRelationships.Select(x => x.outgoingRelationship.DestinationNode))
                    .Union(inAndOutResults.GroupBy(x => x !.SourceNode).Select(z => z.FirstOrDefault() !.SourceNode)),
                    inAndOutResults !
                    .SelectMany(y => y !.OutgoingRelationships.Select(z => z.outgoingRelationship.Relationship))
                    .ToHashSet(),
                    inAndOutResults.FirstOrDefault()?.SourceNode);
            }
            else
            {
                subgraph = new Subgraph();
            }

            ISubgraph?inResults = result.OfType <ISubgraph>().FirstOrDefault();

            if (inResults != null)
            {
                subgraph.Add(inResults);
            }

            return(subgraph);
        }
        public async Task RunAsync(IList <string>?commands, GraphReplicaSet graphReplicaSet)
        {
            _ = commands ?? throw new ArgumentNullException(nameof(commands));
            string replicaSetName = graphReplicaSet switch
            {
                GraphReplicaSet.Published => graphOptions.PublishedReplicaSetName,
                GraphReplicaSet.Draft => graphOptions.DraftReplicaSetName,
                _ => throw new NotImplementedException(),
            };
            var customCommands = new List <ICustomCommand>();

            foreach (var command in commands)
            {
                var customCommand = serviceProvider.GetRequiredService <ICustomCommand>();
                customCommand.Command = command;
                customCommands.Add(customCommand);
            }

            await graphCluster.Run(replicaSetName, customCommands.ToArray()).ConfigureAwait(false);
        }