/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ * Copyright © 2017 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= * * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ package org.onap.aai.parsers.query; import org.apache.tinkerpop.gremlin.process.traversal.P; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.onap.aai.AAISetup; import org.onap.aai.db.props.AAIProperties; import org.onap.aai.exceptions.AAIException; import org.onap.aai.introspection.LoaderFactory; import org.onap.aai.introspection.ModelType; import org.onap.aai.introspection.Version; import org.onap.aai.rest.RestTokens; import org.onap.aai.serialization.engines.QueryStyle; import org.onap.aai.serialization.engines.TitanDBEngine; import org.onap.aai.serialization.engines.TransactionalGraphEngine; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.List; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; public class GraphTraversalTest extends AAISetup { private TransactionalGraphEngine dbEngine; private TransactionalGraphEngine dbEnginev9; @Rule public ExpectedException thrown = ExpectedException.none(); /** * Configure. * @throws Exception * @throws SecurityException * @throws NoSuchFieldException */ @Before public void configure() throws Exception { dbEngine = new TitanDBEngine(QueryStyle.TRAVERSAL, LoaderFactory.createLoaderForVersion(ModelType.MOXY, AAIProperties.LATEST), false); dbEnginev9 = new TitanDBEngine(QueryStyle.TRAVERSAL, LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.v9), false); } /** * Parent query. * * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void parentQuery() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start().has("physical-location-id", "key1").has("aai-node-type", "complex"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal to normal query", expected.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be complex", "complex", query.getResultType()); assertEquals( "result type should be empty", "", query.getParentResultType()); assertEquals("dependent",false, query.isDependent()); } /** * Child query. * * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void childQuery() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/ctag-pools/ctag-pool/key2/key3").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("physical-location-id", "key1").has("aai-node-type", "complex") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "ctag-pool") .has("target-pe", "key2").has("availability-zone-name", "key3"); GraphTraversal expectedParent = __.start() .has("physical-location-id", "key1").has("aai-node-type", "complex"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for complex", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be complex", "complex", query.getParentResultType()); assertEquals( "result type should be ctag-pool", "ctag-pool", query.getResultType()); assertEquals("dependent",true, query.isDependent()); } /** * Naming exceptions. * * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void namingExceptions() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags/cvlan-tag/655").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2").in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "cvlan-tag") .has("cvlan-tag", 655); GraphTraversal expectedParent = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for port group", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be cvlan-tag", "cvlan-tag", query.getResultType()); assertEquals( "result type should be port-group", "port-group", query.getParentResultType()); assertEquals( "contaner type should be empty", "", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } /** * Gets the all. * * @return the all * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void getAll() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2").in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "cvlan-tag"); GraphTraversal expectedParent = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for port group", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be port-group", "port-group", query.getParentResultType()); assertEquals( "result type should be cvlan-tag", "cvlan-tag", query.getResultType()); assertEquals( "container type should be cvlan-tags", "cvlan-tags", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } @Test public void getAllParent() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/pservers").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("aai-node-type", "pserver"); GraphTraversal expectedParent = __.start() .has("aai-node-type", "pserver"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for pserver", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "parent result type should be empty", "", query.getParentResultType()); assertEquals( "result type should be pserver", "pserver", query.getResultType()); assertEquals( "container type should be pservers", "pservers", query.getContainerType()); assertEquals("dependent",false, query.isDependent()); } /** * Gets the via query param. * * @return the via query param * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void getViaQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/mycloudowner/mycloudregionid/tenants/tenant").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("tenant-name", "Tenant1"); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid") .has("aai-node-type", "cloud-region") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "tenant") .has("tenant-name", "Tenant1"); GraphTraversal expectedParent = __.start() .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid") .has("aai-node-type", "cloud-region"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for cloud-region", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be cloud-region", "cloud-region", query.getParentResultType()); assertEquals( "result type should be tenant", "tenant", query.getResultType()); assertEquals( "container type should be empty", "", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } @Test public void getViaDuplicateQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/mycloudowner/mycloudregionid/tenants/tenant").build(); MultivaluedMap map = new MultivaluedHashMap<>(); List values = new ArrayList<>(); values.add("Tenant1"); values.add("Tenant2"); map.put("tenant-name", values); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid") .has("aai-node-type", "cloud-region") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "tenant") .has("tenant-name", P.within(values)); GraphTraversal expectedParent = __.start() .has("cloud-owner", "mycloudowner").has("cloud-region-id", "mycloudregionid") .has("aai-node-type", "cloud-region"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for cloud-region", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be cloud-region", "cloud-region", query.getParentResultType()); assertEquals( "result type should be tenant", "tenant", query.getResultType()); assertEquals( "container type should be empty", "", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } /** * Gets the plural via query param. * * @return the plural via query param * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void getPluralViaQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vnfcs").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("prov-status", "up"); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("aai-node-type", "vnfc") .has("prov-status", "up"); GraphTraversal expectedParent = __.start() .has("aai-node-type", "vnfc"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "parent result type should be empty", "", query.getParentResultType()); assertEquals( "result type should be vnfc", "vnfc", query.getResultType()); assertEquals( "container type should be empty", "vnfcs", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } /** * Gets the all query param naming exception. * * @return the all query param naming exception * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void getAllQueryParamNamingException() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vces/vce/key1/port-groups/port-group/key2/cvlan-tags").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("cvlan-tag", "333"); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2").in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "cvlan-tag") .has("cvlan-tag", 333); GraphTraversal expectedParent = __.start() .has("vnf-id", "key1").has("aai-node-type", "vce") .in("org.onap.relationships.inventory.BelongsTo") .has("aai-node-type", "port-group") .has("interface-id", "key2"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for port group", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be port-group", "port-group", query.getParentResultType()); assertEquals( "result type should be cvlan-tag", "cvlan-tag", query.getResultType()); assertEquals( "container type should be cvlan-tags", "cvlan-tags", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } /** * Abstract type. * * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void abstractType() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("vnf/key1").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("vnf-id", "key1").has(AAIProperties.NODE_TYPE, P.within("vce", "generic-vnf")); GraphTraversal expectedParent = expected; assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for port group", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be empty", "", query.getParentResultType()); assertEquals( "result type should be vnf", "vnf", query.getResultType()); assertEquals("dependent",false, query.isDependent()); } /** * Non parent abstract type. * * @throws UnsupportedEncodingException the unsupported encoding exception * @throws AAIException the AAI exception */ @Test public void nonParentAbstractType() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/pservers/pserver/key2/vnf/key1").build(); thrown.expect(AAIException.class); thrown.expectMessage(containsString("not a valid path")); dbEngine.getQueryBuilder().createQueryFromURI(uri); } @Test public void parentAbstractTypeWithNesting() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("vnf/key1/vf-modules/vf-module/key2").build(); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("vnf-id", "key1").has(AAIProperties.NODE_TYPE, P.within("vce", "generic-vnf")) .union(__.in("org.onap.relationships.inventory.BelongsTo").has(AAIProperties.NODE_TYPE, "vf-module")).has("vf-module-id", "key2"); GraphTraversal expectedParent = __.start() .has("vnf-id", "key1").has(AAIProperties.NODE_TYPE, P.within("vce", "generic-vnf")); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent gremlin query should be equal the query for ", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be vnf", "vnf", query.getParentResultType()); assertEquals( "result type should be vf-module", "vf-module", query.getResultType()); assertEquals("dependent",true, query.isDependent()); } @Test public void getViaBadQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants/tenant").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("tenant-n231ame", "Tenant1"); thrown.expect(AAIException.class); thrown.expect(hasProperty("code", is("AAI_3000"))); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); } @Test public void getPluralViaBadQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/cloud-regions/cloud-region/a/b/tenants").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("tenant-n231ame", "Tenant1"); thrown.expect(AAIException.class); thrown.expect(hasProperty("code", is("AAI_3000"))); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); } @Test public void getPluralViaDuplicateQueryParam() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vnfcs").build(); MultivaluedMap map = new MultivaluedHashMap<>(); List values = new ArrayList<>(); values.add("up"); values.add("down"); values.add("left"); values.add("right"); values.add("start"); map.put("prov-status", values); QueryParser query = dbEngine.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("aai-node-type", "vnfc") .has("prov-status", P.within(values)); GraphTraversal expectedParent = __.start() .has("aai-node-type", "vnfc"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "parent result type should be empty", "", query.getParentResultType()); assertEquals( "result type should be vnfc", "vnfc", query.getResultType()); assertEquals( "container type should be empty", "vnfcs", query.getContainerType()); assertEquals("dependent",true, query.isDependent()); } @Test public void dbAliasedSearch() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/generic-vnfs").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("persona-model-customization-id", "key2"); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("aai-node-type", "generic-vnf") .has("model-customization-id", "key2"); GraphTraversal expectedParent = __.start() .has("aai-node-type", "generic-vnf"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be", "generic-vnf", query.getResultType()); assertEquals( "result type should be empty", "", query.getParentResultType()); assertEquals("dependent",true, query.isDependent()); } @Test public void dataLinkedSearch() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("network/vpn-bindings").build(); MultivaluedMap map = new MultivaluedHashMap<>(); map.putSingle("global-route-target", "key2"); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri, map); GraphTraversal expected = __.start() .has("aai-node-type", "vpn-binding") .where(__.in("org.onap.relationships.inventory.BelongsTo").has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "key2")); GraphTraversal expectedParent = __.start() .has("aai-node-type", "vpn-binding"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be", "vpn-binding", query.getResultType()); assertEquals( "result type should be empty", "", query.getParentResultType()); assertEquals("dependent",true, query.isDependent()); } @Test public void pluralCousin() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/related-to/pservers").build(); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex") .in("org.onap.relationships.inventory.LocatedIn").has("aai-node-type", "pserver"); GraphTraversal expectedParent = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be", "pserver", query.getResultType()); assertEquals( "result type should be", "complex", query.getParentResultType()); //this is controversial but we're not allowing writes on this currently assertEquals("dependent",true, query.isDependent()); } @Test public void specificCousin() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/related-to/pservers/pserver/key2").build(); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex") .in("org.onap.relationships.inventory.LocatedIn").has("aai-node-type", "pserver") .has("hostname", "key2"); GraphTraversal expectedParent = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be", "pserver", query.getResultType()); assertEquals( "result type should be", "complex", query.getParentResultType()); //this is controversial but we're not allowing writes on this currently assertEquals("dependent",true, query.isDependent()); } @Test public void doubleSpecificCousin() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/related-to/pservers/pserver/key2/related-to/vservers/vserver/key3").build(); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri); GraphTraversal expected = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex") .in("org.onap.relationships.inventory.LocatedIn").has("aai-node-type", "pserver") .has("hostname", "key2") .in("tosca.relationships.HostedOn").has("aai-node-type", "vserver") .has("vserver-id", "key3"); GraphTraversal expectedParent = __.start() .has("physical-location-id", "key1") .has("aai-node-type", "complex") .in("org.onap.relationships.inventory.LocatedIn").has("aai-node-type", "pserver") .has("hostname", "key2"); assertEquals( "gremlin query should be " + expected.toString(), expected.toString(), query.getQueryBuilder().getQuery().toString()); assertEquals( "parent", expectedParent.toString(), query.getQueryBuilder().getParentQuery().getQuery().toString()); assertEquals( "result type should be", "vserver", query.getResultType()); assertEquals( "result type should be", "pserver", query.getParentResultType()); //this is controversial but we're not allowing writes on this currently assertEquals("dependent",true, query.isDependent()); } @Test public void traversalEndsInRelatedTo() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/complex/key1/related-to").build(); thrown.expect(AAIException.class); thrown.expectMessage(containsString(RestTokens.COUSIN.toString())); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri); } @Test public void pluralCousinToPluralCousin() throws UnsupportedEncodingException, AAIException { URI uri = UriBuilder.fromPath("cloud-infrastructure/complexes/related-to/pservers").build(); thrown.expect(AAIException.class); thrown.expectMessage(containsString("chain plurals")); QueryParser query = dbEnginev9.getQueryBuilder().createQueryFromURI(uri); } }