2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.onap.aai.rest;
22 import java.util.ArrayList;
23 import java.util.Comparator;
24 import java.util.HashSet;
25 import java.util.LinkedHashMap;
26 import java.util.List;
28 import java.util.Optional;
29 import java.util.concurrent.atomic.AtomicInteger;
30 import java.util.stream.Collectors;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.PUT;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.core.Context;
37 import javax.ws.rs.core.HttpHeaders;
38 import javax.ws.rs.core.MediaType;
39 import javax.ws.rs.core.Response;
40 import javax.ws.rs.core.UriInfo;
42 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
43 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
44 import org.apache.tinkerpop.gremlin.structure.Graph;
45 import org.apache.tinkerpop.gremlin.structure.T;
46 import org.apache.tinkerpop.gremlin.structure.Vertex;
47 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
48 import org.onap.aai.config.SpringContextAware;
49 import org.onap.aai.exceptions.AAIException;
50 import org.onap.aai.introspection.Loader;
51 import org.onap.aai.introspection.LoaderFactory;
52 import org.onap.aai.introspection.ModelType;
53 import org.onap.aai.rest.db.HttpEntry;
54 import org.onap.aai.rest.search.CustomQueryTestDTO;
55 import org.onap.aai.restcore.RESTAPI;
56 import org.onap.aai.restcore.search.GremlinGroovyShell;
57 import org.onap.aai.restcore.search.GroovyQueryBuilder;
58 import org.onap.aai.serialization.db.EdgeSerializer;
59 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
60 import org.onap.aai.setup.SchemaVersion;
61 import org.onap.aai.setup.SchemaVersions;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64 import org.springframework.beans.factory.annotation.Autowired;
65 import org.springframework.beans.factory.annotation.Value;
66 import org.springframework.http.HttpStatus;
67 import org.springframework.web.bind.annotation.RequestBody;
69 import com.beust.jcommander.internal.Lists;
70 import com.beust.jcommander.internal.Maps;
72 @Path("/cq2gremlintest")
73 public class CQ2GremlinTest extends RESTAPI {
75 private static final Logger LOGGER = LoggerFactory.getLogger(CQ2GremlinTest.class);
77 private HttpEntry traversalUriHttpEntry;
80 protected LoaderFactory loaderFactory;
83 protected EdgeSerializer rules;
85 protected Loader loader;
86 protected GraphTraversalSource gts;
89 public CQ2GremlinTest(HttpEntry traversalUriHttpEntry,
90 @Value("${schema.uri.base.path}") String basePath) {
91 this.traversalUriHttpEntry = traversalUriHttpEntry;
97 @Consumes({MediaType.APPLICATION_JSON})
98 @Produces({MediaType.APPLICATION_JSON})
99 public Response getC2Qgremlin(@RequestBody CustomQueryTestDTO content,
100 @Context HttpHeaders headers, @Context UriInfo info) throws AAIException {
101 if (content == null) {
102 return Response.status(HttpStatus.BAD_REQUEST.value())
103 .entity("At least one Json payload should be passed").build();
105 String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
106 String realTime = headers.getRequestHeaders().getFirst("Real-Time");
107 SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
108 traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
109 traversalUriHttpEntry.setPaginationParameters("-1", "-1");
110 return processC2UnitTest(content);
113 private Response processC2UnitTest(CustomQueryTestDTO content) {
115 TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
116 Graph graph = TinkerGraph.open();
117 gts = graph.traversal();
118 List<Vertex> expectedVertices = createGraph(content, graph);
119 GremlinGroovyShell shell = new GremlinGroovyShell();
120 loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion("v19"));
121 LinkedHashMap<String, Object> params = new LinkedHashMap<>();
124 content.getQueryRequiredProperties().forEach(params::put);
125 content.getQueryOptionalProperties().forEach(params::put);
128 new GroovyQueryBuilder().executeTraversal(dbEngine, content.getStoredQuery(), params);
130 GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
131 addStartNode(g, content);
135 GraphTraversal<Vertex, Vertex> result =
136 (GraphTraversal<Vertex, Vertex>) shell.executeTraversal(query, params);
138 List<Vertex> vertices = result.toList();
140 LOGGER.info("Expected result set of vertexes [{}]", convert(expectedVertices));
141 LOGGER.info("Actual Result set of vertexes [{}]", convert(vertices));
143 List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedVertices));
144 vertices = new ArrayList<>(new HashSet<>(vertices));
146 nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
147 vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
149 // Use this instead of the assertTrue as this provides more useful
150 // debugging information such as this when expected and actual differ:
151 // java.lang.AssertionError: Expected all the vertices to be found
152 // Expected :[v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
153 // 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]]
154 if (nonDuplicateExpectedResult.equals(vertices)) {
155 return Response.ok("Sucessfully executed Junit").build();
157 return Response.status(400).build();
161 private List<Vertex> createGraph(CustomQueryTestDTO content, Graph graph) {
162 Map<String, Vertex> verticesMap = Maps.newLinkedHashMap();
163 // Creating all the Vertices
164 content.getVerticesDtos().forEach(vertex -> {
165 StringBuilder vertexIdentifier = new StringBuilder();
166 List<String> keyValues = Lists.newArrayList();
167 keyValues.add(T.id.toString());
168 keyValues.add(String.format("%02d", verticesMap.size() * 10));
169 AtomicInteger index = new AtomicInteger(0);
170 vertex.forEach((k, v) -> {
171 if (index.get() == 1)
172 vertexIdentifier.append(k);
175 index.incrementAndGet();
177 Vertex graphVertex = graph.addVertex(keyValues.toArray());
178 verticesMap.put(vertexIdentifier.toString(), graphVertex);
181 GraphTraversalSource g = graph.traversal();
183 // Creating all the Edges
184 content.getEdgesDtos().forEach(edge -> {
185 String fromId = edge.get("from-id");
186 String toId = edge.get("to-id");
187 boolean treeEdgeIdentifier = !"NONE".equalsIgnoreCase(edge.get("contains-other-v"));
188 Vertex fromVertex = verticesMap.get(fromId);
189 Vertex toVertex = verticesMap.get(toId);
191 if (treeEdgeIdentifier) {
192 rules.addTreeEdge(g, fromVertex, toVertex);
194 rules.addEdge(g, fromVertex, toVertex);
196 } catch (AAIException ex) {
197 LOGGER.warn(ex.toString(), ex);
202 List<Vertex> expectedVertices = Lists.newArrayList();
203 content.getExpectedResultsDtos().getIds()
204 .forEach(vertexId -> expectedVertices.add(verticesMap.get(vertexId)));
205 return expectedVertices;
208 protected void addStartNode(GraphTraversal<Vertex, Vertex> g, CustomQueryTestDTO content) {
209 Optional<LinkedHashMap<String, String>> startNodeVertex = content.getVerticesDtos().stream()
210 .filter(map -> map.containsKey("start-node")).findFirst();
211 if (!startNodeVertex.isPresent()) {
212 throw new IllegalArgumentException("start-node was not specified");
214 startNodeVertex.get().forEach((k, v) -> {
219 protected String convert(List<Vertex> vertices) {
220 return vertices.stream().map(vertex -> vertex.property("aai-node-type").value().toString())
221 .collect(Collectors.joining(","));