Merge "add v16 to traversal repo"
[aai/traversal.git] / aai-traversal / src / main / java / org / onap / aai / rest / CQ2GremlinTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
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
10  *
11  *    http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20 package org.onap.aai.rest;
21
22
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;
28 import java.util.Map;
29 import java.util.Optional;
30 import java.util.concurrent.atomic.AtomicInteger;
31 import java.util.stream.Collectors;
32
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;
42
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;
68
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;
73
74
75 @Path("/cq2gremlintest")
76 public class CQ2GremlinTest extends RESTAPI {
77
78         private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(CQ2GremlinTest.class);
79
80         private HttpEntry traversalUriHttpEntry;
81
82
83         @Autowired
84         protected LoaderFactory loaderFactory;
85
86         @Autowired
87         protected EdgeSerializer rules;
88
89         protected Loader loader;
90         protected GraphTraversalSource gts;
91
92
93         @Autowired
94         public CQ2GremlinTest(
95                         HttpEntry traversalUriHttpEntry,
96                         @Value("${schema.uri.base.path}") String basePath
97                         ){
98                 this.traversalUriHttpEntry  = traversalUriHttpEntry;
99
100         }
101
102         @PUT
103         @Path("")
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 {
107                 if(content == null){
108                         return Response.status(HttpStatus.BAD_REQUEST.value()).entity("At least one Json payload should be passed").build();
109                 }
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);
117         }
118
119         private Response processC2UnitTest(CustomQueryTestDTO content) {
120
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<>();
128
129                 //Adding parameters
130                 content.getQueryRequiredProperties().forEach((K, V) -> {params.put(K, V);});
131                 content.getQueryOptionalProperties().forEach((K, V) -> {params.put(K, V);});
132
133                 String query = new GroovyQueryBuilder().executeTraversal(dbEngine, content.getStoredQuery(), params);
134                 query = "g" + query;
135                 GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
136                 addStartNode(g, content);
137                 params.put("g", g);
138
139                 //Assertion
140                 GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
141
142                 List<Vertex> vertices = result.toList();
143
144                 LOGGER.info("Expected result set of vertexes [{}]", convert(expectedVertices));
145                 LOGGER.info("Actual Result set of vertexes [{}]", convert(vertices));
146
147                 List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedVertices));
148                 vertices = new ArrayList<>(new HashSet<>(vertices));
149
150                 nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
151                 vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
152
153
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();
161                 }
162                 return Response.status(400).build();
163
164         }
165
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) -> {
176                                 if(index.get() == 1)
177                                         vertexIdentifier.append(V);
178                                 keyValues.add(K);
179                                 keyValues.add(V);
180                                 index.incrementAndGet();
181                         });
182                         Vertex graphVertex = graph.addVertex(keyValues.toArray());
183                         verticesMap.put(vertexIdentifier.toString(), graphVertex);
184                 });
185
186                 GraphTraversalSource g = graph.traversal();
187
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);
195                         try{
196                                 if(treeEdgeIdentifier){
197                                         rules.addTreeEdge(g, fromVertex, toVertex);
198                                 }
199                                 else{
200                                         rules.addEdge(g, fromVertex, toVertex);
201                                 }
202                         } catch(AAIException ex){
203                                 LOGGER.warn(ex.toString(), ex);
204                         }
205
206                 });
207
208
209                 List<Vertex> expectedVertices = Lists.newArrayList();
210                 content.getExpectedResultsDtos().getIds().stream().forEach(vertexId -> {
211                         expectedVertices.add(verticesMap.get(vertexId));
212                 });
213                 return expectedVertices;
214         }
215
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");
220                 }
221                 startNodeVertex.get().forEach((K, V) -> {
222                         g.has(K, V);
223                 });
224         }
225
226         protected String convert(List<Vertex> vertices){
227                 return vertices
228                                 .stream()
229                                 .map(vertex -> vertex.property("aai-node-type").value().toString())
230                                 .collect(Collectors.joining(","));
231         }
232
233
234
235 }