Add to traversal custom query to get parent path 55/39855/2
authorMaharajh, Robby (rx2202) <rx2202@us.att.com>
Fri, 23 Mar 2018 18:23:40 +0000 (14:23 -0400)
committerMaharajh, Robby (rx2202) <rx2202@att.com>
Wed, 28 Mar 2018 23:18:18 +0000 (19:18 -0400)
Issue-ID: AAI-963
Change-Id: I3b323a42519de29980337ab80d9d0b68f16878c3
Signed-off-by: Maharajh, Robby (rx2202) <rx2202@att.com>
aai-traversal/src/main/resources/etc/query/stored-queries.json
aai-traversal/src/test/java/org/onap/aai/rest/search/ContainmentPathQueryTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/CountVnfByVnfTypeTest.java
aai-traversal/src/test/java/org/onap/aai/rest/search/PathQueryTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/QueryCountTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/QueryTest.java
aai-traversal/src/test/java/org/onap/aai/rest/search/TreeQueryTest.java [new file with mode: 0644]

index 6c61246..d511e5a 100644 (file)
     "gfp-vnf-data":{ 
       "stored-query":"builder.store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'l-interface').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE,   'l-interface', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'l3-interface-ipv6-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').store('x').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list').store('x'))),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'generic-vnf', 'lag-interface').createEdgeTraversal(EdgeType.TREE, 'lag-interface', 'l-interface').store('x').createEdgeTraversal(EdgeType.TREE, 'l-interface', 'vlan').union(builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv4-address-list').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'vlan', 'l3-interface-ipv6-address-list').store('x')),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'vnf-image').store('x'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf', 'network-profile').store('x')).cap('x').unfold().dedup()"
     }
-  }]
-}
\ No newline at end of file
+  },{
+    "containment-path":{
+      "stored-query":"builder.until(builder.newInstance().not(builder.newInstance().getParentEdge())).repeat(builder.newInstance().getParentVertex()).path()"
+    }
+  }
+  ]
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/ContainmentPathQueryTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/ContainmentPathQueryTest.java
new file mode 100644 (file)
index 0000000..01ba701
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest.search;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.Test;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
+
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+public class ContainmentPathQueryTest extends PathQueryTest {
+
+    public ContainmentPathQueryTest() throws AAIException, NoEdgeRuleFoundException {
+        super();
+    }
+
+    @Override
+    protected void createGraph() throws AAIException, NoEdgeRuleFoundException {
+        Vertex pnf1 = graph.addVertex(T.label, "pnf", T.id, "0", "aai-node-type", "pnf", "pnf-name", "pnf-1");
+        Vertex pInterface1 = graph.addVertex(T.label, "p-interface", T.id, "1", "aai-node-type", "p-interface", "interface-name", "p-interface-1");
+        Vertex lInterface1 = graph.addVertex(T.label, "l-interface", T.id, "2", "aai-node-type", "l-interface", "interface-name", "l-interface-1");
+        Vertex vlan1 = graph.addVertex(T.label, "vlan", T.id, "3", "aai-node-type", "vlan", "vlan-interface", "vlan-1");
+
+        rules.addTreeEdge(gts, pnf1, pInterface1);
+        rules.addTreeEdge(gts, pInterface1, lInterface1);
+        rules.addTreeEdge(gts, lInterface1, vlan1);
+    }
+
+    @Test
+    public void vlanPathTest() {
+        super.run();
+        assertEquals("1 path is returned ",1, pathList.size());
+        Path path = pathList.get(0);
+
+        Vertex pnf1 = graph.traversal().V().has("aai-node-type", "pnf").has("pnf-name", "pnf-1").next();
+        Vertex pInterface1 = graph.traversal().V().has("aai-node-type", "p-interface").has("interface-name", "p-interface-1").next();
+        Vertex lInterface1 = graph.traversal().V().has("aai-node-type", "l-interface").has("interface-name", "l-interface-1").next();
+        Vertex vlan1 = graph.traversal().V().has("aai-node-type", "vlan").has("vlan-interface", "vlan-1").next();
+
+        //remoce edges
+        assertThat(path.objects().stream().filter(o -> o instanceof Vertex).collect(Collectors.toList()), contains(vlan1, lInterface1, pInterface1, pnf1));
+
+    }
+
+    @Override
+    protected String getQueryName() {
+        return "containment-path";
+    }
+
+    @Override
+    protected void addStartNode(GraphTraversal<Vertex, Vertex> g) {
+        g.has("aai-node-type", "vlan").has("vlan-interface", "vlan-1");
+    }
+
+    @Override
+    protected void addParam(Map<String, Object> params) {
+
+    }
+}
index 75e0784..3ec0886 100644 (file)
 */
 package org.onap.aai.rest.search;
 
-import static org.junit.Assert.*;
-
-import java.util.HashMap;
-import java.util.Map;
-
+import com.google.common.collect.ImmutableMap;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.junit.Test;
 import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
 
-public class CountVnfByVnfTypeTest extends QueryTest {
+import java.util.ArrayList;
+import java.util.Map;
 
-       public CountVnfByVnfTypeTest() throws AAIException, NoEdgeRuleFoundException {
+public class CountVnfByVnfTypeTest extends QueryCountTest {
+
+       public CountVnfByVnfTypeTest() throws AAIException {
                super();
     }
 
     @Test
     public void test() {
-       super.run(true);
+       super.run();
     }
 
     @Override
-       protected void createGraph() throws AAIException, NoEdgeRuleFoundException {
+       protected void createGraph() throws AAIException {
                //Set up the test graph
            Vertex genericVnfTypeA1 = graph.addVertex(T.label, "genric-vnf", T.id, "1", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-1", "vnf-name", "vnf-name-1", "vnf-type", "A");
            Vertex genericVnfTypeB1 = graph.addVertex(T.label, "genric-vnf", T.id, "2", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-2", "vnf-name", "vnf-name-2", "vnf-type", "B");
@@ -76,8 +74,12 @@ public class CountVnfByVnfTypeTest extends QueryTest {
            Vertex genericVnfTypeA4 = graph.addVertex(T.label, "genric-vnf", T.id, "7", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-7", "vnf-name", "vnf-name-7", "vnf-type", "A");
            
            GraphTraversalSource g = graph.traversal();
-           
-           expectedResultForMaps = expectedResultForMaps + "[A=4, B=2, C=1]";
+
+               listOfMapEntryForCoutnQueries = new ArrayList<>();
+               listOfMapEntryForCoutnQueries.add(ImmutableMap.of("A", 4L).entrySet().iterator().next());
+               listOfMapEntryForCoutnQueries.add(ImmutableMap.of("B", 2L).entrySet().iterator().next());
+               listOfMapEntryForCoutnQueries.add(ImmutableMap.of("C", 1L).entrySet().iterator().next());
+               //expectedResultForMaps = expectedResultForMaps + "[A=4, B=2, C=1]";
        }
 
     @Override
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/PathQueryTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/PathQueryTest.java
new file mode 100644 (file)
index 0000000..5e1b729
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest.search;
+
+import org.apache.tinkerpop.gremlin.process.traversal.Path;
+import org.onap.aai.exceptions.AAIException;
+
+import java.util.List;
+
+public abstract class PathQueryTest extends QueryTest {
+
+       protected List<Path> pathList;
+
+       public PathQueryTest() throws AAIException {
+               super();
+       }
+
+       @Override
+       public void run() {
+               pathList = (List<Path>)shell.executeTraversal(query, params).toList();
+       }
+}
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/QueryCountTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/QueryCountTest.java
new file mode 100644 (file)
index 0000000..13e3953
--- /dev/null
@@ -0,0 +1,52 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest.search;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.onap.aai.exceptions.AAIException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+public abstract class QueryCountTest extends QueryTest {
+
+       //listOfMapEntryForCoutnQueries is for when the query returns a HashMap, not a Vertex
+       protected List<Map.Entry<String, Long>> listOfMapEntryForCoutnQueries;
+
+
+       public QueryCountTest() throws AAIException {
+               super();
+       }
+
+       @Override
+       public void run() {
+               GraphTraversal<HashMap<String,Long>, HashMap<String,Long>> result = (GraphTraversal<HashMap<String,Long>, HashMap<String,Long>>)shell.executeTraversal(query, params);
+
+               assertThat("all hash maps found", listOfMapEntryForCoutnQueries, is(result.toList()));
+
+       }
+
+}
index 626c9de..f9e467c 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * org.onap.aai
  * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
  */
 package org.onap.aai.rest.search;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsInAnyOrder;
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.when;
-
-import java.util.*;
-import java.util.stream.Collector;
-import java.util.stream.Collectors;
-
 import com.att.eelf.configuration.EELFLogger;
 import com.att.eelf.configuration.EELFManager;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Graph;
 import org.apache.tinkerpop.gremlin.structure.Vertex;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
@@ -46,48 +36,55 @@ import org.onap.aai.introspection.LoaderFactory;
 import org.onap.aai.introspection.ModelType;
 import org.onap.aai.introspection.Version;
 import org.onap.aai.query.builder.GremlinTraversal;
+import org.onap.aai.restcore.search.GremlinGroovyShellSingleton;
 import org.onap.aai.serialization.db.EdgeRules;
 import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
 import org.onap.aai.serialization.engines.QueryStyle;
 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
 
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.when;
+
 public abstract class QueryTest {
 
-       private EELFLogger logger;
+       protected EELFLogger logger;
        protected Graph graph;
-       private GremlinServerSingleton gremlinServerSingleton;
-       private GremlinGroovyShellSingleton shell;
-       @Mock private TransactionalGraphEngine dbEngine;
+       protected GremlinServerSingleton gremlinServerSingleton;
+       protected GremlinGroovyShellSingleton shell;
+       @Mock protected TransactionalGraphEngine dbEngine;
        protected final List<Vertex> expectedResult = new ArrayList<>();
-       //expectedResultForMaps is for when the query returns a HashMap, not a Vertex
-       protected String expectedResultForMaps = new String();
        protected final EdgeRules rules = EdgeRules.getInstance();
        protected Loader loader;
-       
+       protected GraphTraversalSource gts;
+
+       protected String query;
+       LinkedHashMap <String, Object> params;
+
        public QueryTest() throws AAIException, NoEdgeRuleFoundException {
                setUp();
                logger = EELFManager.getInstance().getLogger(getClass());
+               setUpQuery();
        }
 
-       public void setUp() throws AAIException, NoEdgeRuleFoundException {
+       protected void setUp() throws AAIException, NoEdgeRuleFoundException {
                System.setProperty("AJSC_HOME", ".");
                System.setProperty("BUNDLECONFIG_DIR", "src/main/resources");
                MockitoAnnotations.initMocks(this);
                graph = TinkerGraph.open();
+               gts = graph.traversal();
                createGraph();
                gremlinServerSingleton = GremlinServerSingleton.getInstance();
                shell = GremlinGroovyShellSingleton.getInstance();
                loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.getLatest());
        }
-       
-       public void run() {
-               this.run(false);
-       }
-       
-       public void run(boolean isHashMap) {
-               
-               String query = gremlinServerSingleton.getStoredQueryFromConfig(getQueryName());
-               Map<String, Object> params = new HashMap<>();
+
+       protected void setUpQuery() {
+               query = gremlinServerSingleton.getStoredQueryFromConfig(getQueryName());
+               params = new LinkedHashMap <>();
                addParam(params);
                when(dbEngine.getQueryBuilder(any(QueryStyle.class))).thenReturn(new GremlinTraversal<>(loader, graph.traversal()));
                logger.info("Stored query in abstraction form {}", query);
@@ -97,39 +94,34 @@ public abstract class QueryTest {
                GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
                addStartNode(g);
                params.put("g", g);
-               
-               //Certain custom queries return HashMaps instead of Vertex; different code must used for both cases to avoid a ClassCastException
-               if(!isHashMap) {
-                       GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
-                       
-                       List<Vertex> vertices = result.toList();
-
-                       logger.info("Expected result set of vertexes [{}]", convert(expectedResult));
-                       logger.info("Actual Result set of vertexes [{}]", convert(vertices));
-
-                       List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedResult));
-                       vertices = new ArrayList<>(new HashSet<>(vertices));
-
-                       nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
-                       vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
-
-                       // Use this instead of the assertTrue as this provides more useful
-                       // debugging information such as this when expected and actual differ:
-                       // java.lang.AssertionError: Expected all the vertices to be found
-                       // Expected :[v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
-                       // Actual   :[v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
-                       assertEquals("Expected all the vertices to be found", nonDuplicateExpectedResult, vertices);
-               }
-               else {
-                       GraphTraversal<HashMap<String,Long>, HashMap<String,Long>> result = (GraphTraversal<HashMap<String,Long>, HashMap<String,Long>>)shell.executeTraversal(query, params);
-                       
-                       String map = result.toList().toString();
-                       System.out.println(map);
-                       assertTrue("all hash maps found", map.equals(expectedResultForMaps) && expectedResultForMaps.equals(map));                      
-               }
        }
 
-       private String convert(List<Vertex> vertices){
+       public void run() {
+
+               GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
+
+               List<Vertex> vertices = result.toList();
+
+               logger.info("Expected result set of vertexes [{}]", convert(expectedResult));
+               logger.info("Actual Result set of vertexes [{}]", convert(vertices));
+
+               List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedResult));
+               vertices = new ArrayList<>(new HashSet<>(vertices));
+
+               nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
+               vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
+
+
+               // Use this instead of the assertTrue as this provides more useful
+               // debugging information such as this when expected and actual differ:
+               // java.lang.AssertionError: Expected all the vertices to be found
+               // Expected :[v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
+               // Actual   :[v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
+               assertEquals("Expected all the vertices to be found", nonDuplicateExpectedResult, vertices);
+
+       }
+
+       protected String convert(List<Vertex> vertices){
                return vertices
                                .stream()
                                .map(vertex -> vertex.property("aai-node-type").value().toString())
@@ -143,4 +135,5 @@ public abstract class QueryTest {
        protected abstract void addStartNode(GraphTraversal<Vertex, Vertex> g);
        
        protected abstract void addParam(Map<String, Object> params);
+
 }
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/TreeQueryTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/TreeQueryTest.java
new file mode 100644 (file)
index 0000000..1ec880c
--- /dev/null
@@ -0,0 +1,41 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest.search;
+
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import org.onap.aai.exceptions.AAIException;
+
+import java.util.List;
+
+public abstract class TreeQueryTest extends QueryTest {
+
+       protected List<Tree> treeList;
+
+       public TreeQueryTest() throws AAIException {
+               super();
+       }
+
+       @Override
+       public void run() {
+               treeList = (List<Tree>)shell.executeTraversal(query, params).toList();
+       }
+}