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").or(
490 __.has(AAIProperties.NODE_TYPE, "vce"),
491 __.has(AAIProperties.NODE_TYPE, "vpe"),
492 __.has(AAIProperties.NODE_TYPE, "generic-vnf"));
494 GraphTraversal<Vertex, Vertex> expectedParent = expected;
496 "gremlin query should be " + expected.toString(),
498 query.getQueryBuilder().getQuery().toString());
500 "parent gremlin query should be equal the query for port group",
501 expectedParent.toString(),
502 query.getQueryBuilder().getParentQuery().getQuery().toString());
504 "result type should be empty",
506 query.getParentResultType());
508 "result type should be vnf",
510 query.getResultType());
512 assertEquals("dependent",false, query.isDependent());
518 * Non parent abstract type.
520 * @throws UnsupportedEncodingException the unsupported encoding exception
521 * @throws AAIException the AAI exception
524 public void nonParentAbstractType() throws UnsupportedEncodingException, AAIException {
525 URI uri = UriBuilder.fromPath("cloud-infrastructure/pservers/pserver/key2/vnf/key1").build();
526 thrown.expect(AAIException.class);
527 thrown.expectMessage(containsString("not a valid path"));
528 dbEngine.getQueryBuilder().createQueryFromURI(uri);
532 public void parentAbstractTypeWithNesting() throws UnsupportedEncodingException, AAIException {
533 URI uri = UriBuilder.fromPath("vnf/key1/vf-modules/vf-module/key2").build();
535 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri);
537 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
538 .has("vnf-id", "key1").or(
539 __.has(AAIProperties.NODE_TYPE, "vce"),
540 __.has(AAIProperties.NODE_TYPE, "vpe"),
541 __.has(AAIProperties.NODE_TYPE, "generic-vnf"))
542 .filter(x -> true).outE().has("isParent", true).inV().has("vf-module-id", "key2");
544 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
545 .has("vnf-id", "key1").or(
546 __.has(AAIProperties.NODE_TYPE, "vce"),
547 __.has(AAIProperties.NODE_TYPE, "vpe"),
548 __.has(AAIProperties.NODE_TYPE, "generic-vnf"));
550 "gremlin query should be " + expected.toString(),
552 query.getQueryBuilder().getQuery().toString());
554 "parent gremlin query should be equal the query for ",
555 expectedParent.toString(),
556 query.getQueryBuilder().getParentQuery().getQuery().toString());
558 "result type should be vnf",
560 query.getParentResultType());
562 "result type should be vf-module",
564 query.getResultType());
566 assertEquals("dependent",true, query.isDependent());
571 public void getViaBadQueryParam() throws UnsupportedEncodingException, AAIException {
572 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants/tenant").build();
573 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
574 map.putSingle("tenant-n231ame", "Tenant1");
575 thrown.expect(AAIException.class);
576 thrown.expect(hasProperty("code", is("AAI_3000")));
578 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
583 public void getPluralViaBadQueryParam() throws UnsupportedEncodingException, AAIException {
584 URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants").build();
585 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
586 map.putSingle("tenant-n231ame", "Tenant1");
587 thrown.expect(AAIException.class);
588 thrown.expect(hasProperty("code", is("AAI_3000")));
590 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
595 public void getPluralViaDuplicateQueryParam() throws UnsupportedEncodingException, AAIException {
596 URI uri = UriBuilder.fromPath("network/vnfcs").build();
597 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
598 List<String> values = new ArrayList<>();
604 map.put("prov-status", values);
605 QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map);
606 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
607 .has("aai-node-type", "vnfc")
608 .has("prov-status", P.within(values));
610 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
611 .has("aai-node-type", "vnfc");
614 "gremlin query should be " + expected.toString(),
616 query.getQueryBuilder().getQuery().toString());
619 expectedParent.toString(),
620 query.getQueryBuilder().getParentQuery().getQuery().toString());
622 "parent result type should be empty",
624 query.getParentResultType());
626 "result type should be vnfc",
628 query.getResultType());
630 "container type should be empty",
632 query.getContainerType());
633 assertEquals("dependent",true, query.isDependent());
638 public void dbAliasedSearch() throws UnsupportedEncodingException, AAIException {
639 URI uri = UriBuilder.fromPath("network/test-objects").build();
640 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
641 map.putSingle("persona-model-customization-id", "key2");
642 QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map);
643 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
644 .has("aai-node-type", "test-object")
645 .has("model-customization-id", "key2");
646 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
647 .has("aai-node-type", "test-object");
650 "gremlin query should be " + expected.toString(),
652 query.getQueryBuilder().getQuery().toString());
655 expectedParent.toString(),
656 query.getQueryBuilder().getParentQuery().getQuery().toString());
659 "result type should be",
661 query.getResultType());
663 "result type should be empty",
665 query.getParentResultType());
666 assertEquals("dependent",true, query.isDependent());
672 public void dataLinkedSearch() throws UnsupportedEncodingException, AAIException {
673 URI uri = UriBuilder.fromPath("network/vpn-bindings").build();
674 MultivaluedMap<String, String> map = new MultivaluedHashMap<>();
675 map.putSingle("global-route-target", "key2");
676 QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map);
677 GraphTraversal<Vertex, Vertex> expected = __.<Vertex>start()
678 .has("aai-node-type", "vpn-binding")
679 .where(__.out("has").has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "key2"));
680 GraphTraversal<Vertex, Vertex> expectedParent = __.<Vertex>start()
681 .has("aai-node-type", "vpn-binding");
684 "gremlin query should be " + expected.toString(),
686 query.getQueryBuilder().getQuery().toString());
689 expectedParent.toString(),
690 query.getQueryBuilder().getParentQuery().getQuery().toString());
693 "result type should be",
695 query.getResultType());
697 "result type should be empty",
699 query.getParentResultType());
700 assertEquals("dependent",true, query.isDependent());