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;
23 import java.util.ArrayList;
24 import java.util.Comparator;
25 import java.util.HashSet;
26 import java.util.LinkedHashMap;
27 import java.util.List;
29 import java.util.Optional;
30 import java.util.concurrent.atomic.AtomicInteger;
31 import java.util.stream.Collectors;
33 import javax.ws.rs.Consumes;
34 import javax.ws.rs.PUT;
35 import javax.ws.rs.Path;
36 import javax.ws.rs.Produces;
37 import javax.ws.rs.core.Context;
38 import javax.ws.rs.core.HttpHeaders;
39 import javax.ws.rs.core.MediaType;
40 import javax.ws.rs.core.Response;
41 import javax.ws.rs.core.UriInfo;
43 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
44 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
45 import org.apache.tinkerpop.gremlin.structure.Graph;
46 import org.apache.tinkerpop.gremlin.structure.T;
47 import org.apache.tinkerpop.gremlin.structure.Vertex;
48 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
49 import org.onap.aai.config.SpringContextAware;
50 import org.onap.aai.dbmap.DBConnectionType;
51 import org.onap.aai.exceptions.AAIException;
52 import org.onap.aai.introspection.Loader;
53 import org.onap.aai.introspection.LoaderFactory;
54 import org.onap.aai.introspection.ModelType;
55 import org.onap.aai.rest.db.HttpEntry;
56 import org.onap.aai.rest.search.CustomQueryTestDTO;
57 import org.onap.aai.restcore.RESTAPI;
58 import org.onap.aai.restcore.search.GremlinGroovyShell;
59 import org.onap.aai.restcore.search.GroovyQueryBuilder;
60 import org.onap.aai.serialization.db.EdgeSerializer;
61 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
62 import org.onap.aai.setup.SchemaVersion;
63 import org.onap.aai.setup.SchemaVersions;
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.att.eelf.configuration.EELFLogger;
70 import com.att.eelf.configuration.EELFManager;
71 import com.beust.jcommander.internal.Lists;
72 import com.beust.jcommander.internal.Maps;
75 @Path("/cq2gremlintest")
76 public class CQ2GremlinTest extends RESTAPI {
78 private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(CQ2GremlinTest.class);
80 private HttpEntry traversalUriHttpEntry;
84 protected LoaderFactory loaderFactory;
87 protected EdgeSerializer rules;
89 protected Loader loader;
90 protected GraphTraversalSource gts;
94 public CQ2GremlinTest(
95 HttpEntry traversalUriHttpEntry,
96 @Value("${schema.uri.base.path}") String basePath
98 this.traversalUriHttpEntry = traversalUriHttpEntry;
104 @Consumes({ MediaType.APPLICATION_JSON })
105 @Produces({ MediaType.APPLICATION_JSON })
106 public Response getC2Qgremlin(@RequestBody CustomQueryTestDTO content,@Context HttpHeaders headers, @Context UriInfo info) throws AAIException {
108 return Response.status(HttpStatus.BAD_REQUEST.value()).entity("At least one Json payload should be passed").build();
110 String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
111 String realTime = headers.getRequestHeaders().getFirst("Real-Time");
112 SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
113 DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
114 traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), type);
115 traversalUriHttpEntry.setPaginationParameters("-1", "-1");
116 return processC2UnitTest(content);
119 private Response processC2UnitTest(CustomQueryTestDTO content) {
121 TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
122 Graph graph = TinkerGraph.open();
123 gts = graph.traversal();
124 List<Vertex> expectedVertices = createGraph(content, graph);
125 GremlinGroovyShell shell = new GremlinGroovyShell();
126 loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion("v16"));
127 LinkedHashMap <String, Object> params = new LinkedHashMap<>();
130 content.getQueryRequiredProperties().forEach((K, V) -> {params.put(K, V);});
131 content.getQueryOptionalProperties().forEach((K, V) -> {params.put(K, V);});
133 String query = new GroovyQueryBuilder().executeTraversal(dbEngine, content.getStoredQuery(), params);
135 GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
136 addStartNode(g, content);
140 GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
142 List<Vertex> vertices = result.toList();
144 LOGGER.info("Expected result set of vertexes [{}]", convert(expectedVertices));
145 LOGGER.info("Actual Result set of vertexes [{}]", convert(vertices));
147 List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedVertices));
148 vertices = new ArrayList<>(new HashSet<>(vertices));
150 nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
151 vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
154 // Use this instead of the assertTrue as this provides more useful
155 // debugging information such as this when expected and actual differ:
156 // java.lang.AssertionError: Expected all the vertices to be found
157 // Expected :[v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
158 // 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]]
159 if(nonDuplicateExpectedResult.equals(vertices)){
160 return Response.ok("Sucessfully executed Junit").build();
162 return Response.status(400).build();
166 private List<Vertex> createGraph(CustomQueryTestDTO content, Graph graph) {
167 Map<String, Vertex> verticesMap = Maps.newLinkedHashMap();
168 //Creating all the Vertices
169 content.getVerticesDtos().stream().forEach(vertex -> {
170 StringBuilder vertexIdentifier = new StringBuilder();
171 List<String> keyValues = Lists.newArrayList();
172 keyValues.add(T.id.toString());
173 keyValues.add(String.format("%02d", verticesMap.size() * 10));
174 AtomicInteger index = new AtomicInteger(0);
175 vertex.forEach((K, V) -> {
177 vertexIdentifier.append(V);
180 index.incrementAndGet();
182 Vertex graphVertex = graph.addVertex(keyValues.toArray());
183 verticesMap.put(vertexIdentifier.toString(), graphVertex);
186 GraphTraversalSource g = graph.traversal();
188 //Creating all the Edges
189 content.getEdgesDtos().stream().forEach(edge -> {
190 String fromId = edge.get("from-id");
191 String toId = edge.get("to-id");
192 boolean treeEdgeIdentifier = !"NONE".equalsIgnoreCase(edge.get("contains-other-v"));
193 Vertex fromVertex = verticesMap.get(fromId);
194 Vertex toVertex = verticesMap.get(toId);
196 if(treeEdgeIdentifier){
197 rules.addTreeEdge(g, fromVertex, toVertex);
200 rules.addEdge(g, fromVertex, toVertex);
202 } catch(AAIException ex){
203 LOGGER.warn(ex.toString(), ex);
209 List<Vertex> expectedVertices = Lists.newArrayList();
210 content.getExpectedResultsDtos().getIds().stream().forEach(vertexId -> {
211 expectedVertices.add(verticesMap.get(vertexId));
213 return expectedVertices;
216 protected void addStartNode(GraphTraversal<Vertex, Vertex> g, CustomQueryTestDTO content) {
217 Optional<LinkedHashMap<String, String>> startNodeVertex = content.getVerticesDtos().stream().filter(map -> map.containsKey("start-node")).findFirst();
218 if(!startNodeVertex.isPresent()){
219 throw new IllegalArgumentException("start-node was not specified");
221 startNodeVertex.get().forEach((K, V) -> {
226 protected String convert(List<Vertex> vertices){
229 .map(vertex -> vertex.property("aai-node-type").value().toString())
230 .collect(Collectors.joining(","));