add v16 to traversal repo 56/84956/3
authorLaMont, William (wl2432) <wl2432@att.com>
Wed, 10 Apr 2019 22:03:20 +0000 (18:03 -0400)
committerLaMont, William (wl2432) <wl2432@att.com>
Thu, 11 Apr 2019 14:49:45 +0000 (10:49 -0400)
Issue-ID: AAI-2322
Change-Id: I8967e1e90dc407424c8b8943d1278108f9786cef
Signed-off-by: LaMont, William (wl2432) <wl2432@att.com>
31 files changed:
aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
aai-traversal/src/main/java/org/onap/aai/interceptors/pre/VersionInterceptor.java
aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java
aai-traversal/src/main/java/org/onap/aai/rest/dsl/AAIDslErrorListener.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java
aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java
aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java
aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryConfigDTO.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryDTO.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryTestDTO.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/rest/search/ExpectedResultsDto.java [new file with mode: 0644]
aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java
aai-traversal/src/main/resources/antlr4/org/onap/aai/AAIDsl.g4
aai-traversal/src/main/resources/etc/appprops/aaiconfig.properties
aai-traversal/src/main/resources/retired.properties
aai-traversal/src/test/java/org/onap/aai/AAIGremlinQueryTest.java
aai-traversal/src/test/java/org/onap/aai/QueryParameterTest.java
aai-traversal/src/test/java/org/onap/aai/SubgraphPruneTest.java
aai-traversal/src/test/java/org/onap/aai/TraversalTestConfiguration.java
aai-traversal/src/test/java/org/onap/aai/rest/AbstractSpringRestTest.java
aai-traversal/src/test/java/org/onap/aai/rest/BadQueryFormatTest.java
aai-traversal/src/test/java/org/onap/aai/rest/DslConsumerTest.java
aai-traversal/src/test/java/org/onap/aai/rest/QueryConsumerTest.java
aai-traversal/src/test/java/org/onap/aai/rest/dsl/DslQueryProcessorTest.java
aai-traversal/src/test/java/org/onap/aai/rest/dsl/ProdDslTest.java [new file with mode: 0644]
aai-traversal/src/test/java/org/onap/aai/rest/search/GetVNFVpnBondingServiceDetailsTest.java [new file with mode: 0644]
aai-traversal/src/test/resources/application-onap-test.properties
aai-traversal/src/test/resources/application-test.properties
aai-traversal/src/test/resources/schema-ingest.properties

index 64a3b44..4d8f4a8 100644 (file)
@@ -179,6 +179,7 @@ public class TraversalApp {
                }
 
                String currentDirectory = System.getProperty("user.dir");
+               System.setProperty("aai.service.name", TraversalApp.class.getSimpleName());
 
                if (System.getProperty("AJSC_HOME") == null) {
                        System.setProperty("AJSC_HOME", ".");
index df9807c..902d6f0 100644 (file)
@@ -62,7 +62,7 @@ public class VersionInterceptor extends AAIContainerFilter implements ContainerR
 
         String uri = requestContext.getUriInfo().getPath();
 
-        if (uri.startsWith("search") || uri.startsWith("util/echo") || uri.startsWith("tools") || uri.startsWith("recents")) {
+        if (uri.startsWith("search") || uri.startsWith("util/echo") || uri.startsWith("tools") || uri.startsWith("recents")|| uri.startsWith("cq2gremlin")|| uri.startsWith("cq2gremlintest")) {
             return;
                }
 
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java
new file mode 100644 (file)
index 0000000..dcf8418
--- /dev/null
@@ -0,0 +1,126 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.dbmap.DBConnectionType;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.rest.search.CustomQueryConfigDTO;
+import org.onap.aai.rest.search.CustomQueryDTO;
+import org.onap.aai.restcore.RESTAPI;
+import org.onap.aai.restcore.search.GroovyQueryBuilder;
+import org.onap.aai.serialization.db.EdgeSerializer;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.setup.SchemaVersions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.RequestBody;
+
+
+@Path("/cq2gremlin")
+public class CQ2Gremlin extends RESTAPI {
+
+       private HttpEntry traversalUriHttpEntry;
+
+
+       @Autowired
+       protected LoaderFactory loaderFactory;
+       
+       @Autowired
+       protected EdgeSerializer rules;
+       
+       
+       @Autowired
+       public CQ2Gremlin(
+               HttpEntry traversalUriHttpEntry,
+               @Value("${schema.uri.base.path}") String basePath
+       ){
+               this.traversalUriHttpEntry  = traversalUriHttpEntry;
+       }
+       
+       @PUT
+       @Path("")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public Response getC2Qgremlin(@RequestBody Map<String, CustomQueryConfigDTO> content,@Context HttpHeaders headers, @Context UriInfo info) {
+               if(content.size() == 0){
+                       return Response.status(HttpStatus.BAD_REQUEST.value()).entity("At least one custom query should be passed").build();
+               }
+               return processGremlinQuery(content.values().toArray(new CustomQueryConfigDTO[0])[0], info, headers);
+       }
+       
+       protected Response processGremlinQuery(CustomQueryConfigDTO content, UriInfo info,
+                       HttpHeaders headers) {
+               try{
+                       String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
+                       String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+                       LinkedHashMap <String, Object> params;
+                       CustomQueryDTO queryDTO = content.getQueryDTO();
+                       String query = queryDTO.getQuery();
+                       params = new LinkedHashMap <>();
+                       
+                       List<String> optionalParameters = queryDTO.getQueryOptionalProperties();
+                       if (!optionalParameters.isEmpty()){
+                               for ( String key : optionalParameters ) {
+                                       params.put(key, key);
+                               }
+                       }
+                       
+                       List<String> requiredParameters = queryDTO.getQueryRequiredProperties();
+                       if (!requiredParameters.isEmpty()){
+                               for ( String key : requiredParameters ) {
+                                       params.put(key, key);
+                               }
+                       }
+                       
+                       SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
+                       DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
+                       traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), type);
+                       traversalUriHttpEntry.setPaginationParameters("-1", "-1");
+                       
+                       TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
+                       
+                       query = new GroovyQueryBuilder().executeTraversal(dbEngine,query, params);
+                       query = "g" + query;
+                       return Response.ok(query).build();
+               }
+               catch(Exception ex){
+                       return Response.status(500).entity("Query conversion failed with following reason: " + ex.toString()).build();
+               }
+               
+       }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java
new file mode 100644 (file)
index 0000000..40538be
--- /dev/null
@@ -0,0 +1,235 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest;
+
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.dbmap.DBConnectionType;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.rest.search.CustomQueryTestDTO;
+import org.onap.aai.restcore.RESTAPI;
+import org.onap.aai.restcore.search.GremlinGroovyShell;
+import org.onap.aai.restcore.search.GroovyQueryBuilder;
+import org.onap.aai.serialization.db.EdgeSerializer;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.setup.SchemaVersion;
+import org.onap.aai.setup.SchemaVersions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.beust.jcommander.internal.Lists;
+import com.beust.jcommander.internal.Maps;
+
+
+@Path("/cq2gremlintest")
+public class CQ2GremlinTest extends RESTAPI {
+
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(CQ2GremlinTest.class);
+
+       private HttpEntry traversalUriHttpEntry;
+
+
+       @Autowired
+       protected LoaderFactory loaderFactory;
+
+       @Autowired
+       protected EdgeSerializer rules;
+
+       protected Loader loader;
+       protected GraphTraversalSource gts;
+
+
+       @Autowired
+       public CQ2GremlinTest(
+                       HttpEntry traversalUriHttpEntry,
+                       @Value("${schema.uri.base.path}") String basePath
+                       ){
+               this.traversalUriHttpEntry  = traversalUriHttpEntry;
+
+       }
+
+       @PUT
+       @Path("")
+       @Consumes({ MediaType.APPLICATION_JSON })
+       @Produces({ MediaType.APPLICATION_JSON })
+       public Response getC2Qgremlin(@RequestBody CustomQueryTestDTO content,@Context HttpHeaders headers, @Context UriInfo info) throws AAIException {
+               if(content == null){
+                       return Response.status(HttpStatus.BAD_REQUEST.value()).entity("At least one Json payload should be passed").build();
+               }
+               String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
+               String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+               SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
+               DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
+               traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), type);
+               traversalUriHttpEntry.setPaginationParameters("-1", "-1");
+               return processC2UnitTest(content);
+       }
+
+       private Response processC2UnitTest(CustomQueryTestDTO content) {
+
+               TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
+               Graph graph = TinkerGraph.open();
+               gts = graph.traversal();
+               List<Vertex> expectedVertices = createGraph(content, graph);
+               GremlinGroovyShell shell = new GremlinGroovyShell();
+               loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion("v16"));
+               LinkedHashMap <String, Object> params = new LinkedHashMap<>();
+
+               //Adding parameters
+               content.getQueryRequiredProperties().forEach((K, V) -> {params.put(K, V);});
+               content.getQueryOptionalProperties().forEach((K, V) -> {params.put(K, V);});
+
+               String query = new GroovyQueryBuilder().executeTraversal(dbEngine, content.getStoredQuery(), params);
+               query = "g" + query;
+               GraphTraversal<Vertex, Vertex> g = graph.traversal().V();
+               addStartNode(g, content);
+               params.put("g", g);
+
+               //Assertion
+               GraphTraversal<Vertex, Vertex> result = (GraphTraversal<Vertex, Vertex>)shell.executeTraversal(query, params);
+
+               List<Vertex> vertices = result.toList();
+
+               LOGGER.info("Expected result set of vertexes [{}]", convert(expectedVertices));
+               LOGGER.info("Actual Result set of vertexes [{}]", convert(vertices));
+
+               List<Vertex> nonDuplicateExpectedResult = new ArrayList<>(new HashSet<>(expectedVertices));
+               vertices = new ArrayList<>(new HashSet<>(vertices));
+
+               nonDuplicateExpectedResult.sort(Comparator.comparing(vertex -> vertex.id().toString()));
+               vertices.sort(Comparator.comparing(vertex -> vertex.id().toString()));
+
+
+               // Use this instead of the assertTrue as this provides more useful
+               // debugging information such as this when expected and actual differ:
+               // java.lang.AssertionError: Expected all the vertices to be found
+               // Expected :[v[2], v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12]]
+               // 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]]
+               if(nonDuplicateExpectedResult.equals(vertices)){
+                       return Response.ok("Sucessfully executed Junit").build();
+               }
+               return Response.status(400).build();
+
+       }
+
+       private List<Vertex> createGraph(CustomQueryTestDTO content, Graph graph) {
+               Map<String, Vertex> verticesMap = Maps.newLinkedHashMap();
+               //Creating all the Vertices
+               content.getVerticesDtos().stream().forEach(vertex -> {
+                       StringBuilder vertexIdentifier = new StringBuilder();
+                       List<String> keyValues = Lists.newArrayList();
+                       keyValues.add(T.id.toString());
+                       keyValues.add(String.format("%02d", verticesMap.size() * 10));
+                       AtomicInteger index = new AtomicInteger(0);
+                       vertex.forEach((K, V) -> {
+                               if(index.get() == 1)
+                                       vertexIdentifier.append(V);
+                               keyValues.add(K);
+                               keyValues.add(V);
+                               index.incrementAndGet();
+                       });
+                       Vertex graphVertex = graph.addVertex(keyValues.toArray());
+                       verticesMap.put(vertexIdentifier.toString(), graphVertex);
+               });
+
+               GraphTraversalSource g = graph.traversal();
+
+               //Creating all the Edges
+               content.getEdgesDtos().stream().forEach(edge -> {
+                       String fromId = edge.get("from-id");
+                       String toId = edge.get("to-id");
+                       boolean treeEdgeIdentifier = !"NONE".equalsIgnoreCase(edge.get("contains-other-v"));
+                       Vertex fromVertex = verticesMap.get(fromId);
+                       Vertex toVertex = verticesMap.get(toId);
+                       try{
+                               if(treeEdgeIdentifier){
+                                       rules.addTreeEdge(g, fromVertex, toVertex);
+                               }
+                               else{
+                                       rules.addEdge(g, fromVertex, toVertex);
+                               }
+                       } catch(AAIException ex){
+                               LOGGER.warn(ex.toString(), ex);
+                       }
+
+               });
+
+
+               List<Vertex> expectedVertices = Lists.newArrayList();
+               content.getExpectedResultsDtos().getIds().stream().forEach(vertexId -> {
+                       expectedVertices.add(verticesMap.get(vertexId));
+               });
+               return expectedVertices;
+       }
+
+       protected void addStartNode(GraphTraversal<Vertex, Vertex> g, CustomQueryTestDTO content) {
+               Optional<LinkedHashMap<String, String>> startNodeVertex = content.getVerticesDtos().stream().filter(map -> map.containsKey("start-node")).findFirst();
+               if(!startNodeVertex.isPresent()){
+                       throw new IllegalArgumentException("start-node was not specified");
+               }
+               startNodeVertex.get().forEach((K, V) -> {
+                       g.has(K, V);
+               });
+       }
+
+       protected String convert(List<Vertex> vertices){
+               return vertices
+                               .stream()
+                               .map(vertex -> vertex.property("aai-node-type").value().toString())
+                               .collect(Collectors.joining(","));
+       }
+
+
+
+}
index ad5fffb..2d09636 100644 (file)
  */
 package org.onap.aai.rest;
 
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.Encoded;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-import javax.ws.rs.core.Response.Status;
-
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
 import org.onap.aai.concurrent.AaiCallable;
 import org.onap.aai.dbmap.DBConnectionType;
 import org.onap.aai.exceptions.AAIException;
@@ -64,11 +50,12 @@ import org.onap.aai.util.TraversalConstants;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
 
 @Path("{version: v[1-9][0-9]*|latest}/dsl")
 public class DslConsumer extends RESTAPI {
@@ -90,8 +77,8 @@ public class DslConsumer extends RESTAPI {
 
        @Autowired
        public DslConsumer(HttpEntry traversalUriHttpEntry, DslQueryProcessor dslQueryProcessor,
-                       SchemaVersions schemaVersions, GremlinServerSingleton gremlinServerSingleton,
-                       @Value("${schema.uri.base.path}") String basePath) {
+                       SchemaVersions schemaVersions, GremlinServerSingleton gremlinServerSingleton,
+                       @Value("${schema.uri.base.path}") String basePath) {
                this.traversalUriHttpEntry = traversalUriHttpEntry;
                this.dslQueryProcessor = dslQueryProcessor;
                this.schemaVersions = schemaVersions;
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/AAIDslErrorListener.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/AAIDslErrorListener.java
new file mode 100644 (file)
index 0000000..26a625a
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest.dsl;
+
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+
+public class AAIDslErrorListener extends BaseErrorListener {
+
+    @Override
+    public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e)
+            throws ParseCancellationException {
+        throw new ParseCancellationException("line " + line + ":" + charPositionInLine + " " + msg);
+    }
+}
index a6be24c..8fd23cc 100644 (file)
  */
 package org.onap.aai.rest.dsl;
 
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.List;
-
-import org.antlr.v4.runtime.tree.TerminalNode;
-
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.google.common.collect.Lists;
+import org.onap.aai.AAIDslBaseListener;
 import org.onap.aai.AAIDslParser;
-import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.edges.EdgeRuleQuery;
-import org.onap.aai.edges.enums.EdgeType;
+import org.onap.aai.edges.EdgeIngestor;
 import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.introspection.Introspector;
 import org.onap.aai.introspection.Loader;
 import org.onap.aai.introspection.LoaderFactory;
 import org.onap.aai.introspection.ModelType;
-import org.onap.aai.logging.LogFormatTools;
-import org.onap.aai.setup.SchemaVersion;
 import org.onap.aai.setup.SchemaVersions;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.onap.aai.AAIDslBaseListener;
-import org.onap.aai.edges.EdgeIngestor;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * The Class DslListener.
  */
 public class DslListener extends AAIDslBaseListener {
 
-       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslQueryProcessor.class);
+       private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslListener.class);
 
-       private final EdgeIngestor edgeRules;
+       boolean validationFlag = false;
+       EdgeIngestor edgeIngestor;
+       Loader loader;
 
-       DslContext context = null;
-       DslQueryBuilder dslBuilder = null;
+       private Deque<DslQueryBuilder> dslQueryBuilders = new LinkedList<>();
+       private Deque<String> traversedNodes = new LinkedList<>();
+       private Deque<List<String>> returnedNodes = new LinkedList<>();
+
+       List<String> traversedEdgeLabels = new LinkedList<>();
 
        /**
         * Instantiates a new DslListener.
         */
        @Autowired
        public DslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory) {
-               this.edgeRules = edgeIngestor;
-               context = new DslContext();
+               this.loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
+               this.edgeIngestor = edgeIngestor;
+       }
 
-               Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
-               dslBuilder = new DslQueryBuilder(edgeIngestor, loader);
+       public DslQueryBuilder builder() {
+               return dslQueryBuilders.peekFirst();
        }
 
        public String getQuery() throws AAIException {
+               //TODO Change the exception reporting
                if (!getException().isEmpty()) {
                        LOGGER.error("Exception in the DSL Query" + getException());
                        throw new AAIException("AAI_6149", getException());
                }
-               return dslBuilder.getQuery().toString();
+
+               return this.compile();
+       }
+
+       public String compile() {
+               List<String> queries = dslQueryBuilders.stream().map(dslQb -> dslQb.getQuery().toString()).collect(Collectors.toList());
+               return String.join("", Lists.reverse(queries));
        }
 
        public String getException() {
-               return dslBuilder.getQueryException().toString();
+               return builder().getQueryException().toString();
        }
 
        @Override
        public void enterAaiquery(AAIDslParser.AaiqueryContext ctx) {
-               /*
-                * This is my start-node, have some validations here
-                */
-               context.setStartNodeFlag(true);
-               dslBuilder.start();
+               dslQueryBuilders.push(new DslQueryBuilder(edgeIngestor, loader));
        }
 
        @Override
-       public void exitAaiquery(AAIDslParser.AaiqueryContext ctx) {
-               dslBuilder.end(context);
+       public void enterStartStatement(AAIDslParser.StartStatementContext ctx) {
+               builder().start();
        }
 
        @Override
-       public void enterDslStatement(AAIDslParser.DslStatementContext ctx) {
-               if (context.isUnionStart()) {
-                       dslBuilder.startUnion();
+       public void exitStartStatement(AAIDslParser.StartStatementContext ctx) {
+               builder().end();
+               if (!traversedNodes.isEmpty()) {
+                       traversedNodes.removeFirst();
                }
+
        }
 
        @Override
-       public void exitDslStatement(AAIDslParser.DslStatementContext ctx) {
-               if (context.isUnionQuery()) {
-                       dslBuilder.comma(context);
-                       context.setUnionStart(true);
-               }
+       public void exitLimit(AAIDslParser.LimitContext ctx) {
+               builder().limit(ctx.num().getText());
        }
 
        @Override
-       public void enterSingleNodeStep(AAIDslParser.SingleNodeStepContext ctx) {
-               try {
-                       /*
-                        * Set the previous Node to current node and get the new current
-                        * node
-                        */
-                       context.setPreviousNode(context.getCurrentNode());
-                       context.setCurrentNode(ctx.NODE().getText());
-
-                       if (context.isUnionQuery() || context.isTraversal() || context.isWhereQuery()) {
-                               String oldPreviousNode = context.getPreviousNode();
-
-                               if (context.isUnionStart()) {
-                                       String previousNode = context.getUnionStartNodes().peek();
-                                       context.setPreviousNode(previousNode);
-
-                                       context.setUnionStart(false);
-                               }
+       public void enterNestedStatement(AAIDslParser.NestedStatementContext ctx) {
+               dslQueryBuilders.addFirst(new DslQueryBuilder(edgeIngestor, loader));
+               builder().startInstance();
+       }
 
-                               dslBuilder.edgeQuery(context);
+       @Override
+       public void exitNestedStatement(AAIDslParser.NestedStatementContext ctx) {
+               int count = 1;
+               if(!ctx.traversal().isEmpty()) {
+                       count += ctx.traversal().size() ;
+               }
+               //TODO so ugly
+               String resultNode = traversedNodes.peekFirst();
 
-                               /*
-                                * Reset is required bcos for union queries im changing the
-                                * context
-                                */
-                               context.setPreviousNode(oldPreviousNode);
+               if (!traversedNodes.isEmpty()) {
+                       Stream<Integer> integers = Stream.iterate(0, i -> i + 1);
+                       integers.limit(count)
+                                       .forEach(i -> traversedNodes.removeFirst());
+               }
+               List<String> resultNodes = returnedNodes.pop();
+               resultNodes.add(resultNode);
+               returnedNodes.addFirst(resultNodes);
+       }
 
-                       }
+       @Override
+       public void enterComma(AAIDslParser.CommaContext ctx) {
+               builder().comma();
+       }
 
-                       else {
-                               dslBuilder.nodeQuery(context);
-                       }
+       @Override
+       public void enterVertex(AAIDslParser.VertexContext ctx) {
 
-               } catch (AAIException e) {
-                       LOGGER.info("AAIException in DslListener" + e.getMessage());
+               if (!traversedNodes.isEmpty()) {
+                       builder().edgeQuery(traversedEdgeLabels, traversedNodes.peekFirst(), ctx.label().getText());
+               } else {
+                       builder().nodeQuery(ctx.label().getText());
                }
 
+               traversedNodes.addFirst(ctx.label().getText());
        }
 
        @Override
-       public void exitSingleNodeStep(AAIDslParser.SingleNodeStepContext ctx) {
-               if (context.isStartNode() && isValidationFlag()) {
-                       try {
-                               dslBuilder.validateFilter(context);
-                       } catch (AAIException e) {
-                               LOGGER.error("AAIException in DslListener" + LogFormatTools.getStackTop(e));
+       public void exitVertex(AAIDslParser.VertexContext ctx) {
+
+               /*TODO dont use context */
+               if (ctx.getParent() instanceof AAIDslParser.StartStatementContext && isValidationFlag()) {
+                       List<String> allKeys = new ArrayList<>();
+
+                       if (ctx.filter() != null) {
+                               allKeys = ctx.filter().propertyFilter().stream().flatMap(
+                                               pf -> pf.key().stream()).map(
+                                               e -> e.getText().replaceAll("\'", "")).collect(Collectors.toList());
+
                        }
+                       builder().validateFilter(ctx.label().getText(), allKeys);
                }
-               context.setStartNodeFlag(false);
-               context.setCtx(ctx);
-               dslBuilder.store(context);
+               if (ctx.store() != null) {
+                       builder().store();
+               }
+               traversedEdgeLabels = new ArrayList<>();
        }
 
-       private void generateExitStep() {
 
+       @Override
+       public void enterUnionVertex(AAIDslParser.UnionVertexContext ctx) {
+               returnedNodes.addFirst(new ArrayList<>());
+               builder().union();
        }
 
        @Override
-       public void enterUnionQueryStep(AAIDslParser.UnionQueryStepContext ctx) {
-
-               Deque<String> unionStartNodes = context.getUnionStartNodes();
-               unionStartNodes.add(context.getCurrentNode());
-
-               context.setUnionStart(true);
-               /*
-                * I may not need this
-                */
-               context.setUnionQuery(true);
-               dslBuilder.union(context);
+       public void exitUnionVertex(AAIDslParser.UnionVertexContext ctx) {
+               String resultNode = returnedNodes.pop().get(0);
+               traversedNodes.addFirst(resultNode);
+               builder().endUnion();
+       }
 
+       @Override
+       public void enterWhereFilter(AAIDslParser.WhereFilterContext ctx) {
+               returnedNodes.addFirst(new ArrayList<>());
+               builder().where();
        }
 
        @Override
-       public void exitUnionQueryStep(AAIDslParser.UnionQueryStepContext ctx) {
-               context.setUnionStart(false);
-               context.setUnionQuery(false);
-               Deque<String> unionStartNodes = context.getUnionStartNodes();
-               if (unionStartNodes.peek() != null) {
-                       unionStartNodes.pop();
+       public void exitWhereFilter(AAIDslParser.WhereFilterContext ctx) {
+               if(!returnedNodes.isEmpty()) {
+                       returnedNodes.pop();
                }
-
-               dslBuilder.endUnion(context);
-
+               builder().endWhere();
        }
 
        @Override
-       public void enterFilterTraverseStep(AAIDslParser.FilterTraverseStepContext ctx) {
-               context.setWhereQuery(true);
-               context.setWhereStartNode(context.getCurrentNode());
-               dslBuilder.where(context);
-
+       public void enterTraversal(AAIDslParser.TraversalContext ctx) {
        }
 
        @Override
-       public void exitFilterTraverseStep(AAIDslParser.FilterTraverseStepContext ctx) {
-               context.setWhereQuery(false);
-               context.setCurrentNode(context.getWhereStartNode());
-
-               dslBuilder.endWhere(context);
-
+       public void enterEdge(AAIDslParser.EdgeContext ctx) {
        }
 
        @Override
-       public void enterFilterStep(AAIDslParser.FilterStepContext ctx) {
+       public void enterEdgeFilter(AAIDslParser.EdgeFilterContext ctx) {
+               traversedEdgeLabels = ctx.key().stream().map(value -> value.getText()).collect(Collectors.toList());
 
-               context.setCtx(ctx);
-               dslBuilder.filter(context);
        }
 
        @Override
-       public void exitFilterStep(AAIDslParser.FilterStepContext ctx) {
-               // For now do nothing
-       }
+       public void enterFilter(AAIDslParser.FilterContext ctx) {
 
-       @Override
-       public void enterTraverseStep(AAIDslParser.TraverseStepContext ctx) {
-               context.setTraversal(true);
        }
 
        @Override
-       public void exitTraverseStep(AAIDslParser.TraverseStepContext ctx) {
-               context.setTraversal(false);
+       public void enterPropertyFilter(AAIDslParser.PropertyFilterContext ctx) {
+
+               List<AAIDslParser.KeyContext> valueList = ctx.key();
+               String filterKey = valueList.get(0).getText();
+
+               boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+               List<AAIDslParser.NumContext> numberValues = ctx.num();
+
+               /*
+                * Add all String values
+                */
+               List<String> values = valueList.stream().filter(value -> !filterKey.equals(value.getText()))
+                               .map(value -> "'" + value.getText().replace("'", "") + "'").collect(Collectors.toList());
+               /*
+                * Add all numeric values
+                */
+               values.addAll(numberValues.stream().filter(value -> !filterKey.equals(value.getText()))
+                               .map(value -> value.getText()).collect(Collectors.toList()));
+
+               builder().filter(isNot, traversedNodes.peekFirst(), filterKey, values);
+
        }
 
-       @Override
-       public void enterLimitStep(AAIDslParser.LimitStepContext ctx) {
-               context.setCtx(ctx);
-               dslBuilder.limit(context);
+       public boolean isValidationFlag() {
+               return validationFlag;
        }
-       
+
        public void setValidationFlag(boolean validationFlag) {
-               this.context.setValidationFlag(validationFlag);
-       }
-       
-       public boolean isValidationFlag() {
-               return this.context.isValidationFlag();
+               this.validationFlag = validationFlag;
        }
 
 }
index fce8a98..6817cf7 100644 (file)
  */
 package org.onap.aai.rest.dsl;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import org.antlr.v4.runtime.tree.TerminalNode;
-import org.apache.tinkerpop.gremlin.structure.Direction;
-import org.apache.tinkerpop.gremlin.structure.Edge;
-import org.onap.aai.AAIDslBaseListener;
-import org.onap.aai.AAIDslParser;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
 import org.onap.aai.edges.EdgeIngestor;
+import org.onap.aai.edges.EdgeRule;
 import org.onap.aai.edges.EdgeRuleQuery;
 import org.onap.aai.edges.enums.EdgeType;
-import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
 import org.onap.aai.introspection.Introspector;
 import org.onap.aai.introspection.Loader;
 import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.schema.enums.PropertyMetadata;
 
-import com.jcabi.log.Logger;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 public class DslQueryBuilder {
 
-       private StringBuilder query;
-       private StringBuilder queryException;
-       private final EdgeIngestor edgeRules;
-       private final Loader loader;
-
-       public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) {
-               this.edgeRules = edgeIngestor;
-               this.loader = loader;
-               query = new StringBuilder();
-               queryException = new StringBuilder();
-       }
-
-       public StringBuilder getQuery() {
-               return query;
-       }
-
-       public void setQuery(StringBuilder query) {
-               this.query = query;
-       }
-
-       public StringBuilder getQueryException() {
-               return queryException;
-       }
-
-       public void setQueryException(StringBuilder queryException) {
-               this.queryException = queryException;
-       }
-
-       public DslQueryBuilder start() {
-               query.append("builder");
-               return this;
-       }
-
-       public DslQueryBuilder startUnion() {
-               query.append("builder.newInstance()");
-               return this;
-       }
-
-       public DslQueryBuilder end(DslContext context) {
-               query.append(".cap('x').unfold().dedup()").append(context.getLimitQuery());
-               return this;
-       }
-
-       public DslQueryBuilder nodeQuery(DslContext context) {
-               query.append(".getVerticesByProperty('aai-node-type', '").append(context.getCurrentNode()).append("')");
-               if(context.isStartNode() && context.getStartNode().isEmpty())
-                       context.setStartNode(context.getCurrentNode());
-               return this;
-       }
-
-       public DslQueryBuilder edgeQuery(DslContext context) throws AAIException {
-               EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(context.getPreviousNode(), context.getCurrentNode());
-               String edgeType = "";
-               if (!edgeRules.hasRule(baseQ.build())) {
-                       throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + context.getPreviousNode()
-                                       + ", " + context.getCurrentNode());
-               } else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())) {
-                       edgeType = "EdgeType.TREE";
-               } else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
-                       edgeType = "EdgeType.COUSIN";
-               } else
-                       edgeType = "EdgeType.COUSIN";
-
-               query.append(".createEdgeTraversal(").append(edgeType).append(", '").append(context.getPreviousNode())
-                               .append("','").append(context.getCurrentNode()).append("')");
-
-               return this;
-       }
-
-       public DslQueryBuilder where(DslContext context) {
-               query.append(".where(builder.newInstance()");
-               return this;
-       }
-
-       public DslQueryBuilder endWhere(DslContext context) {
-               query.append(")");
-               return this;
-       }
-
-       public DslQueryBuilder endUnion(DslContext context) {
-               /*
-                * Need to delete the last comma
-                */
-               if (query.toString().endsWith(",")) {
-                       query.deleteCharAt(query.length() - 1);
-               }
-               query.append(")");
-               return this;
-       }
-
-       public DslQueryBuilder limit(DslContext context) {
-               /*
-                * limit queries are strange - You have to append in the end
-                */
-               AAIDslParser.LimitStepContext ctx = (AAIDslParser.LimitStepContext) context.getCtx();
-               context.setLimitQuery(new StringBuilder(".limit(").append(ctx.NODE().getText()).append(")"));
-               return this;
-       }
-
-       public DslQueryBuilder filter(DslContext context) {
-               return this.filterPropertyStart(context).filterPropertyKeys(context).filterPropertyEnd();
-
-       }
-
-       public DslQueryBuilder filterPropertyStart(DslContext context) {
-               AAIDslParser.FilterStepContext ctx = (AAIDslParser.FilterStepContext) context.getCtx();
-               if (ctx.NOT() != null && ctx.NOT().getText().equals("!"))
-                       query.append(".getVerticesExcludeByProperty(");
-               else
-                       query.append(".getVerticesByProperty(");
-
-               return this;
-
-       }
-
-       public DslQueryBuilder filterPropertyEnd() {
-               query.append(")");
-               return this;
-
-       }
-
-       public DslQueryBuilder validateFilter(DslContext context) throws AAIException {
-               Introspector obj = loader.introspectorFromName(context.getStartNode());
-               if(context.getStartNodeKeys().isEmpty()){
-                       queryException.append("No keys sent. Valid keys for " + context.getStartNode() + " are "
-                                       + String.join(",", obj.getIndexedProperties()));
-                       return this;
-               }
-               boolean notIndexed = context.getStartNodeKeys().stream()
-                               .filter((prop) -> obj.getIndexedProperties().contains(prop)).collect(Collectors.toList()).isEmpty();
-               if (notIndexed)
-                       queryException.append("Non indexed keys sent. Valid keys for " + context.getStartNode() + " "
-                                       + String.join(",", obj.getIndexedProperties()));
-
-               return this;
-       }
-
-       public DslQueryBuilder filterPropertyKeys(DslContext context) {
-               AAIDslParser.FilterStepContext ctx = (AAIDslParser.FilterStepContext) context.getCtx();
-               final String key = ctx.KEY(0).getText();
-               /*
-                * This key should be indexed if it is start node
-                */
-               if (context.isStartNode() && context.getStartNodeKeys().isEmpty()) {
-                       // check if key is not indexed, then throw exception
-                       context.getStartNodeKeys().add(key.replaceAll("'", ""));
-               }
-
-               query.append(key);
-               List<TerminalNode> nodes = ctx.KEY();
-               List<TerminalNode> numberValues = ctx.NODE();
-               /*
-                * Add all String values
-                */
-               List<String> valuesArray = nodes.stream().filter((node) -> !key.equals(node.getText()))
-                               .map((node) -> "'" + node.getText().replace("'", "").trim() + "'").collect(Collectors.toList());
-
-               /*
-                * Add all numeric values
-                */
-               valuesArray.addAll(numberValues.stream().filter((node) -> !key.equals(node.getText()) )
-                               .map((node) -> node.getText()).collect(Collectors.toList()));
-               
-               
-               /*
-                * The whole point of doing this to separate P.within from key-value
-                * search For a list of values QB uses P.within For just a single value
-                * QB uses key,value check
-                */
-               if (nodes.size() > 2) {
-                       String values = String.join(",", valuesArray);
-                       query.append(",").append(" new ArrayList<>(Arrays.asList(" + values.toString() + "))");
-               } else {
-                       if (!valuesArray.isEmpty())
-                               query.append(",").append(valuesArray.get(0).toString());
-               }
-               return this;
-       }
-
-       public DslQueryBuilder union(DslContext context) {
-               query.append(".union(");
-               return this;
-       }
-
-       public DslQueryBuilder store(DslContext context) {
-               AAIDslParser.SingleNodeStepContext ctx = (AAIDslParser.SingleNodeStepContext) context.getCtx();
-               if (ctx.STORE() != null && ctx.STORE().getText().equals("*")) {
-                       query.append(".store('x')");
-               }
-               return this;
-
-       }
-
-       public DslQueryBuilder comma(DslContext context) {
-               query.append(",");
-               return this;
-
-       }
+    private final EdgeIngestor edgeRules;
+    private final Loader loader;
+    private StringBuilder query;
+    private StringBuilder queryException;
+
+    public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) {
+        this.edgeRules = edgeIngestor;
+        this.loader = loader;
+        query = new StringBuilder();
+        queryException = new StringBuilder();
+    }
+
+    public StringBuilder getQuery() {
+        return query;
+    }
+
+    public void setQuery(StringBuilder query) {
+        this.query = query;
+    }
+
+    public StringBuilder getQueryException() {
+        return queryException;
+    }
+
+    public void setQueryException(StringBuilder queryException) {
+        this.queryException = queryException;
+    }
+
+    public DslQueryBuilder start() {
+        query.append("builder");
+        return this;
+    }
+
+    /*
+     * DSL always dedupes the results
+     */
+    public DslQueryBuilder end() {
+        query.append(".cap('x').unfold().dedup()");
+        return this;
+    }
+
+    public DslQueryBuilder nodeQuery(String node) {
+        query.append(".getVerticesByProperty('aai-node-type', '").append(node).append("')");
+        return this;
+    }
+
+    public DslQueryBuilder edgeQuery(List<String> edgeLabels, String aNode, String bNode) {
+        //TODO : change this for fuzzy search.
+
+        String edgeType = "";
+        String edgeLabelsClause = "";
+        String edgeTraversalClause = ".createEdgeTraversal(";
+
+
+        if (!edgeLabels.isEmpty()) {
+            edgeTraversalClause = ".createEdgeTraversalWithLabels(";
+            edgeLabelsClause = String.join("", ", new ArrayList<>(Arrays.asList(", Joiner.on(",").join(edgeLabels), "))");
+        }
+
+        EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(aNode, bNode);
+        Multimap<String, EdgeRule> rules = ArrayListMultimap.create();
+        try {
+            //TODO chnage this - ugly
+            if (edgeLabels.isEmpty()) {
+                rules.putAll(edgeRules.getRules(baseQ.build()));
+            } else {
+                edgeLabels.stream().forEach(label -> {
+                    try {
+                        rules.putAll(edgeRules.getRules(baseQ.label(label).build()));
+                    } catch (EdgeRuleNotFoundException e) {
+                        queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
+                                + ", " + bNode + label);
+
+                    }
+                });
+
+            }
+        } catch (EdgeRuleNotFoundException e) {
+            if (!edgeLabels.isEmpty()) {
+                queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
+                        + ", " + bNode + edgeLabels.stream().toString());
+            }
+            else {
+                queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
+                        + ", " + bNode);
+            }
+            return this;
+        }
+
+        if (rules.isEmpty() || rules.keys().isEmpty()) {
+            queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
+                    + ", " + bNode);
+        } else {
+            if (edgeLabels.isEmpty()) {
+                if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())) {
+                    edgeType = "EdgeType.TREE" + ",";
+                }
+                if (edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
+                    if (edgeType.isEmpty()) {
+                        edgeType = "EdgeType.COUSIN" + ",";
+                    } else {
+                        edgeType = "";
+                    }
+                }
+            }
+        }
+
+        query.append(edgeTraversalClause).append(edgeType).append(" '").append(aNode)
+                .append("','").append(bNode).append("'").append(edgeLabelsClause).append(")");
+
+        return this;
+    }
+
+
+    public DslQueryBuilder where() {
+        query.append(".where(");
+        return this;
+    }
+
+    public DslQueryBuilder endWhere() {
+        query.append(")");
+        return this;
+    }
+
+    public DslQueryBuilder limit(String limit) {
+        query.append(".limit(").append(limit).append(")");
+        return this;
+    }
+
+    public DslQueryBuilder filter(boolean isNot, String node, String key, List<String> values) {
+        return this.filterPropertyStart(isNot).filterPropertyKeys(node, key, values).filterPropertyEnd();
+    }
+
+    public DslQueryBuilder filterPropertyStart(boolean isNot) {
+        if (isNot) {
+            query.append(".getVerticesExcludeByProperty(");
+        } else {
+            query.append(".getVerticesByProperty(");
+        }
+        return this;
+    }
+
+    public DslQueryBuilder filterPropertyEnd() {
+        query.append(")");
+        return this;
+    }
+
+    public DslQueryBuilder validateFilter(String node, List<String> keys) {
+        try {
+            Introspector obj = loader.introspectorFromName(node);
+            if (keys.isEmpty()) {
+                queryException.append("No keys sent. Valid keys for " + node + " are "
+                        + String.join(",", obj.getIndexedProperties()));
+                return this;
+            }
+
+            boolean notIndexed = keys.stream()
+                    .filter(prop -> obj.getIndexedProperties().contains(prop)).collect(Collectors.toList()).isEmpty();
+
+            if (notIndexed) {
+                queryException.append("Non indexed keys sent. Valid keys for " + node + " "
+                        + String.join(",", obj.getIndexedProperties()));
+            }
+        } catch (AAIUnknownObjectException e) {
+            queryException.append("Unknown Object being referenced by the query" + node);
+        }
+        return this;
+
+    }
+
+    public DslQueryBuilder filterPropertyKeys(String node, String key, List<String> values) {
+        try {
+            Introspector obj = loader.introspectorFromName(node);
+
+            Optional<String> alias = obj.getPropertyMetadata(key, PropertyMetadata.DB_ALIAS);
+            if (alias.isPresent()) {
+                key = alias.get();
+            }
+            query.append(key);
+
+            if (!values.isEmpty()) {
+                if (values.size() > 1) {
+                    String valuesArray = String.join(",", values);
+                    query.append(",").append(" new ArrayList<>(Arrays.asList(" + valuesArray + "))");
+                } else {
+                    query.append(",").append(values.get(0));
+                }
+            }
+        } catch (AAIUnknownObjectException e) {
+            queryException.append("Unknown Object being referenced by the query" + node);
+        }
+        return this;
+    }
+
+    public DslQueryBuilder union() {
+        query.append(".union(");
+        return this;
+    }
+
+    public DslQueryBuilder endUnion() {
+        query.append(")");
+        return this;
+    }
+
+    public DslQueryBuilder store() {
+        query.append(".store('x')");
+        return this;
+    }
+
+    public DslQueryBuilder startInstance() {
+        query.append("builder.newInstance()");
+        return this;
+    }
+
+    public DslQueryBuilder endInstance() {
+        return this;
+    }
+
+    public DslQueryBuilder comma() {
+        query.append(",");
+        return this;
+    }
+
+
 }
index d9ce63e..a3978fd 100644 (file)
  */
 package org.onap.aai.rest.dsl;
 
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
 import org.antlr.v4.runtime.CharStreams;
 import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.ParseTreeWalker;
-
 import org.onap.aai.AAIDslLexer;
 import org.onap.aai.AAIDslParser;
 import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.rest.dsl.DslListener;
-import org.antlr.v4.runtime.Token;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+
+
 /**
  * The Class DslQueryProcessor.
  */
@@ -60,18 +58,23 @@ public class DslQueryProcessor {
 
                        // Create a lexer from the input CharStream
                        AAIDslLexer lexer = new AAIDslLexer(CharStreams.fromStream(stream, StandardCharsets.UTF_8));
+                       lexer.removeErrorListeners();
+                       lexer.addErrorListener(new AAIDslErrorListener());
 
                        // Get a list of tokens pulled from the lexer
                        CommonTokenStream tokens = new CommonTokenStream(lexer);
 
                        // Parser that feeds off of the tokens buffer
                        AAIDslParser parser = new AAIDslParser(tokens);
+                       parser.removeErrorListeners(); // remove ConsoleErrorListener
+                       parser.addErrorListener(new AAIDslErrorListener());
 
                        dslListener.setValidationFlag(isValidationFlag());
                        // Specify our entry point
                        ParseTree ptree = parser.aaiquery();
                        LOGGER.info("QUERY-interim" + ptree.toStringTree(parser));
 
+
                        // Walk it and attach our listener
                        ParseTreeWalker walker = new ParseTreeWalker();
                        walker.walk(dslListener, ptree);
@@ -83,8 +86,10 @@ public class DslQueryProcessor {
                         * 
                         */
                        return dslListener.getQuery();
-               } catch (AAIException e) {
-                       throw new AAIException("AAI_6149", "Error while processing the query :" + e.getMessage());
+               } catch(ParseCancellationException e){
+                       throw new AAIException("AAI_6149", "DSL Syntax Error while processing the query :" + e.getMessage());
+               } catch(AAIException e) {
+                       throw new AAIException("AAI_6149", "DSL Syntax Error  while processing the query :" + e.getMessage());
                } catch (Exception e) {
                        throw new AAIException("AAI_6149","Error while processing the query :" + e.getMessage());
                }
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryConfigDTO.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryConfigDTO.java
new file mode 100644 (file)
index 0000000..30d8d30
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest.search;
+
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright (C) 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=========================================================
+ */
+
+import org.springframework.util.StringUtils;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CustomQueryConfigDTO {
+
+       @JsonProperty("stored-query")
+       private String storedQuery;
+       @JsonProperty("query")
+       private CustomQueryDTO queryDTO;
+
+       public CustomQueryDTO getQueryDTO() {
+               if(queryDTO == null)
+                       queryDTO = new CustomQueryDTO();
+               if (!StringUtils.isEmpty(storedQuery)) {
+                       queryDTO.setQuery(storedQuery);
+               }
+               return queryDTO;
+       }
+
+       public void setQueryDTO(CustomQueryDTO query) {
+               this.queryDTO = query;
+       }
+
+       public void setStoredQuery(String storedQuery) {
+               this.storedQuery = storedQuery;
+       }
+       
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryDTO.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryDTO.java
new file mode 100644 (file)
index 0000000..16b1430
--- /dev/null
@@ -0,0 +1,56 @@
+package org.onap.aai.rest.search;
+
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Lists;
+
+public class CustomQueryDTO {
+
+       private String query;
+       @JsonProperty("optional-properties")
+       private List<String> queryOptionalProperties = Lists.newArrayList();
+       @JsonProperty("required-properties")
+       private List<String> queryRequiredProperties = Lists.newArrayList();;
+       
+       public void setQuery(String query) {
+               this.query = query;
+       }
+       public String getQuery() {
+               return this.query;
+       }
+
+       public void setQueryOptionalProperties( List<String> queryOptionalProperties) {
+               this.queryOptionalProperties = queryOptionalProperties;
+       }
+       public List<String> getQueryOptionalProperties( ) {
+               return queryOptionalProperties;
+       }
+       public void setQueryRequiredProperties( List<String> queryRequiredProperties) {
+               this.queryRequiredProperties = queryRequiredProperties;
+       }
+       public List<String> getQueryRequiredProperties( ) {
+               return queryRequiredProperties;
+       }
+
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryTestDTO.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/CustomQueryTestDTO.java
new file mode 100644 (file)
index 0000000..cdc9d15
--- /dev/null
@@ -0,0 +1,121 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest.search;
+
+/*-
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright (C) 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=========================================================
+ */
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.beust.jcommander.internal.Maps;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class CustomQueryTestDTO {
+       
+       
+       @JsonProperty("stored-query")
+       private String storedQuery;
+
+       @JsonProperty("vertices")
+       private List<LinkedHashMap<String, String>> verticesDtos;
+       
+       @JsonProperty("edges")
+       private List<LinkedHashMap<String, String>> edgesDtos;
+       
+       @JsonProperty("optional-properties")
+       private Map<String, String> queryOptionalProperties = Maps.newHashMap();
+       
+       @JsonProperty("required-properties")
+       private Map<String, String> queryRequiredProperties = Maps.newHashMap();
+       
+       @JsonProperty("expected-result")
+       private ExpectedResultsDto expectedResultsDtos;
+
+       public String getStoredQuery() {
+               return storedQuery;
+       }
+
+       public void setStoredQuery(String storedQuery) {
+               this.storedQuery = storedQuery;
+       }
+
+       public List<LinkedHashMap<String, String>> getVerticesDtos() {
+               return verticesDtos;
+       }
+
+       public void setVerticesDtos(List<LinkedHashMap<String, String>> verticesDtos) {
+               this.verticesDtos = verticesDtos;
+       }
+
+       public List<LinkedHashMap<String, String>> getEdgesDtos() {
+               return edgesDtos;
+       }
+
+       public void setEdgesDtos(List<LinkedHashMap<String, String>> edgesDtos) {
+               this.edgesDtos = edgesDtos;
+       }
+       
+       public Map<String, String> getQueryOptionalProperties() {
+               return queryOptionalProperties;
+       }
+
+       public void setQueryOptionalProperties(
+                       Map<String, String> queryOptionalProperties) {
+               this.queryOptionalProperties = queryOptionalProperties;
+       }
+
+       public Map<String, String> getQueryRequiredProperties() {
+               return queryRequiredProperties;
+       }
+
+       public void setQueryRequiredProperties(
+                       Map<String, String> queryRequiredProperties) {
+               this.queryRequiredProperties = queryRequiredProperties;
+       }
+
+       public ExpectedResultsDto getExpectedResultsDtos() {
+               return expectedResultsDtos;
+       }
+
+       public void setExpectedResultsDtos(ExpectedResultsDto expectedResultsDtos) {
+               this.expectedResultsDtos = expectedResultsDtos;
+       }
+
+               
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/ExpectedResultsDto.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/ExpectedResultsDto.java
new file mode 100644 (file)
index 0000000..9c4c3b0
--- /dev/null
@@ -0,0 +1,39 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+
+package org.onap.aai.rest.search;
+
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ExpectedResultsDto {
+       @JsonProperty("ids")
+       List<String> ids;
+
+       public List<String> getIds() {
+               return ids;
+       }
+
+       public void setIds(List<String> ids) {
+               this.ids = ids;
+       }
+       
+}
index 231c82b..ab3c9fd 100644 (file)
@@ -22,6 +22,8 @@ package org.onap.aai.web;
 import org.glassfish.jersey.filter.LoggingFilter;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.glassfish.jersey.servlet.ServletProperties;
+import org.onap.aai.rest.CQ2Gremlin;
+import org.onap.aai.rest.CQ2GremlinTest;
 import org.onap.aai.rest.DslConsumer;
 import org.onap.aai.rest.QueryConsumer;
 import org.onap.aai.rest.RecentAPIConsumer;
@@ -37,6 +39,7 @@ import org.springframework.stereotype.Component;
 import javax.annotation.Priority;
 import javax.ws.rs.container.ContainerRequestFilter;
 import javax.ws.rs.container.ContainerResponseFilter;
+
 import java.util.List;
 import java.util.Set;
 import java.util.logging.Logger;
@@ -60,6 +63,8 @@ public class JerseyConfiguration extends ResourceConfig {
         register(RecentAPIConsumer.class);
         register(DslConsumer.class);
         register(EchoResponse.class);
+        register(CQ2Gremlin.class);
+        register(CQ2GremlinTest.class);
 
         //Request Filters
         registerFiltersForRequests();
index cf34571..78162f5 100644 (file)
@@ -1,29 +1,41 @@
 /**
- * Define a grammar called AAIDsl
+ * Define a parser grammar called AAIDsl
  */
 grammar AAIDsl;
 
+aaiquery: startStatement limit?;
 
-aaiquery: dslStatement;
+startStatement: (vertex ) (traversal)* ;
+nestedStatement: (vertex|unionVertex ) (traversal)* ;
 
-dslStatement: (singleNodeStep ) (traverseStep )* limitStep*;
+vertex: label store? (filter)?;
 
-unionQueryStep: LBRACKET dslStatement ( COMMA (dslStatement))* RBRACKET;
+traversal:  (edge (vertex|unionVertex));
 
-traverseStep: (TRAVERSE (  singleNodeStep | unionQueryStep));
+filter:  (propertyFilter)* whereFilter?;
+propertyFilter: (not? '(' key (',' (key | num))* ')');
 
-singleNodeStep: NODE STORE? (filterStep | filterTraverseStep)*;
+whereFilter: (not? '(' edge nestedStatement ')' );
 
-filterStep: NOT? (LPAREN KEY (COMMA (KEY | NODE))* RPAREN);
-filterTraverseStep: (LPAREN traverseStep* RPAREN);
+unionVertex: '[' ( (edgeFilter)* nestedStatement ( comma ( (edgeFilter)* nestedStatement))*) ']';
 
-limitStep: LIMIT NODE;
+comma: ',';
+edge: TRAVERSE (edgeFilter)*;
+edgeFilter: '(' key (',' key )* ')';
 
-LIMIT: 'LIMIT';
-NODE: ID;
+num: NUM;
+limit: LIMIT num;
+label: (ID | NUM )+;
+key: KEY;
 
-KEY: ['] (ID | ' ')* ['] ;
+store: STORE;
+not: NOT;
 
+LIMIT: 'LIMIT'|'limit';
+NUM: (DIGIT)+;
+
+/*NODE: (ID | NUM )+;*/
+KEY : '\'' ( ~['\r\n] )*? '\'';
 
 AND: [&];
 
@@ -33,29 +45,18 @@ OR: [|];
 
 TRAVERSE: [>] ;
 
-LPAREN: [(];
-       
-RPAREN: [)];
-
-COMMA: [,] ;
-
 EQUAL: [=];
 
-LBRACKET: [[];
-       
-RBRACKET: [\]];
-
 NOT: [!];
 
-VALUE: [DIGIT]+;
-
 fragment LOWERCASE  : [a-z] ;
 fragment UPPERCASE  : [A-Z] ;
 fragment DIGIT      : [0-9] ;
+fragment  ESC : '\\' . ;
+fragment ID_SPECIALS: [-:_];
+
 ID
-   : ( LOWERCASE | UPPERCASE | DIGIT) ( LOWERCASE | UPPERCASE | DIGIT | '-' | '.' | '_' | '/')*
+   :  ( LOWERCASE | UPPERCASE  | DIGIT | ID_SPECIALS)
    ;
 
 WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines
-
-
index a07e985..b94c3b1 100644 (file)
@@ -31,23 +31,23 @@ aai.transaction.logging.get=true
 aai.transaction.logging.post=true
 
 aai.server.url.base=https://localhost:8443/aai/
-aai.server.url=https://localhost:8443/aai/v15/
+aai.server.url=https://localhost:8443/aai/v16/
 aai.global.callback.url=https://localhost:8443/aai/
 
 
-aai.notification.current.version=v15
+aai.notification.current.version=v16
 aai.notificationEvent.default.status=UNPROCESSED
 aai.notificationEvent.default.eventType=AAI-EVENT
 aai.notificationEvent.default.domain=devINT1
 aai.notificationEvent.default.sourceName=aai
 aai.notificationEvent.default.sequenceNumber=0
 aai.notificationEvent.default.severity=NORMAL
-aai.notificationEvent.default.version=v15
+aai.notificationEvent.default.version=v16
 # This one lets us enable/disable resource-version checking on updates/deletes
 aai.resourceversion.enableflag=true
 # This will specify how deep the stack trace should be logged
 aai.logging.maxStackTraceEntries=10
-aai.default.api.version=v15
+aai.default.api.version=v16
 
 # Used by Model-processing code
 aai.model.query.resultset.maxcount=50
index 2261713..2be5d88 100644 (file)
@@ -1,5 +1,5 @@
 # Retired properties
 retired.api.pattern.list=\
-  ^/aai/v[2-7]+/.*$\
+  ^/aai/v[2-9]+/.*$\
 
 retired.api.all.versions=
\ No newline at end of file
index 0a9ec97..7f5b1d8 100644 (file)
@@ -138,7 +138,7 @@ public class AAIGremlinQueryTest {
         String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
         headers.add("Authorization", "Basic " + authorization);
 
-        baseUrl = "https://localhost:" + randomPort;
+        baseUrl = "http://localhost:" + randomPort;
     }
 
     @Test
index 3956b70..76a1277 100644 (file)
@@ -163,7 +163,7 @@ public class QueryParameterTest {
         String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
         headers.add("Authorization", "Basic " + authorization);
 
-        baseUrl = "https://localhost:" + randomPort;
+        baseUrl = "http://localhost:" + randomPort;
     }
 
     @Test
index efb9e89..bc43979 100644 (file)
@@ -106,7 +106,7 @@ public class SubgraphPruneTest {
         String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
         headers.add("Authorization", "Basic " + authorization);
 
-        baseUrl = "https://localhost:" + randomPort;
+        baseUrl = "http://localhost:" + randomPort;
     }
 
     @Test
index 46e6be7..552feb6 100644 (file)
@@ -58,30 +58,35 @@ public class TraversalTestConfiguration {
     @Bean
     RestTemplate restTemplate(RestTemplateBuilder builder) throws Exception {
 
-        char[] trustStorePassword = env.getProperty("server.ssl.trust-store-password").toCharArray();
-        char[] keyStorePassword   = env.getProperty("server.ssl.key-store-password").toCharArray();
+        RestTemplate restTemplate = null;
 
-        String keyStore = env.getProperty("server.ssl.key-store");
-        String trustStore = env.getProperty("server.ssl.trust-store");
+        if(env.acceptsProfiles("one-way-ssl", "two-way-ssl")) {
+            char[] trustStorePassword = env.getProperty("server.ssl.trust-store-password").toCharArray();
+            char[] keyStorePassword = env.getProperty("server.ssl.key-store-password").toCharArray();
 
-        SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
+            String keyStore = env.getProperty("server.ssl.key-store");
+            String trustStore = env.getProperty("server.ssl.trust-store");
+            SSLContextBuilder sslContextBuilder = SSLContextBuilder.create();
 
-        if(env.acceptsProfiles("two-way-ssl")){
-            sslContextBuilder = sslContextBuilder.loadKeyMaterial(loadPfx(keyStore, keyStorePassword), keyStorePassword);
-        }
+            if (env.acceptsProfiles("two-way-ssl")) {
+                sslContextBuilder = sslContextBuilder.loadKeyMaterial(loadPfx(keyStore, keyStorePassword), keyStorePassword);
+            }
 
-        SSLContext sslContext = sslContextBuilder
-                .loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword)
-                .build();
+            SSLContext sslContext = sslContextBuilder
+                    .loadTrustMaterial(ResourceUtils.getFile(trustStore), trustStorePassword)
+                    .build();
 
-        HttpClient client = HttpClients.custom()
-                .setSSLContext(sslContext)
-                .setSSLHostnameVerifier((s, sslSession) -> true)
-                .build();
+            HttpClient client = HttpClients.custom()
+                    .setSSLContext(sslContext)
+                    .setSSLHostnameVerifier((s, sslSession) -> true)
+                    .build();
 
-        RestTemplate restTemplate =  builder
-                .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
-                .build();
+            restTemplate = builder
+                    .requestFactory(new HttpComponentsClientHttpRequestFactory(client))
+                    .build();
+        }else {
+            restTemplate = builder.build();
+        }
 
         restTemplate.setErrorHandler(new ResponseErrorHandler() {
             @Override
index 7235fa3..b767dbb 100644 (file)
@@ -99,7 +99,7 @@ public abstract class AbstractSpringRestTest {
         String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
         headers.add("Authorization", "Basic " + authorization);
         httpEntity = new HttpEntity(headers);
-        baseUrl = "https://localhost:" + randomPort;
+        baseUrl = "http://localhost:" + randomPort;
     }
 
     /*
index a566499..5edf12d 100644 (file)
@@ -84,7 +84,7 @@ public class BadQueryFormatTest {
         String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
         headers.add("Authorization", "Basic " + authorization);
 
-        baseUrl = "https://localhost:" + randomPort;
+        baseUrl = "http://localhost:" + randomPort;
     }
 
     @Test
index 347e21b..e4576ae 100644 (file)
@@ -107,7 +107,7 @@ public class DslConsumerTest extends AbstractSpringRestTest {
 
                httpEntity = new HttpEntity(payload, headers);
                responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class);
-               assertEquals("Expected the response to be 400", HttpStatus.INTERNAL_SERVER_ERROR,
+               assertEquals("Expected the response to be 404", HttpStatus.NOT_FOUND,
                                responseEntity.getStatusCode());
        }
        
index 80efe37..b894985 100644 (file)
@@ -96,7 +96,7 @@ public class QueryConsumerTest {
                headers.add("X-TransactionId", "JUNIT");
                String authorization = Base64.getEncoder().encodeToString("AAI:AAI".getBytes("UTF-8"));
                headers.add("Authorization", "Basic " + authorization);
-               baseUrl = "https://localhost:" + randomPort;
+               baseUrl = "http://localhost:" + randomPort;
                httpTestUtil = new HttpTestUtil();
                addPserver();
 
index e6665fd..340f8f8 100644 (file)
  */
 package org.onap.aai.rest.dsl;
 
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-
 import org.onap.aai.AAISetup;
 import org.onap.aai.exceptions.AAIException;
 
+import static org.junit.Assert.assertEquals;
+
 /**
  * The Class DslMain.
  */
 public class DslQueryProcessorTest extends AAISetup {
+       @Rule
+       public ExpectedException expectedEx = ExpectedException.none();
+
+       @Test
+       public void singleNode1() throws AAIException {
+               String aaiQuery = "cloud-region* !('cloud-owner','coid')";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner','coid')"
+                               + ".store('x').cap('x').unfold().dedup()";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void singleNodeLimit() throws AAIException {
+               String aaiQuery = "cloud-region* !('cloud-owner','coid') LIMIT 10";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner','coid')"
+                               + ".store('x').cap('x').unfold().dedup().limit(10)";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void specialCharacterTest() throws AAIException {
+               String aaiQuery = "cloud-region* !('cloud-owner','coidhello:?_-)(!@#$%^&*+={}[]|/.<,') LIMIT 10";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner','coidhello:?_-)(!@#$%^&*+={}[]|/.<,')"
+                               + ".store('x').cap('x').unfold().dedup().limit(10)";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void singleNodeLimitBlah() throws AAIException {
+               String aaiQuery = "cloud-region* !('cloud-owner','coid') LIMIT blah";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner','coid')"
+                               + ".getVerticesByProperty('cloud-region-id','cr id').store('x').cap('x').unfold().dedup().limit(10)";
+
+               expectedEx.expect(org.onap.aai.exceptions.AAIException.class);
+               expectedEx.expectMessage("DSL Syntax Error while processing the query");
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+       }
+
+       @Test
+       public void singleNodeLimitNull() throws AAIException {
+               String aaiQuery = "cloud-region* !('cloud-owner','coid') LIMIT ";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner','coid')"
+                               + ".getVerticesByProperty('cloud-region-id','cr id').store('x').cap('x').unfold().dedup().limit(10)";
+
+               expectedEx.expect(org.onap.aai.exceptions.AAIException.class);
+               expectedEx.expectMessage("DSL Syntax Error while processing the query");
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+       }
 
        @Test
        public void cloudRegion1Test() throws AAIException {
@@ -48,20 +105,38 @@ public class DslQueryProcessorTest extends AAISetup {
        @Test
        public void cloudRegion_entitlementTest() throws AAIException {
 
-               String aaiQuery = "generic-vnf('vnf-id','vnfId') (> vserver > tenant > cloud-region*('cloud-region-id','One')) > entitlement*";
+               /*
+               A store within a where makes no sense
+                */
+               String aaiQuery = "generic-vnf('vnf-id','vnfId') ( > vserver > tenant > cloud-region('cloud-region-id','One')) > entitlement*";
+
                String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').where("
                                + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver').createEdgeTraversal(EdgeType.TREE, 'vserver','tenant').createEdgeTraversal(EdgeType.TREE, 'tenant','cloud-region')"
-                               + ".getVerticesByProperty('cloud-region-id','One').store('x'))"
+                               + ".getVerticesByProperty('cloud-region-id','One'))"
                                + ".createEdgeTraversal(EdgeType.TREE, 'generic-vnf','entitlement').store('x').cap('x').unfold().dedup()";
 
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
                assertEquals(dslQuery, query);
        }
 
+       @Test
+       public void cloudRegion_entitlementTestWithLabels() throws AAIException {
+
+               String aaiQuery = "generic-vnf('vnf-id','vnfId') (> ('tosca.relationships.HostedOn') vserver > ('org.onap.relationships.inventory.BelongsTo') tenant > ('org.onap.relationships.inventory.BelongsTo') cloud-region('cloud-region-id','One')) > ('org.onap.relationships.inventory.ComposedOf')service-instance*";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').where("
+                               + "builder.newInstance().createEdgeTraversalWithLabels( 'generic-vnf','vserver', new ArrayList<>(Arrays.asList('tosca.relationships.HostedOn'))).createEdgeTraversalWithLabels( 'vserver','tenant', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.BelongsTo'))).createEdgeTraversalWithLabels( 'tenant','cloud-region', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.BelongsTo')))"
+                               + ".getVerticesByProperty('cloud-region-id','One'))"
+                               + ".createEdgeTraversalWithLabels( 'generic-vnf','service-instance', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.ComposedOf'))).store('x').cap('x').unfold().dedup()";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
        @Test
        public void complex_az_fromComplexTest() throws AAIException {
 
-               String aaiQuery = "cloud-region('cloud-owner','coid')('cloud-region-id','crid') > [ availability-zone* , complex*]";
+               String aaiQuery = "cloud-region('cloud-owner','coid')('cloud-region-id','crid')  > [  availability-zone* ,  complex*]";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
                String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region')"
                                + ".getVerticesByProperty('cloud-owner','coid').getVerticesByProperty('cloud-region-id','crid')"
@@ -71,6 +146,19 @@ public class DslQueryProcessorTest extends AAISetup {
                assertEquals(dslQuery, query);
        }
 
+       @Test
+       public void complex_az_fromComplexTestWithLabels() throws AAIException {
+
+               String aaiQuery = "cloud-region('cloud-owner','coid')('cloud-region-id','crid')  > [  ('org.onap.relationships.inventory.BelongsTo')availability-zone* ,  ('org.onap.relationships.inventory.LocatedIn')complex*]";
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region')"
+                               + ".getVerticesByProperty('cloud-owner','coid').getVerticesByProperty('cloud-region-id','crid')"
+                               + ".union(builder.newInstance().createEdgeTraversalWithLabels( 'cloud-region','availability-zone', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.BelongsTo'))).store('x')"
+                               + ",builder.newInstance().createEdgeTraversalWithLabels( 'cloud-region','complex', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.LocatedIn'))).store('x')).cap('x').unfold().dedup()";
+
+               assertEquals(dslQuery, query);
+       }
+
        @Test
        public void cloudRegion_fromComplex1Test() throws AAIException {
 
@@ -102,8 +190,8 @@ public class DslQueryProcessorTest extends AAISetup {
                                + ".where(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'vserver','generic-vnf').getVerticesByProperty('vnf-name','ZALL1MMSC03'))"
                                + ".createEdgeTraversal(EdgeType.TREE, 'vserver','tenant').createEdgeTraversal(EdgeType.TREE, 'tenant','cloud-region')"
                                + ".store('x').cap('x').unfold().dedup()";
-               String aaiQuery = "image('application-vendor','F5') > vserver (>generic-vnf('vnf-name','ZALL1MMSC03')) > tenant > cloud-region*";
 
+        String aaiQuery = "image('application-vendor','F5') > vserver (> generic-vnf('vnf-name','ZALL1MMSC03')) > tenant > cloud-region*";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
                assertEquals(builderQuery, query);
        }
@@ -117,8 +205,7 @@ public class DslQueryProcessorTest extends AAISetup {
                                + ").createEdgeTraversal(EdgeType.TREE, 'vserver','tenant').createEdgeTraversal(EdgeType.TREE, 'tenant','cloud-region')"
                                + ".store('x').cap('x').unfold().dedup()";
 
-               String aaiQuery = "image('application-vendor','vendor') >  vserver( >generic-vnf('nf-type', 'nfType') ) > tenant > cloud-region*";
-
+               String aaiQuery = "image('application-vendor','vendor') >  vserver(> generic-vnf('nf-type', 'nfType') ) > tenant > cloud-region*";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
 
                assertEquals(builderQuery, query);
@@ -166,8 +253,8 @@ public class DslQueryProcessorTest extends AAISetup {
                                + ".createEdgeTraversal(EdgeType.COUSIN, 'pserver','complex').store('x')"
                                + ").cap('x').unfold().dedup()";
 
-               String aaiQuery = "generic-vnf*('vnf-id','vnfId') >  " + "[  pserver* > complex*, "
-                               + " vserver > pserver* > complex* " + "]";
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId') > [ pserver* > complex*, "
+                               + "  vserver > pserver* > complex* " + "]";
 
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
 
@@ -175,19 +262,17 @@ public class DslQueryProcessorTest extends AAISetup {
        }
 
        @Test
-       public void complex_fromVnfTest() throws AAIException {
+       public void complex_fromVnfTest2() throws AAIException {
 
                String builderQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').store('x').union("
-                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','pserver').store('x')"
-                               + ".createEdgeTraversal(EdgeType.COUSIN, 'pserver','complex').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','pserver').store('x'),"
                                + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver')"
-                               + ".createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').store('x')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').store('x'))"
                                + ".createEdgeTraversal(EdgeType.COUSIN, 'pserver','complex').store('x')"
-                               + ").cap('x').unfold().dedup()";
-
-               String aaiQuery = "generic-vnf*('vnf-id','vnfId') >  " + "[  pserver* > complex*, "
-                               + " vserver > pserver* > complex* " + "]";
+                               + ".cap('x').unfold().dedup()";
 
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId')   > [  pserver* , "
+                               + "  vserver > pserver*  ] > complex*";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
 
                assertEquals(builderQuery, query);
@@ -208,8 +293,7 @@ public class DslQueryProcessorTest extends AAISetup {
 
                String aaiQuery = "customer('global-customer-id', 'a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb') > service-subscription('service-subscription-id', 'Nimbus') "
                                + " > service-instance('service-instance-id','sid') > generic-vnf* "
-                               + " > [ vnfc* , vserver*, pserver* , pnf* ]";
-
+                               + "  > [  vnfc* ,  vserver*,  pserver* ,  pnf* ]";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
 
                assertEquals(builderQuery, query);
@@ -222,8 +306,8 @@ public class DslQueryProcessorTest extends AAISetup {
                                + ".getVerticesByProperty('hostname','hostname1'),builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver')"
                                + ".createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').getVerticesByProperty('hostname','hostname1'))).store('x').cap('x').unfold().dedup()";
 
-               String aaiQuery = "generic-vnf*('vnf-id','vnfId') (> [pserver('hostname','hostname1'), "
-                               + "vserver > pserver('hostname','hostname1')])";
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId') (> [  pserver('hostname','hostname1'), "
+                               + " vserver > pserver('hostname','hostname1')])";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
 
                assertEquals(builderQuery, query);
@@ -259,7 +343,7 @@ public class DslQueryProcessorTest extends AAISetup {
        @Test
        public void hasNotPropertyNullValuesTest() throws AAIException {
                String aaiQuery = "cloud-region* !('cloud-owner',' ',' null ')";
-               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner', new ArrayList<>(Arrays.asList('','null'))).store('x').cap('x').unfold().dedup()";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesExcludeByProperty('cloud-owner', new ArrayList<>(Arrays.asList(' ',' null '))).store('x').cap('x').unfold().dedup()";
 
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
                assertEquals(dslQuery, query);
@@ -267,12 +351,38 @@ public class DslQueryProcessorTest extends AAISetup {
 
        @Test
        public void hasPropertyIntegerTest() throws AAIException {
-               String aaiQuery = "cloud-region('cloud-owner', 'att-nc')('cloud-region-id', 'MTN61a') > vlan-range > vlan-tag*('vlan-id-inner', 20)";
-               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesByProperty('cloud-owner','att-nc').getVerticesByProperty('cloud-region-id','MTN61a').getVerticesByProperty('vlan-id-inner',20).store('x').cap('x').unfold().dedup()";
+               String aaiQuery = "cloud-region('cloud-owner', 'att-nc')('cloud-region-id', 'MTN61a') > vlan-tag*('vlan-id-inner', 20)";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesByProperty('cloud-owner','att-nc').getVerticesByProperty('cloud-region-id','MTN61a').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region','vlan-tag').getVerticesByProperty('vlan-id-inner',20).store('x').cap('x').unfold().dedup()";
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void noEdgeRuleTest() throws AAIException {
+               String aaiQuery = "vserver('vserver-id','abc') > logical-link* > l-interface*";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'vserver').getVerticesByProperty('vserver-id','abc').createEdgeTraversal(EdgeType.TREE, 'vserver','logical-link').store('x').createEdgeTraversal('logical-link','l-interface').store('x')cap('x').unfold().dedup()";
+               expectedEx.expect(org.onap.aai.exceptions.AAIException.class);
+               expectedEx.expectMessage("No EdgeRule found for passed nodeTypes: vserver, logical-link");
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void multipleEdgeRuleTest() throws AAIException {
+               String aaiQuery = "vserver('vserver-id','abc') > l-interface* > lag-interface*";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'vserver').getVerticesByProperty('vserver-id','abc').createEdgeTraversal(EdgeType.TREE, 'vserver','l-interface').store('x').createEdgeTraversal( 'l-interface','lag-interface').store('x').cap('x').unfold().dedup()";
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void multipleEdgeRuleTestWithLabels() throws AAIException {
+               String aaiQuery = "vserver('vserver-id','abc') > l-interface* > ('org.onap.relationships.inventory.BelongsTo') lag-interface*";
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'vserver').getVerticesByProperty('vserver-id','abc').createEdgeTraversal(EdgeType.TREE, 'vserver','l-interface').store('x').createEdgeTraversalWithLabels( 'l-interface','lag-interface', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.BelongsTo'))).store('x').cap('x').unfold().dedup()";
                String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
                assertEquals(dslQuery, query);
        }
-       
+
        @Test
        public void hasNotPropertyTest() throws AAIException {
                String aaiQuery = "cloud-region* !('cloud-owner')";
@@ -282,4 +392,63 @@ public class DslQueryProcessorTest extends AAISetup {
                assertEquals(dslQuery, query);
        }
 
+       @Test
+       public void overlyNestedQueryTest() throws AAIException {
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId') (> [ pserver('hostname','hostname1'),  vserver (> [  pserver('hostname','hostname1'),  pserver('hostname','hostname1')])]) > vserver";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').where(builder.newInstance().union" +
+                               "(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','pserver').getVerticesByProperty('hostname','hostname1')," +
+                               "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver').where(builder.newInstance().union(builder.newInstance()" +
+                               ".createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').getVerticesByProperty('hostname','hostname1'),builder.newInstance()." +
+                               "createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').getVerticesByProperty('hostname','hostname1'))))).store('x').createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver').cap('x').unfold().dedup()";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void overlyNestedQueryTestWithLabels() throws AAIException {
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId') (> [ ('tosca.relationships.HostedOn')pserver('hostname','hostname1'),  ('tosca.relationships.HostedOn')vserver (> [  ('tosca.relationships.HostedOn')pserver('hostname','hostname1'),  ('tosca.relationships.HostedOn')pserver('hostname','hostname1')])]) > ('org.onap.relationships.inventory.PartOf')allotted-resource";
+
+               String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').where(builder.newInstance().union" +
+                               "(builder.newInstance().createEdgeTraversalWithLabels( 'generic-vnf','pserver', new ArrayList<>(Arrays.asList('tosca.relationships.HostedOn'))).getVerticesByProperty('hostname','hostname1')," +
+                               "builder.newInstance().createEdgeTraversalWithLabels( 'generic-vnf','vserver', new ArrayList<>(Arrays.asList('tosca.relationships.HostedOn'))).where(builder.newInstance().union(builder.newInstance()" +
+                               ".createEdgeTraversalWithLabels( 'vserver','pserver', new ArrayList<>(Arrays.asList('tosca.relationships.HostedOn'))).getVerticesByProperty('hostname','hostname1'),builder.newInstance()." +
+                               "createEdgeTraversalWithLabels( 'vserver','pserver', new ArrayList<>(Arrays.asList('tosca.relationships.HostedOn'))).getVerticesByProperty('hostname','hostname1'))))).store('x').createEdgeTraversalWithLabels( 'generic-vnf','allotted-resource', new ArrayList<>(Arrays.asList('org.onap.relationships.inventory.PartOf'))).cap('x').unfold().dedup()";
+
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+               assertEquals(dslQuery, query);
+       }
+
+       @Test
+       public void nestedUnionQueryTest() throws AAIException {
+
+               String builderQuery = "builder.getVerticesByProperty('aai-node-type', 'generic-vnf').getVerticesByProperty('vnf-id','vnfId').store('x').union("
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','pserver').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','vserver')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'vserver','pserver').store('x'))"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'pserver','complex').store('x')"
+                               + ".union(builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex','availability-zone')"
+                               + ".createEdgeTraversal(EdgeType.TREE, 'availability-zone','cloud-region').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'complex','cloud-region').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.TREE, 'complex','ctag-pool').store('x').union("
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'ctag-pool','availability-zone').store('x')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'availability-zone','complex').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'ctag-pool','generic-vnf').store('x')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'generic-vnf','availability-zone').store('x')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'availability-zone','complex').store('x'),"
+                               + "builder.newInstance().createEdgeTraversal(EdgeType.COUSIN, 'ctag-pool','vpls-pe').store('x')"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'vpls-pe','complex').store('x'))"
+                               + ".createEdgeTraversal(EdgeType.COUSIN, 'complex','cloud-region').store('x'))"
+                               + ".createEdgeTraversal(EdgeType.TREE, 'cloud-region','tenant').store('x')"
+                               + ".cap('x').unfold().dedup()";
+
+               String aaiQuery = "generic-vnf*('vnf-id','vnfId')   > [  pserver* , "
+                               + "  vserver > pserver*  ] > complex*  > [  availability-zone > cloud-region*,  cloud-region*,  " +
+                         "  ctag-pool*  > [  availability-zone* > complex* ,   generic-vnf* > availability-zone* > complex*,  vpls-pe* > complex*] > cloud-region*] > tenant* " ;
+               String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+
+               assertEquals(builderQuery, query);
+       }
+
 }
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/dsl/ProdDslTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/dsl/ProdDslTest.java
new file mode 100644 (file)
index 0000000..822643e
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest.dsl;
+
+import org.junit.Test;
+import org.onap.aai.AAISetup;
+import org.onap.aai.exceptions.AAIException;
+
+import static org.junit.Assert.assertEquals;
+
+//TODO: Change this to read queries and their builder equivalent from a file
+//TODO: Add queries run by SEs
+
+public class ProdDslTest extends AAISetup {
+    @Test
+    public void msoQueryTest1() throws AAIException {
+        String aaiQuery = "cloud-region('cloud-owner', 'value')('cloud-region-id', 'value') > vlan-tag*('vlan-id-outer', 'value')";
+
+        String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'cloud-region').getVerticesByProperty('cloud-owner','value')"
+                + ".getVerticesByProperty('cloud-region-id','value').createEdgeTraversal(EdgeType.COUSIN, 'cloud-region','vlan-tag')"
+                + ".getVerticesByProperty('vlan-id-outer','value').store('x').cap('x').unfold().dedup()";
+
+        String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+        assertEquals(dslQuery, query);
+    }
+
+    @Test
+    public void msoQueryTest2() throws AAIException {
+        String aaiQuery = "pserver('hostname', 'pserver-1') > p-interface > sriov-pf*('pf-pci-id', '0000:ee:00.0')";
+
+        String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'pserver').getVerticesByProperty('hostname','pserver-1')"
+                + ".createEdgeTraversal(EdgeType.TREE, 'pserver','p-interface')"
+                + ".createEdgeTraversal(EdgeType.TREE, 'p-interface','sriov-pf').getVerticesByProperty('pf-pci-id','0000:ee:00.0').store('x').cap('x').unfold().dedup()";
+
+        String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+        assertEquals(dslQuery, query);
+    }
+
+    @Test
+    public void msoQueryTest3() throws AAIException {
+        String aaiQuery = "l-interface ('interface-id', 'value') > sriov-vf > sriov-pf*";
+
+        String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'l-interface').getVerticesByProperty('interface-id','value')"
+                + ".createEdgeTraversal(EdgeType.TREE, 'l-interface','sriov-vf')"
+                + ".createEdgeTraversal(EdgeType.COUSIN, 'sriov-vf','sriov-pf').store('x').cap('x').unfold().dedup()";
+
+        String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+        assertEquals(dslQuery, query);
+    }
+
+    //TODO : Get this from schema
+    @Test
+    public void msoQueryTest4() throws AAIException {
+        //String aaiQuery = "l-interface ('interface-id', 'value') > lag-interface('interface-name', 'bond1') > sriov-pf*";
+        String aaiQuery = "l-interface ('interface-id', 'value') > lag-interface('interface-name', 'bond1') > p-interface > sriov-pf*";
+
+        String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'l-interface').getVerticesByProperty('interface-id','value')"
+                + ".createEdgeTraversal( 'l-interface','lag-interface').getVerticesByProperty('interface-name','bond1')"
+                + ".createEdgeTraversal(EdgeType.COUSIN, 'lag-interface','p-interface').createEdgeTraversal(EdgeType.TREE, 'p-interface','sriov-pf').store('x').cap('x').unfold().dedup()";
+
+        String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+        assertEquals(dslQuery, query);
+    }
+
+    //TODO : Get this from schema
+    @Test
+    public void msoQueryTest5() throws AAIException {
+        //String aaiQuery = "pserver ('hostname', 'value') > vserver ('vserver-name', 'value') > l-interface > vlan-tag*";
+        String aaiQuery = "pserver ('hostname', 'value') > vserver ('vserver-name', 'value') > l-interface > cp > vlan-tag*";
+        String dslQuery = "builder.getVerticesByProperty('aai-node-type', 'pserver').getVerticesByProperty('hostname','value')"
+                + ".createEdgeTraversal(EdgeType.COUSIN, 'pserver','vserver').getVerticesByProperty('vserver-name','value')"
+                + ".createEdgeTraversal(EdgeType.TREE, 'vserver','l-interface').createEdgeTraversal(EdgeType.COUSIN, 'l-interface','cp').createEdgeTraversal(EdgeType.COUSIN, 'cp','vlan-tag').store('x').cap('x').unfold().dedup()";
+
+        String query = dslQueryProcessor.parseAaiQuery(aaiQuery);
+        assertEquals(dslQuery, query);
+    }
+
+}
\ No newline at end of file
diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/search/GetVNFVpnBondingServiceDetailsTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/search/GetVNFVpnBondingServiceDetailsTest.java
new file mode 100644 (file)
index 0000000..b859b84
--- /dev/null
@@ -0,0 +1,112 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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=========================================================
+ */
+package org.onap.aai.rest.search;
+
+import java.util.Map;
+
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.structure.T;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
+
+public class GetVNFVpnBondingServiceDetailsTest extends QueryTest {
+
+    public GetVNFVpnBondingServiceDetailsTest() throws AAIException, NoEdgeRuleFoundException {
+        super();
+    }
+
+    // Test ignored for time being as query files pulled from aai-queries in schema-service differ
+    // from the stored-queries.json file that used to reside in traversal.
+    @Ignore
+    @Test
+    public void run() {
+        super.run();
+    }
+
+    @Override
+    protected void createGraph() throws AAIException, NoEdgeRuleFoundException {
+        //Set up the test graph
+
+
+        Vertex gnvf1 = graph.addVertex(T.label, "generic-vnf", T.id, "0", "aai-node-type", "generic-vnf", "vnf-id", "vnf-id-1", "vnf-name", "vnf-name-1");
+        Vertex vserver = graph.addVertex(T.label, "vserver", T.id, "1", "aai-node-type", "vserver", "vserver-name1", "vservername1");
+        Vertex linter1 = graph.addVertex(T.label, "l-interface", T.id, "2", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-1", "l-interface-name", "l-interface-name1");
+        Vertex linter2 = graph.addVertex(T.label, "l-interface", T.id, "3", "aai-node-type", "l-interface", "l-interface-id", "l-interface-id-2", "l-interface-name", "l-interface-name2");
+        Vertex vlan1 = graph.addVertex(T.label, "vlan", T.id, "4", "aai-node-type", "vlan","vlan-interface", "vlan11");
+        Vertex config1 = graph.addVertex(T.label, "configuration", T.id, "5", "aai-node-type", "configuration", "configuration-id", "configuration1");
+        Vertex l3network1 = graph.addVertex(T.label, "l3-network", T.id, "6", "aai-node-type", "l3-network", "ll3-network-id", "l3-network-id-1", "l3-network-name", "l3-network-name1");
+        Vertex l3inter1ipv4addresslist = graph.addVertex(T.label, "interface-ipv4-address-list", T.id, "7", "aai-node-type", "l3-interface-ipv4-address-list", "l3-interface-ipv4-address-list-id", "l3-interface-ipv4-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1");
+        Vertex l3inter1ipv6addresslist = graph.addVertex(T.label, "l3-interface-ipv6-address-list", T.id, "8", "aai-node-type", "l3-interface-ipv6-address-list", "l3-interface-ipv6-address-list-id", "l3-interface-ipv6-address-list-id-1", "l3-interface-ipv6-address-list-name", "l3-interface-ipv6-address-list-name1");
+        Vertex configVpnBinding = graph.addVertex(T.label, "vpn-binding", T.id, "9", "aai-node-type", "vpn-binding",
+                "vpn-id", "test-binding-config", "vpn-name", "test");
+        Vertex customer = graph.addVertex(T.label, "customer", T.id, "10", "aai-node-type", "customer", "customer-id", "customer-id-1", "customer-name", "customer-name1");
+        Vertex subnet1 = graph.addVertex(T.label, "subnet", T.id, "11", "aai-node-type", "subnet", "subnet-id", "subnet-id-11");
+        Vertex routeTarget1 = graph.addVertex(T.label, "route-target", T.id, "12", "aai-node-type", "route-target", "global-route-target", "111");
+
+
+        GraphTraversalSource g = graph.traversal();
+        rules.addEdge(g, gnvf1, vserver);//false
+        rules.addEdge(g, gnvf1, config1);//false
+        rules.addTreeEdge(g, vserver, linter1);//true
+        rules.addTreeEdge(g, linter1, linter2);//true
+        rules.addTreeEdge(g, linter2, vlan1);//true
+        rules.addEdge(g, config1, l3network1 );//false
+        rules.addTreeEdge(g, l3network1, subnet1);//true
+        rules.addEdge(g, subnet1, l3inter1ipv4addresslist );//false
+        rules.addEdge(g, subnet1, l3inter1ipv6addresslist );//false
+        rules.addEdge(g, l3network1, configVpnBinding );//false
+        rules.addEdge(g, configVpnBinding, customer );//false
+        rules.addTreeEdge(g, configVpnBinding, routeTarget1);//true
+
+
+        expectedResult.add(vserver);
+        expectedResult.add(config1);
+        expectedResult.add(linter1);
+        expectedResult.add(linter2);
+        expectedResult.add(vlan1);
+        expectedResult.add(l3network1);
+        expectedResult.add(subnet1);
+        expectedResult.add(l3inter1ipv4addresslist);
+        expectedResult.add(l3inter1ipv6addresslist);
+        expectedResult.add(configVpnBinding);
+        expectedResult.add(customer);
+        expectedResult.add(routeTarget1);
+
+    }
+
+    @Override
+    protected String getQueryName() {
+        return "getVNFVpnBondingServiceDetails";
+    }
+    @Override
+    protected void addStartNode(GraphTraversal<Vertex, Vertex> g) {
+        g.has("vnf-name", "vnf-name-1");
+
+    }
+    @Override
+    protected void addParam(Map<String, Object> params) {
+        params.put("vnf-name", "vnf-name-1");
+    }
+}
index fc53f7a..48a0b60 100644 (file)
@@ -57,7 +57,7 @@ schema.ingest.file=${server.local.startpath}/application-test.properties
 # Schema Version Related Attributes
 schema.uri.base.path=/aai
 # Lists all of the versions in the schema
-schema.version.list=v10,v11,v12,v13,v14,v15
+schema.version.list=v10,v11,v12,v13,v14,v15,v16
 # Specifies from which version should the depth parameter to default to zero
 schema.version.depth.start=v10
 # Specifies from which version should the related link be displayed in response payload
@@ -70,5 +70,5 @@ schema.version.namespace.change.start=v12
 # Specifies from which version should the client start seeing the edge label in payload
 schema.version.edge.label.start=v12
 # Specifies the version that the application should default to
-schema.version.api.default=v15
+schema.version.api.default=v16
 schema.translator.list=config
\ No newline at end of file
index 57b51d5..7e244bb 100644 (file)
@@ -12,7 +12,7 @@ spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSou
 
 spring.jersey.application-path=${schema.uri.base.path}
 
-spring.profiles.active=production,one-way-ssl
+spring.profiles.active=production
 #The max number of active threads in this pool
 server.tomcat.max-threads=200
 #The minimum number of threads always kept alive
@@ -29,13 +29,14 @@ server.local.startpath=src/main/resources/
 server.basic.auth.location=${server.local.startpath}etc/auth/realm.properties
 
 server.port=8446
-server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
-server.ssl.key-store=${server.local.startpath}etc/auth/aai_keystore
-server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.trust-store=${server.local.startpath}etc/auth/aai_keystore
-server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
-server.ssl.client-auth=want
-server.ssl.key-store-type=JKS
+security.require-ssl=false 
+server.ssl.enabled=false
+#server.ssl.enabled-protocols=TLSv1.1,TLSv1.2
+#server.ssl.key-store=${server.local.startpath}etc/auth/aai_keystore
+#server.ssl.key-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
+#server.ssl.trust-store-password=password(OBF:1vn21ugu1saj1v9i1v941sar1ugw1vo0)
+#server.ssl.client-auth=want
+#server.ssl.key-store-type=JKS
 
 # JMS bind address host port
 jms.bind.address=tcp://localhost:61646
@@ -60,7 +61,7 @@ schema.ingest.file=${server.local.startpath}/application-test.properties
 # Schema Version Related Attributes
 schema.uri.base.path=/aai
 # Lists all of the versions in the schema
-schema.version.list=v10,v11,v12,v13,v14,v15
+schema.version.list=v10,v11,v12,v13,v14,v15,v16
 # Specifies from which version should the depth parameter to default to zero
 schema.version.depth.start=v10
 # Specifies from which version should the related link be displayed in response payload
@@ -73,6 +74,6 @@ schema.version.namespace.change.start=v12
 # Specifies from which version should the client start seeing the edge label in payload
 schema.version.edge.label.start=v12
 # Specifies the version that the application should default to
-schema.version.api.default=v15
+schema.version.api.default=v16
 
 schema.translator.list=config
index f461aea..9371645 100644 (file)
@@ -2,9 +2,9 @@ schema.configuration.location=N/A
 schema.nodes.location=src/main/resources/etc/oxm/
 schema.edges.location=src/main/resources/etc/dbedgerules/
 
-schema.version.list=v10,v11,v12,v13,v14,v15
+schema.version.list=v10,v11,v12,v13,v14,v15,v16
 schema.version.depth.start=v10
 schema.version.related.link.start=v10
 schema.version.app.root.start=v11
 schema.version.edge.label.start=v12
-schema.version.api.default=v15
+schema.version.api.default=v16