2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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=========================================================
21 package org.openecomp.aai.parsers.query;
23 import static org.hamcrest.CoreMatchers.containsString;
24 import static org.hamcrest.Matchers.hasProperty;
25 import static org.hamcrest.Matchers.is;
26 import static org.junit.Assert.assertEquals;
28 import java.io.UnsupportedEncodingException;
30 import java.util.ArrayList;
31 import java.util.List;
33 import javax.ws.rs.core.MultivaluedHashMap;
34 import javax.ws.rs.core.MultivaluedMap;
35 import javax.ws.rs.core.UriBuilder;
37 import org.apache.tinkerpop.gremlin.process.traversal.P;
38 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
39 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
40 import org.apache.tinkerpop.gremlin.structure.Vertex;
41 import org.junit.BeforeClass;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.rules.ExpectedException;
46 import org.openecomp.aai.db.props.AAIProperties;
47 import org.openecomp.aai.exceptions.AAIException;
48 import org.openecomp.aai.introspection.LoaderFactory;
49 import org.openecomp.aai.introspection.ModelType;
50 import org.openecomp.aai.introspection.Version;
51 import org.openecomp.aai.serialization.engines.QueryStyle;
52 import org.openecomp.aai.serialization.engines.TitanDBEngine;
53 import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
54 import org.openecomp.aai.serialization.queryformats.QueryFormatTestHelper;
55 import org.openecomp.aai.util.AAIConstants;
58 public class GraphTraversalTest {
60 private static TransactionalGraphEngine dbEngine;
62 private static TransactionalGraphEngine dbEnginev9;
65 public ExpectedException thrown = ExpectedException.none();
70 * @throws SecurityException
71 * @throws NoSuchFieldException
74 public static void configure() throws NoSuchFieldException, SecurityException, Exception {
75 System.setProperty("AJSC_HOME", "./src/test/resources/");
76 System.setProperty("BUNDLECONFIG_DIR", "bundleconfig-local");
77 QueryFormatTestHelper.setFinalStatic(AAIConstants.class.getField("AAI_HOME_ETC_OXM"), "src/test/resources/org/openecomp/aai/introspection/");
79 new TitanDBEngine(QueryStyle.TRAVERSAL,
80 LoaderFactory.createLoaderForVersion(ModelType.MOXY, AAIProperties.LATEST),
84 new TitanDBEngine(QueryStyle.TRAVERSAL,
85 LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.v9),
92 * @throws UnsupportedEncodingException the unsupported encoding exception
93 * @throws AAIException the AAI exception
96 public void parentQuery() throws UnsupportedEncodingException, AAIException {
97 URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1").build();
99 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
101 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start().has("physical-location-id", "key1").has("aai-node-type", "complex");
103 "gremlin query should be " + expected.toString(),
105 query.getQueryBuilder().getQuery().toString());
107 "parent gremlin query should be equal to normal query",
109 query.getQueryBuilder().getParentQuery().getQuery().toString());
111 "result type should be complex",
113 query.getResultType());
115 "result type should be empty",
117 query.getParentResultType());
118 assertEquals("dependent",false, query.isDependent());
126 * @throws UnsupportedEncodingException the unsupported encoding exception
127 * @throws AAIException the AAI exception
130 public void childQuery() throws UnsupportedEncodingException, AAIException {
131 URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/ctag-pools/ctag-pool/key2/key3").build();
132 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
133 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
134 .has("physical-location-id", "key1").has("aai-node-type", "complex")
136 .has("aai-node-type", "ctag-pool")
137 .has("target-pe", "key2").has("availability-zone-name", "key3");
138 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
139 .has("physical-location-id", "key1").has("aai-node-type", "complex");
141 "gremlin query should be " + expected.toString(),
143 query.getQueryBuilder().getQuery().toString());
145 "parent gremlin query should be equal the query for complex",
146 expectedParent.toString(),
147 query.getQueryBuilder().getParentQuery().getQuery().toString());
149 "result type should be complex",
151 query.getParentResultType());
153 "result type should be ctag-pool",
155 query.getResultType());
156 assertEquals("dependent",true, query.isDependent());
164 * @throws UnsupportedEncodingException the unsupported encoding exception
165 * @throws AAIException the AAI exception
168 public void namingExceptions() throws UnsupportedEncodingException, AAIException {
169 URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags/cvlan-tag/655").build();
170 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
171 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
172 .has("vnf-id", "key1").has("aai-node-type", "vce")
174 .has("aai-node-type", "port-group")
175 .has("interface-id", "key2").out("hasCTag")
176 .has("aai-node-type", "cvlan-tag")
177 .has("cvlan-tag", 655);
178 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
179 .has("vnf-id", "key1").has("aai-node-type", "vce")
181 .has("aai-node-type", "port-group")
182 .has("interface-id", "key2");
184 "gremlin query should be " + expected.toString(),
186 query.getQueryBuilder().getQuery().toString());
188 "parent gremlin query should be equal the query for port group",
189 expectedParent.toString(),
190 query.getQueryBuilder().getParentQuery().getQuery().toString());
192 "result type should be cvlan-tag",
194 query.getResultType());
196 "result type should be port-group",
198 query.getParentResultType());
200 "contaner type should be empty",
202 query.getContainerType());
203 assertEquals("dependent",true, query.isDependent());
212 * @throws UnsupportedEncodingException the unsupported encoding exception
213 * @throws AAIException the AAI exception
216 public void getAll() throws UnsupportedEncodingException, AAIException {
217 URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags").build();
218 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
219 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
220 .has("vnf-id", "key1").has("aai-node-type", "vce")
222 .has("aai-node-type", "port-group")
223 .has("interface-id", "key2").out("hasCTag")
224 .has("aai-node-type", "cvlan-tag");
225 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
226 .has("vnf-id", "key1").has("aai-node-type", "vce")
228 .has("aai-node-type", "port-group")
229 .has("interface-id", "key2");
231 "gremlin query should be " + expected.toString(),
233 query.getQueryBuilder().getQuery().toString());
235 "parent gremlin query should be equal the query for port group",
236 expectedParent.toString(),
237 query.getQueryBuilder().getParentQuery().getQuery().toString());
239 "result type should be port-group",
241 query.getParentResultType());
243 "result type should be cvlan-tag",
245 query.getResultType());
247 "container type should be cvlan-tags",
249 query.getContainerType());
250 assertEquals("dependent",true, query.isDependent());
256 public void getAllParent() throws UnsupportedEncodingException, AAIException {
257 URI uri = UriBuilder.fromPath("cloud-infrastructure/pservers").build();
258 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
259 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
260 .has("aai-node-type", "pserver");
261 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
262 .has("aai-node-type", "pserver");
264 "gremlin query should be " + expected.toString(),
266 query.getQueryBuilder().getQuery().toString());
268 "parent gremlin query should be equal the query for pserver",
269 expectedParent.toString(),
270 query.getQueryBuilder().getParentQuery().getQuery().toString());
272 "parent result type should be empty",
274 query.getParentResultType());
276 "result type should be pserver",
278 query.getResultType());
280 "container type should be pservers",
282 query.getContainerType());
283 assertEquals("dependent",false, query.isDependent());
290 * Gets the via query param.
292 * @return the via query param
293 * @throws UnsupportedEncodingException the unsupported encoding exception
294 * @throws AAIException the AAI exception
297 public void getViaQueryParam() throws UnsupportedEncodingException, AAIException {
298 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/mycloudowner/mycloudregionid/tenants/tenant").build();
299 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
300 map.putSingle("tenant-name", "Tenant1");
301 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
302 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
303 .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid")
304 .has("aai-node-type", "cloud-region")
306 .has("aai-node-type", "tenant")
307 .has("tenant-name", "Tenant1");
309 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
310 .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid")
311 .has("aai-node-type", "cloud-region");
314 "gremlin query should be " + expected.toString(),
316 query.getQueryBuilder().getQuery().toString());
318 "parent gremlin query should be equal the query for cloud-region",
319 expectedParent.toString(),
320 query.getQueryBuilder().getParentQuery().getQuery().toString());
322 "result type should be cloud-region",
324 query.getParentResultType());
326 "result type should be tenant",
328 query.getResultType());
330 "container type should be empty",
332 query.getContainerType());
333 assertEquals("dependent",true, query.isDependent());
338 public void getViaDuplicateQueryParam() throws UnsupportedEncodingException, AAIException {
339 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/mycloudowner/mycloudregionid/tenants/tenant").build();
340 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
341 List<String> values = new ArrayList<>();
342 values.add("Tenant1");
343 values.add("Tenant2");
344 map.put("tenant-name", values);
345 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
346 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
347 .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid")
348 .has("aai-node-type", "cloud-region")
350 .has("aai-node-type", "tenant")
351 .has("tenant-name", P.within(values));
353 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
354 .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid")
355 .has("aai-node-type", "cloud-region");
358 "gremlin query should be " + expected.toString(),
360 query.getQueryBuilder().getQuery().toString());
362 "parent gremlin query should be equal the query for cloud-region",
363 expectedParent.toString(),
364 query.getQueryBuilder().getParentQuery().getQuery().toString());
366 "result type should be cloud-region",
368 query.getParentResultType());
370 "result type should be tenant",
372 query.getResultType());
374 "container type should be empty",
376 query.getContainerType());
377 assertEquals("dependent",true, query.isDependent());
382 * Gets the plural via query param.
384 * @return the plural via query param
385 * @throws UnsupportedEncodingException the unsupported encoding exception
386 * @throws AAIException the AAI exception
389 public void getPluralViaQueryParam() throws UnsupportedEncodingException, AAIException {
390 URI uri = UriBuilder.fromPath("network/vnfcs").build();
391 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
392 map.putSingle("prov-status", "up");
393 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
394 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
395 .has("aai-node-type", "vnfc")
396 .has("prov-status", "up");
398 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
399 .has("aai-node-type", "vnfc");
402 "gremlin query should be " + expected.toString(),
404 query.getQueryBuilder().getQuery().toString());
407 expectedParent.toString(),
408 query.getQueryBuilder().getParentQuery().getQuery().toString());
410 "parent result type should be empty",
412 query.getParentResultType());
414 "result type should be vnfc",
416 query.getResultType());
418 "container type should be empty",
420 query.getContainerType());
421 assertEquals("dependent",true, query.isDependent());
426 * Gets the all query param naming exception.
428 * @return the all query param naming exception
429 * @throws UnsupportedEncodingException the unsupported encoding exception
430 * @throws AAIException the AAI exception
433 public void getAllQueryParamNamingException() throws UnsupportedEncodingException, AAIException {
434 URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags").build();
435 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
436 map.putSingle("cvlan-tag", "333");
437 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
439 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
440 .has("vnf-id", "key1").has("aai-node-type", "vce")
442 .has("aai-node-type", "port-group")
443 .has("interface-id", "key2").out("hasCTag")
444 .has("aai-node-type", "cvlan-tag")
445 .has("cvlan-tag", 333);
446 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
447 .has("vnf-id", "key1").has("aai-node-type", "vce")
449 .has("aai-node-type", "port-group")
450 .has("interface-id", "key2");
452 "gremlin query should be " + expected.toString(),
454 query.getQueryBuilder().getQuery().toString());
456 "parent gremlin query should be equal the query for port group",
457 expectedParent.toString(),
458 query.getQueryBuilder().getParentQuery().getQuery().toString());
460 "result type should be port-group",
462 query.getParentResultType());
464 "result type should be cvlan-tag",
466 query.getResultType());
468 "container type should be cvlan-tags",
470 query.getContainerType());
471 assertEquals("dependent",true, query.isDependent());
479 * @throws UnsupportedEncodingException the unsupported encoding exception
480 * @throws AAIException the AAI exception
483 public void abstractType() throws UnsupportedEncodingException, AAIException {
484 URI uri = UriBuilder.fromPath("vnf/key1").build();
486 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
488 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
489 .has("vnf-id", "key1").has(
490 AAIProperties.NODE_TYPE, P.within("vce" , "vpe" , "generic-vnf"));
492 GraphTraversal<Vertex, Vertex> expectedParent = expected;
494 "gremlin query should be " + expected.toString(),
496 query.getQueryBuilder().getQuery().toString());
498 "parent gremlin query should be equal the query for port group",
499 expectedParent.toString(),
500 query.getQueryBuilder().getParentQuery().getQuery().toString());
502 "result type should be empty",
504 query.getParentResultType());
506 "result type should be vnf",
508 query.getResultType());
510 assertEquals("dependent",false, query.isDependent());
516 * Non parent abstract type.
518 * @throws UnsupportedEncodingException the unsupported encoding exception
519 * @throws AAIException the AAI exception
522 public void nonParentAbstractType() throws UnsupportedEncodingException, AAIException {
523 URI uri = UriBuilder.fromPath("cloud-infrastructure/pservers/pserver/key2/vnf/key1").build();
524 thrown.expect(AAIException.class);
525 thrown.expectMessage(containsString("not a valid path"));
526 dbEngine.getQueryBuilder().createQueryFromURI(uri);
530 public void parentAbstractTypeWithNesting() throws UnsupportedEncodingException, AAIException {
531 URI uri = UriBuilder.fromPath("vnf/key1/vf-modules/vf-module/key2").build();
533 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
535 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
536 .has("vnf-id", "key1").has(AAIProperties.NODE_TYPE, P.within("vce", "vpe", "generic-vnf"))
537 .union(__.out("has").has("aai-node-type", "vf-module"))
538 .has("vf-module-id", "key2");
540 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
541 .has("vnf-id", "key1").has(AAIProperties.NODE_TYPE, P.within("vce", "vpe", "generic-vnf"));
543 "gremlin query should be " + expected.toString(),
545 query.getQueryBuilder().getQuery().toString());
547 "parent gremlin query should be equal the query for ",
548 expectedParent.toString(),
549 query.getQueryBuilder().getParentQuery().getQuery().toString());
551 "result type should be vnf",
553 query.getParentResultType());
555 "result type should be vf-module",
557 query.getResultType());
559 assertEquals("dependent",true, query.isDependent());
564 public void getViaBadQueryParam() throws UnsupportedEncodingException, AAIException {
565 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants/tenant").build();
566 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
567 map.putSingle("tenant-n231ame", "Tenant1");
568 thrown.expect(AAIException.class);
569 thrown.expect(hasProperty("code", is("AAI_3000")));
571 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
576 public void getPluralViaBadQueryParam() throws UnsupportedEncodingException, AAIException {
577 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants").build();
578 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
579 map.putSingle("tenant-n231ame", "Tenant1");
580 thrown.expect(AAIException.class);
581 thrown.expect(hasProperty("code", is("AAI_3000")));
583 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
588 public void getPluralViaDuplicateQueryParam() throws UnsupportedEncodingException, AAIException {
589 URI uri = UriBuilder.fromPath("network/vnfcs").build();
590 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
591 List<String> values = new ArrayList<>();
597 map.put("prov-status", values);
598 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
599 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
600 .has("aai-node-type", "vnfc")
601 .has("prov-status", P.within(values));
603 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
604 .has("aai-node-type", "vnfc");
607 "gremlin query should be " + expected.toString(),
609 query.getQueryBuilder().getQuery().toString());
612 expectedParent.toString(),
613 query.getQueryBuilder().getParentQuery().getQuery().toString());
615 "parent result type should be empty",
617 query.getParentResultType());
619 "result type should be vnfc",
621 query.getResultType());
623 "container type should be empty",
625 query.getContainerType());
626 assertEquals("dependent",true, query.isDependent());
631 public void dbAliasedSearch() throws UnsupportedEncodingException, AAIException {
632 URI uri = UriBuilder.fromPath("network/test-objects").build();
633 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
634 map.putSingle("persona-model-customization-id", "key2");
635 QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map);
636 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
637 .has("aai-node-type", "test-object")
638 .has("model-customization-id", "key2");
639 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
640 .has("aai-node-type", "test-object");
643 "gremlin query should be " + expected.toString(),
645 query.getQueryBuilder().getQuery().toString());
648 expectedParent.toString(),
649 query.getQueryBuilder().getParentQuery().getQuery().toString());
652 "result type should be",
654 query.getResultType());
656 "result type should be empty",
658 query.getParentResultType());
659 assertEquals("dependent",true, query.isDependent());
665 public void dataLinkedSearch() throws UnsupportedEncodingException, AAIException {
666 URI uri = UriBuilder.fromPath("network/vpn-bindings").build();
667 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
668 map.putSingle("global-route-target", "key2");
669 QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map);
670 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
671 .has("aai-node-type", "vpn-binding")
672 .where(__.out("has").has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "key2"));
673 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
674 .has("aai-node-type", "vpn-binding");
677 "gremlin query should be " + expected.toString(),
679 query.getQueryBuilder().getQuery().toString());
682 expectedParent.toString(),
683 query.getQueryBuilder().getParentQuery().getQuery().toString());
686 "result type should be",
688 query.getResultType());
690 "result type should be empty",
692 query.getParentResultType());
693 assertEquals("dependent",true, query.isDependent());