diff options
Diffstat (limited to 'aai-core')
5 files changed, 179 insertions, 105 deletions
diff --git a/aai-core/pom.xml b/aai-core/pom.xml index d210f4e0..8e1e81f1 100644 --- a/aai-core/pom.xml +++ b/aai-core/pom.xml @@ -36,7 +36,7 @@ limitations under the License. <springframework.version>4.3.24.RELEASE</springframework.version> <jacoco.line.coverage.limit>0.50</jacoco.line.coverage.limit> - <gremlin.version>3.2.2</gremlin.version> + <gremlin.version>3.2.3</gremlin.version> <groovy.version>2.5.15</groovy.version> <mockito.core.version>3.4.0</mockito.core.version> <!-- Start of Default ONAP Schema Properties --> diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java index 3c5c4489..b8a354ea 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/GraphTraversalBuilder.java @@ -4,6 +4,8 @@ * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. * ================================================================================ + * Modifications Copyright © 2023 Deutsche Telekom. + * ================================================================================ * 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 @@ -62,6 +64,9 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { protected GraphTraversal<Vertex, E> traversal = null; protected Admin<Vertex, E> completeTraversal = null; + protected QueryBuilder<E> containerQuery; + protected QueryBuilder<E> parentQuery; + /** * Instantiates a new graph traversal builder. * @@ -351,7 +356,7 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { traversal.has(AAIProperties.NODE_TYPE, type); } stepIndex++; - markContainer(); + markContainerIndex(); return (QueryBuilder<Vertex>) this; } @@ -838,21 +843,16 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { return this; } - /** - * @{inheritDoc} - */ @Override public <E2> E2 getQuery() { return (E2) this.traversal; } - /** - * @{inheritDoc} - */ @Override public QueryBuilder<E> getParentQuery() { - - return cloneQueryAtStep(parentStepIndex); + return this.parentQuery != null + ? this.parentQuery + : cloneQueryAtStep(parentStepIndex); } @Override @@ -861,26 +861,22 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { if (this.parentStepIndex == 0) { return removeQueryStepsBetween(0, containerStepIndex); } else { - return cloneQueryAtStep(containerStepIndex); + return this.containerQuery; } } - /** - * @{inheritDoc} - */ @Override public void markParentBoundary() { + this.parentQuery = cloneQueryAtStep(stepIndex); parentStepIndex = stepIndex; } @Override - public void markContainer() { + public void markContainerIndex() { + this.containerQuery = cloneQueryAtStep(stepIndex); containerStepIndex = stepIndex; } - /** - * @{inheritDoc} - */ @Override public Vertex getStart() { return this.start; @@ -945,7 +941,9 @@ public abstract class GraphTraversalBuilder<E> extends QueryBuilder<E> { if (this.completeTraversal == null) { executeQuery(); } - return this.completeTraversal.toList(); + // clone is necessary since toList would optimize traversal steps + // which messes with the indeces that are registered while parsing + return this.completeTraversal.clone().toList(); } protected QueryBuilder<Edge> has(String key, String value) { diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java index 4500a47e..e68cfe69 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/GremlinQueryBuilder.java @@ -574,7 +574,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> { list.add(".has('aai-node-type', '" + type + "')"); } stepIndex++; - this.markContainer(); + this.markContainerIndex(); return (QueryBuilder<Vertex>) this; } @@ -879,7 +879,7 @@ public abstract class GremlinQueryBuilder<E> extends QueryBuilder<E> { } @Override - public void markContainer() { + public void markContainerIndex() { this.containerStepIndex = stepIndex; } diff --git a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java index 2bc90726..6d56d1af 100644 --- a/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java +++ b/aai-core/src/main/java/org/onap/aai/query/builder/QueryBuilder.java @@ -487,7 +487,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> { * This is necessary in cases such as "if the Optional Property 1 is sent, * find all Nodes of type A with edges to Nodes of type B with property 1, * otherwise, simply find all nodes of type A". - * + * * @param type * @param outNodeType * @param inNodeType @@ -506,7 +506,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> { * This is necessary in cases such as "if the Optional Property 1 is sent, * find all Nodes of type A with edges to Nodes of type B with property 1, * otherwise, simply find all nodes of type A". - * + * * @param type * @param outNodeType * @param inNodeType @@ -603,7 +603,7 @@ public abstract class QueryBuilder<E> implements Iterator<E> { public abstract <E2> E2 getQuery(); /** - * Form boundary. + * Marks the current step index as the boundary to the parent. */ public abstract void markParentBoundary(); @@ -721,7 +721,10 @@ public abstract class QueryBuilder<E> implements Iterator<E> { */ public abstract QueryBuilder<Path> path(); - public abstract void markContainer(); + /** + * Marks the current step index as the container step. + */ + public abstract void markContainerIndex(); public abstract QueryBuilder<E> getContainerQuery(); diff --git a/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java b/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java index 2a68e53d..31abc599 100644 --- a/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java +++ b/aai-core/src/test/java/org/onap/aai/introspection/sideeffect/DataLinkTest.java @@ -92,70 +92,122 @@ public class DataLinkTest extends DataLinkSetup { graphMgt.makePropertyKey(AAIProperties.LAST_MOD_TS).dataType(Long.class).cardinality(Cardinality.SINGLE).make(); graphMgt.commit(); - graph.traversal().addV().property("aai-node-type", "vpn-binding").property("vpn-id", "addKey") - .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/addKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v1").addV().property("aai-node-type", "vpn-binding").property("vpn-id", "modifyKey") - .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v2").addV().property("aai-node-type", "route-target") - .property("global-route-target", "modifyTargetKey").property("route-target-role", "modifyRoleKey") - .property("linked", true) - .property(AAIProperties.AAI_URI, - "/network/vpn-bindings/vpn-binding/modifyKey/route-targets/route-target/modifyTargetKey/modifyRoleKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v3").addE("org.onap.relationships.inventory.BelongsTo").to("v2").from("v3") - .property(EdgeProperty.CONTAINS.toString(), true).addV().property("aai-node-type", "vpn-binding") - .property("vpn-id", "deleteKey") - .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v4").addV().property("aai-node-type", "route-target") - .property("global-route-target", "deleteTargetKey").property("route-target-role", "deleteRoleKey") - .property("linked", true) - .property(AAIProperties.AAI_URI, - "/network/vpn-bindings/vpn-binding/deleteKey/route-targets/route-target/deleteTargetKey/deleteRoleKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v5").addE("org.onap.relationships.inventory.BelongsTo").to("v4").from("v5") - .property(EdgeProperty.CONTAINS.toString(), true).addV().property("aai-node-type", "vpn-binding") - .property("vpn-id", "getKey") - .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v6").addV().property("aai-node-type", "route-target") - .property("global-route-target", "getTargetKey").property("route-target-role", "getRoleKey") - .property("linked", true) - .property(AAIProperties.AAI_URI, - "/network/vpn-bindings/vpn-binding/getKey/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v7").addE("org.onap.relationships.inventory.BelongsTo").to("v6").from("v7") - .property(EdgeProperty.CONTAINS.toString(), true).addV().property("aai-node-type", "vpn-binding") - .property("vpn-id", "getKeyNoLink") - .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v8").addV().property("aai-node-type", "route-target") - .property("global-route-target", "getTargetKeyNoLink").property("route-target-role", "getRoleKeyNoLink") - .property(AAIProperties.AAI_URI, - "/network/vpn-bindings/vpn-binding/getKeyNoLink/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink") - .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()).property(AAIProperties.CREATED_TS, 123) - .property(AAIProperties.SOURCE_OF_TRUTH, "sot").property(AAIProperties.RESOURCE_VERSION, "123") - .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot").property(AAIProperties.LAST_MOD_TS, 333) - .as("v9").addE("org.onap.relationships.inventory.BelongsTo").to("v8").from("v9") - .property(EdgeProperty.CONTAINS.toString(), true).next(); + graph.traversal() + .addV() + .property("aai-node-type", "vpn-binding") + .property("vpn-id", "addKey") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/addKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v1") + .addV() + .property("aai-node-type", "vpn-binding") + .property("vpn-id", "modifyKey") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v2") + .addV() + .property("aai-node-type", "route-target") + .property("global-route-target", "modifyTargetKey") + .property("route-target-role", "modifyRoleKey") + .property("linked", true) + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey/route-targets/route-target/modifyTargetKey/modifyRoleKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v3") + .addE("org.onap.relationships.inventory.BelongsTo").to("v2").from("v3") + .property(EdgeProperty.CONTAINS.toString(), true) + .addV() + .property("aai-node-type", "vpn-binding") + .property("vpn-id", "deleteKey") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v4") + .addV() + .property("aai-node-type", "route-target") + .property("global-route-target", "deleteTargetKey") + .property("route-target-role", "deleteRoleKey") + .property("linked", true) + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey/route-targets/route-target/deleteTargetKey/deleteRoleKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v5") + .addE("org.onap.relationships.inventory.BelongsTo").to("v4").from("v5") + .property(EdgeProperty.CONTAINS.toString(), true) + .addV() + .property("aai-node-type", "vpn-binding") + .property("vpn-id", "getKey") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v6") + .addV() + .property("aai-node-type", "route-target") + .property("global-route-target", "getTargetKey") + .property("route-target-role", "getRoleKey") + .property("linked", true) + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v7") + .addE("org.onap.relationships.inventory.BelongsTo").to("v6").from("v7") + .property(EdgeProperty.CONTAINS.toString(), true) + .addV() + .property("aai-node-type", "vpn-binding") + .property("vpn-id", "getKeyNoLink") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v8") + .addV() + .property("aai-node-type", "route-target") + .property("global-route-target", "getTargetKeyNoLink") + .property("route-target-role", "getRoleKeyNoLink") + .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink") + .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString()) + .property(AAIProperties.CREATED_TS, 123) + .property(AAIProperties.SOURCE_OF_TRUTH, "sot") + .property(AAIProperties.RESOURCE_VERSION, "123") + .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot") + .property(AAIProperties.LAST_MOD_TS, 333) + .as("v9") + .addE("org.onap.relationships.inventory.BelongsTo").to("v8").from("v9") + .property(EdgeProperty.CONTAINS.toString(), true) + .next(); graph.tx().commit(); } @@ -230,21 +282,41 @@ public class DataLinkTest extends DataLinkSetup { runner.execute(obj, self); assertThat("new route-target vertex found with/or without link", - traversal.V().has(AAIProperties.NODE_TYPE, "route-target") - .has("global-route-target", "modifyTargetKey2").has("route-target-role", "modifyRoleKey2") + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "modifyTargetKey2") + .has("route-target-role", "modifyRoleKey2") .hasNext(), is(true)); - assertThat("new route-target vertex found", - traversal.V().has(AAIProperties.NODE_TYPE, "route-target") - .has("global-route-target", "modifyTargetKey2").has("route-target-role", "modifyRoleKey2") - .has("linked", true).hasNext(), + assertThat("new route-target vertex has link", + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "modifyTargetKey2") + .has("route-target-role", "modifyRoleKey2") + .has("linked", true) + .hasNext(), + is(true)); + assertThat("previous vertex still exists", + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "modifyTargetKey") + .has("route-target-role", "modifyRoleKey") + .hasNext(), is(true)); - assertThat("previous link removed", - traversal.V().has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "modifyTargetKey") - .has("route-target-role", "modifyRoleKey").has("linked").hasNext(), + assertThat("link of previous vert removed", + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "modifyTargetKey") + .has("route-target-role", "modifyRoleKey") + .has("linked") + .hasNext(), is(not(true))); - assertThat("previous vertex still exists", traversal.V().has(AAIProperties.NODE_TYPE, "route-target") - .has("global-route-target", "modifyTargetKey").has("route-target-role", "modifyRoleKey").hasNext(), + assertThat("previous vertex still exists", + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "modifyTargetKey") + .has("route-target-role", "modifyRoleKey") + .hasNext(), is(true)); g.tx().rollback(); @@ -274,11 +346,14 @@ public class DataLinkTest extends DataLinkSetup { runner.execute(obj, self); assertFalse("route-target vertex not found", - traversal.V().has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "deleteTargetKey") - .has("route-target-role", "deleteRoleKey").has("linked", true).hasNext()); + traversal.V() + .has(AAIProperties.NODE_TYPE, "route-target") + .has("global-route-target", "deleteTargetKey") + .has("route-target-role", "deleteRoleKey") + .has("linked", true) + .hasNext()); g.tx().rollback(); - } @Test @@ -307,7 +382,6 @@ public class DataLinkTest extends DataLinkSetup { obj.getValue("global-route-target").equals("getTargetKey") && obj.getValue("route-target-role").equals("getRoleKey")); g.tx().rollback(); - } @Test @@ -350,6 +424,5 @@ public class DataLinkTest extends DataLinkSetup { routeTargetTwoV.property(AAIProperties.LINKED).orElse(false)); g.tx().rollback(); - } } |