Add utilites and unit tests to help coverage 37/28137/1
authorVenkata Harish K Kajur <vk250x@att.com>
Mon, 15 Jan 2018 05:47:04 +0000 (00:47 -0500)
committerVenkata Harish K Kajur <vk250x@att.com>
Mon, 15 Jan 2018 05:47:41 +0000 (00:47 -0500)
Issue-ID: AAI-649
Change-Id: Ia855abe83692d86f4243f98ca75737c991da8976
Signed-off-by: Venkata Harish K Kajur <vk250x@att.com>
15 files changed:
aai-core/pom.xml
aai-core/src/main/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngine.java
aai-core/src/main/java/org/onap/aai/serialization/engines/query/QueryEngine.java
aai-core/src/test/java/org/onap/aai/AAIJunitRunner.java [new file with mode: 0644]
aai-core/src/test/java/org/onap/aai/HttpTestUtil.java [new file with mode: 0644]
aai-core/src/test/java/org/onap/aai/PayloadUtil.java [new file with mode: 0644]
aai-core/src/test/java/org/onap/aai/rest/PserverTest.java [new file with mode: 0644]
aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java [new file with mode: 0644]
aai-core/src/test/java/org/onap/aai/serialization/db/DbSerializerTest.java
aai-core/src/test/java/org/onap/aai/serialization/engines/query/GraphTraversalQueryEngineTest.java
aai-core/src/test/resources/bundleconfig-local/etc/appprops/aaiconfig.properties
aai-core/src/test/resources/payloads/templates/pserver.json [new file with mode: 0644]
aai-core/src/test/resources/payloads/templates/relationship.json [new file with mode: 0644]
aai-schema/src/main/resources/aai_schema/aai_schema_v12.xsd
aai-schema/src/main/resources/oxm/aai_oxm_v12.xml

index 37edc5b..a93e2e6 100644 (file)
@@ -24,6 +24,7 @@
         <gendoc.version>v12</gendoc.version>
         <aai.wiki.link>https://wiki.onap.org/</aai.wiki.link>
         <hbase.version>1.0.2</hbase.version>
+        <jackson.version>2.2.3</jackson.version>
     </properties>
     <profiles>
         <profile>
         <dependency>
             <groupId>com.fasterxml.jackson.jaxrs</groupId>
             <artifactId>jackson-jaxrs-json-provider</artifactId>
-            <version>2.1.4</version>
+            <version>${jackson.version}</version>
         </dependency>
         <dependency>
             <groupId>com.googlecode.json-simple</groupId>
         <dependency>
             <groupId>com.fasterxml.jackson.module</groupId>
             <artifactId>jackson-module-jaxb-annotations</artifactId>
-            <version>2.1.4</version>
+            <version>${jackson.version}</version>
         </dependency>
         <dependency>
             <groupId>com.sun.jersey</groupId>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
-            <version>2.1.4</version>
+            <version>${jackson.version}</version>
         </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-annotations</artifactId>
-            <version>2.1.4</version>
+            <version>${jackson.version}</version>
         </dependency>
         <dependency>
             <groupId>com.fasterxml.jackson.dataformat</groupId>
             <artifactId>jackson-dataformat-yaml</artifactId>
-            <version>2.1.4</version>
+            <version>${jackson.version}</version>
         </dependency>
         <dependency>
             <groupId>xml-apis</groupId>
             <version>1.6.2</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.skyscreamer</groupId>
+            <artifactId>jsonassert</artifactId>
+            <version>1.4.0</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
index 692fd53..7efe2ea 100644 (file)
@@ -69,6 +69,7 @@ public class GraphTraversalQueryEngine extends QueryEngine {
        @Override
        public List<Vertex> findParents(Vertex start) {
                
+               @SuppressWarnings("unchecked")
                final GraphTraversal<Vertex, Vertex> pipe = this.g.V(start).emit(v -> true).repeat(__.union(__.inE().has(CONTAINS.toString(), OUT.toString()).outV(), __.outE().has(CONTAINS.toString(), IN.toString()).inV()));
                return pipe.toList();
        }
@@ -79,6 +80,7 @@ public class GraphTraversalQueryEngine extends QueryEngine {
        @Override
        public List<Vertex> findAllChildren(Vertex start) {
                
+               @SuppressWarnings("unchecked")
                GraphTraversal<Vertex, Vertex> pipe =  this.g
                                .V(start).emit(v -> true).repeat(__.union(__.outE().has(CONTAINS.toString(), OUT.toString()).inV(), __.inE().has(CONTAINS.toString(), IN.toString()).outV()));
                
@@ -87,7 +89,12 @@ public class GraphTraversalQueryEngine extends QueryEngine {
                
        }
 
+       /**
+        * {@inheritDoc}
+        */
+       @Override
        public List<Vertex> findChildrenOfType(Vertex start, String type) {
+               @SuppressWarnings("unchecked")
                GraphTraversal<Vertex, Vertex> pipe =  this.g.V(start).union(
                                        __.outE().has(CONTAINS.toString(), OUT.toString()).inV(),
                                        __.inE().has(CONTAINS.toString(), IN.toString()).outV()
@@ -96,7 +103,12 @@ public class GraphTraversalQueryEngine extends QueryEngine {
                return pipe.toList();
        }
        
+       /**
+        * {@inheritDoc}
+        */
+       @Override
        public List<Vertex> findChildren(Vertex start) {
+               @SuppressWarnings("unchecked")
                GraphTraversal<Vertex, Vertex> pipe =  this.g.V(start).union(
                                        __.outE().has(CONTAINS.toString(), OUT.toString()),
                                        __.inE().has(CONTAINS.toString(), IN.toString())
@@ -110,6 +122,7 @@ public class GraphTraversalQueryEngine extends QueryEngine {
         */
        @Override
        public List<Vertex> findDeletable(Vertex start) {
+               @SuppressWarnings("unchecked")
                GraphTraversal<Vertex, Vertex> pipe = this.g
                                .V(start).emit(v -> true).repeat(
                                        __.union(
index 01f11b1..5a468b7 100644 (file)
@@ -34,7 +34,7 @@ import java.util.List;
 
 public abstract class QueryEngine {
 
-       final protected GraphTraversalSource g;
+       protected final GraphTraversalSource g;
 
        /**
         * Instantiates a new query engine.
@@ -46,49 +46,103 @@ public abstract class QueryEngine {
        }
        
        /**
-        * Find parents.
+        * Finds all the parents/grandparents/etc of the given start node.
         *
-        * @param start the start
-        * @return the list
+        * @param start - the start vertex whose parent chain you want
+        * @return the list of start and start's parent, grandparent, etc, in
+        *                      order (ie {start, parent, grandparent, etc} 
         */
        public abstract List<Vertex> findParents(Vertex start);
        
        /**
-        * Find children.
+        * Finds all children, grandchildren, etc of start
         *
-        * @param start the start
-        * @return the list
+        * @param start the start vertex
+        * @return the list of child/grandchild/etc vertices
         */
        public abstract List<Vertex> findAllChildren(Vertex start);
        
+       /**
+        * Finds all immediate children of start (no grandchildren or so forth) of the given type
+        * @param start - the start vertex
+        * @param type - the desired aai-node-type
+        * @return the list of immediate child vertices of given type
+        */
        public abstract List<Vertex> findChildrenOfType(Vertex start, String type);
        
+       /**
+        * Finds all immediate children of start (no grandchildren or so forth)
+        * @param start - the start vertex
+        * @return the list of immediate child vertices
+        */
        public abstract List<Vertex> findChildren(Vertex start);
+       
        /**
-        * Find deletable.
+        * Find all vertices that should be deleted in a cascade from a delete of start
         *
-        * @param start the start
-        * @return the list
+        * @param start - the start vertex
+        * @return the list of vertices to be deleted when start is deleted
         */
        public abstract List<Vertex> findDeletable(Vertex start);
        
+       /**
+        * Finds the subgraph under start, including cousins as well as start's children/grandchildren/etc.
+        * More specifically, this includes start, all its descendants, start's cousins, and start's
+        * descendants' cousins (but not any of the cousins' cousins or descendants), and the edges
+        * connecting them.
+        * 
+        * @param start - the start vertex
+        * @return - Tree containing nodes and edges of the subgraph 
+        */
        public Tree<Element> findSubGraph(Vertex start) {
                return findSubGraph(start, AAIProperties.MAXIMUM_DEPTH, false);
        }
+       
+       /**
+        * Finds the subgraph under start, including cousins as well as start's children/grandchildren/etc.
+        * More specifically, this includes start, all its descendants, start's cousins, and start's
+        * descendants' cousins (but not any of the cousins' cousins or descendants), and the edges
+        * connecting them.
+        * 
+        * @param start - the start vertex
+        * @param iterations - depth of the subgraph, this limits how many generations of 
+        *                                              descendants are included
+        * @param nodeOnly - if true the subgraph will NOT include the cousins
+        * @return Tree containing nodes and edges of the subgraph 
+        */
        public abstract Tree<Element> findSubGraph(Vertex start, int iterations, boolean nodeOnly);
+       
        /**
-        * Find related vertices.
+        * Find vertices of type nodeType related to start by edges of the given
+        *  direction and label.
         *
-        * @param start the start
-        * @param direction the direction
-        * @param label the label
-        * @param nodeType the node type
-        * @return the list
+        * @param start - the start vertex
+        * @param direction - the direction of edges to traverse from start
+        * @param label - the label of edges to traverse from start
+        * @param nodeType - the node type the results should be
+        * @return the list of related vertices
         */
        public abstract List<Vertex> findRelatedVertices(Vertex start, Direction direction, String label, String nodeType);
 
+       /**
+        * Finds cousin edges connecting start to other vertices only of types defined in an old version.
+        * The idea is that if a user is using an old version, they won't understand any new node types in
+        * subsequent versions. Thus, revealing edges to new types will cause problems. This methods 
+        * filters any such edges out.
+        * 
+        * @param start - the start vertex
+        * @param loader - loader for retrieving the list of allowed node types for the desired version
+        *                                      (version is set when the loader was instantiated)
+        * @return list of cousin edges between start and any node types understood by the version specified in loader
+        */
        public abstract List<Edge> findEdgesForVersion(Vertex start, Loader loader);
        
+       /**
+        * Finds all cousins of start. 
+        * 
+        * @param start - the start vertex
+        * @return list of start's cousin vertices
+        */
        public abstract List<Vertex> findCousinVertices(Vertex start);
 
 }
diff --git a/aai-core/src/test/java/org/onap/aai/AAIJunitRunner.java b/aai-core/src/test/java/org/onap/aai/AAIJunitRunner.java
new file mode 100644 (file)
index 0000000..52c83bf
--- /dev/null
@@ -0,0 +1,60 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+import org.onap.aai.util.AAIConstants;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+public class AAIJunitRunner extends BlockJUnit4ClassRunner {
+
+    public AAIJunitRunner(Class<?> klass) throws InitializationError {
+        super(klass);
+        setProps();
+        modifyOxmHome();
+    }
+
+    public void setProps(){
+        System.setProperty("AJSC_HOME", ".");
+        System.setProperty("BUNDLECONFIG_DIR", "src/test/resources/bundleconfig-local");
+    }
+
+    public void modifyOxmHome(){
+        try {
+            Field aaiConstantsField = AAIConstants.class.getField("AAI_HOME_ETC_OXM");
+            setFinalStatic(aaiConstantsField, "../aai-schema/src/main/resources/oxm/");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void setFinalStatic(Field field, Object newValue) throws Exception {
+        field.setAccessible(true);
+        Field modifiersField = Field.class.getDeclaredField("modifiers");
+        modifiersField.setAccessible(true);
+        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+        field.set(null, newValue);
+    }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java b/aai-core/src/test/java/org/onap/aai/HttpTestUtil.java
new file mode 100644 (file)
index 0000000..1ec1a05
--- /dev/null
@@ -0,0 +1,369 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.javatuples.Pair;
+import org.mockito.Mockito;
+import org.onap.aai.dbmap.DBConnectionType;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.introspection.Version;
+import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.parsers.uri.URIToObject;
+import org.onap.aai.rest.db.DBRequest;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.restcore.HttpMethod;
+import org.onap.aai.restcore.RESTAPI;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+import javax.ws.rs.core.*;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.*;
+
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+public class HttpTestUtil extends RESTAPI {
+
+    private static final EELFLogger logger = EELFManager.getInstance().getLogger(HttpTestUtil.class);
+
+    protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
+
+    private static final String EMPTY = "";
+
+    protected HttpHeaders httpHeaders;
+    protected UriInfo uriInfo;
+
+    protected MultivaluedMap<String, String> headersMultiMap;
+    protected MultivaluedMap<String, String> queryParameters;
+
+    protected List<String> aaiRequestContextList;
+    protected List<MediaType> outputMediaTypes;
+
+    public void init(){
+
+        httpHeaders         = Mockito.mock(HttpHeaders.class);
+        uriInfo             = Mockito.mock(UriInfo.class);
+
+        headersMultiMap     = new MultivaluedHashMap<>();
+        queryParameters     = Mockito.spy(new MultivaluedHashMap<>());
+
+        headersMultiMap.add("X-FromAppId", "JUNIT");
+        headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
+        headersMultiMap.add("Real-Time", "true");
+        headersMultiMap.add("Accept", "application/json");
+        headersMultiMap.add("aai-request-context", "");
+
+        outputMediaTypes = new ArrayList<>();
+        outputMediaTypes.add(APPLICATION_JSON);
+
+        aaiRequestContextList = new ArrayList<>();
+        aaiRequestContextList.add("");
+
+        when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
+
+        when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
+
+        when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
+        when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
+
+        doReturn(null).when(queryParameters).remove(anyObject());
+        when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
+    }
+
+    public Response doPut(String uri, String payload) throws UnsupportedEncodingException, AAIException {
+
+        this.init();
+        Response response = null;
+        boolean success = true;
+        TransactionalGraphEngine dbEngine = null;
+
+        try {
+
+            uri = uri.replaceAll("/aai/", "");
+            logger.info("Starting the put request for the uri {} with payload {}", uri, payload);
+
+            String [] arr = uri.split("/");
+
+            Version version = null;
+
+            if(arr != null && arr.length > 1){
+                if(arr[0].matches("^v\\d+")){
+                    version = Version.valueOf(arr[0]);
+                    uri = uri.replaceAll("^v\\d+", "");
+                }
+            }
+
+            if(version == null){
+                version = Version.getLatest();
+            }
+            Mockito.when(uriInfo.getPath()).thenReturn(uri);
+
+            DBConnectionType type = DBConnectionType.REALTIME;
+            HttpEntry httpEntry   = new HttpEntry(version, ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+            Loader loader         = httpEntry.getLoader();
+            dbEngine              = httpEntry.getDbEngine();
+
+            URI uriObject = UriBuilder.fromPath(uri).build();
+            URIToObject uriToObject = new URIToObject(loader, uriObject);
+
+            String objType = uriToObject.getEntityName();
+            QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+
+            logger.info("Unmarshalling the payload to this {}", objType);
+
+            Introspector obj;
+            HttpMethod httpMethod;
+            if(uri.contains("/relationship-list/relationship")){
+                obj = loader.unmarshal("relationship", payload, org.onap.aai.restcore.MediaType.getEnum("application/json"));
+                httpMethod = HttpMethod.PUT_EDGE;
+            } else {
+                obj = loader.unmarshal(objType, payload, org.onap.aai.restcore.MediaType.getEnum("application/json"));
+                httpMethod = HttpMethod.PUT;
+                this.validateIntrospector(obj, loader, uriObject, httpMethod);
+            }
+
+
+            DBRequest dbRequest =
+                    new DBRequest.Builder(httpMethod, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                            .rawRequestContent(payload).build();
+
+            List<DBRequest> dbRequestList = new ArrayList<>();
+            dbRequestList.add(dbRequest);
+
+            Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+            response = responsesTuple.getValue1().get(0).getValue1();
+
+        } catch (AAIException e) {
+                       response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, e);
+                       success = false;
+               } catch(Exception e){
+            AAIException ex = new AAIException("AAI_4000", e);
+            response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, ex);
+            success = false;
+        } finally {
+            if(success){
+                if(response != null){
+                    if((response.getStatus() / 100) == 2){
+                        logger.info("Successfully completed the PUT request with status {} and committing it to DB", response.getStatus());
+                    } else {
+                        logFailure(HttpMethod.PUT, response);
+                    }
+                }
+                dbEngine.commit();
+            } else {
+                if(response != null) {
+                    logFailure(HttpMethod.PUT, response);
+                }
+                dbEngine.rollback();
+            }
+        }
+
+        return response;
+    }
+
+    public Response doGet(String uri) throws UnsupportedEncodingException, AAIException {
+
+        this.init();
+        Response response = null;
+        boolean success = true;
+        TransactionalGraphEngine dbEngine = null;
+
+        try {
+
+            uri = uri.replaceAll("/aai/", "");
+            logger.info("Starting the GET request for the uri {} with depth {}", uri, "all");
+
+            String [] arr = uri.split("/");
+
+            Version version = null;
+
+            if(arr != null && arr.length > 1){
+                if(arr[0].matches("^v\\d+")){
+                    version = Version.valueOf(arr[0]);
+                    uri = uri.replaceAll("^v\\d+", "");
+                }
+            }
+
+            if(version == null){
+                version = Version.getLatest();
+            }
+
+            DBConnectionType type = DBConnectionType.REALTIME;
+            HttpEntry httpEntry   = new HttpEntry(version, ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+            Loader loader         = httpEntry.getLoader();
+            dbEngine              = httpEntry.getDbEngine();
+
+            URI uriObject = UriBuilder.fromPath(uri).build();
+            URIToObject uriToObject = new URIToObject(loader, uriObject);
+
+            String objType = uriToObject.getEntityName();
+            queryParameters.add("depth", "all");
+            QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject, queryParameters);
+
+            Mockito.when(uriInfo.getPath()).thenReturn(uri);
+
+            logger.info("Unmarshalling the payload to this {}", objType);
+
+            Introspector obj = loader.introspectorFromName(objType);
+
+            DBRequest dbRequest =
+                    new DBRequest.Builder(HttpMethod.GET, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                            .build();
+
+            List<DBRequest> dbRequestList = new ArrayList<>();
+            dbRequestList.add(dbRequest);
+
+            Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+            response = responsesTuple.getValue1().get(0).getValue1();
+
+        } catch (AAIException e) {
+            response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, e);
+            success = false;
+        } catch(Exception e){
+            AAIException ex = new AAIException("AAI_4000", e);
+            response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, ex);
+            success = false;
+        } finally {
+            if(success){
+                if(response != null){
+                    if((response.getStatus() / 100) == 2){
+                        logger.info("Successfully completed the GET request with status {} and committing it to DB", response.getStatus());
+                    } else {
+                        logFailure(HttpMethod.GET, response);
+                    }
+                }
+                dbEngine.commit();
+            } else {
+                logFailure(HttpMethod.GET, response);
+                dbEngine.rollback();
+            }
+        }
+
+        return response;
+    }
+
+    public Response doDelete(String uri, String resourceVersion) throws UnsupportedEncodingException, AAIException {
+
+        this.init();
+        Response response = null;
+        boolean success = true;
+        TransactionalGraphEngine dbEngine = null;
+
+        try {
+
+            uri = uri.replaceAll("/aai/", "");
+            logger.info("Starting the delete request for the uri {} with resource version {}", uri, resourceVersion);
+
+            String [] arr = uri.split("/");
+
+            Version version = null;
+
+            if(arr != null && arr.length > 1){
+                if(arr[0].matches("^v\\d+")){
+                    version = Version.valueOf(arr[0]);
+                    if(!uri.contains("relationship-list/relationship")){
+                        uri = uri.replaceAll("^v\\d+", "");
+                    }
+                }
+            }
+
+            if(version == null){
+                version = Version.getLatest();
+            }
+
+            Mockito.when(uriInfo.getPath()).thenReturn(uri);
+            DBConnectionType type = DBConnectionType.REALTIME;
+            HttpEntry httpEntry   = new HttpEntry(version, ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+            Loader loader         = httpEntry.getLoader();
+            dbEngine              = httpEntry.getDbEngine();
+
+            URI uriObject = UriBuilder.fromPath(uri).build();
+            URIToObject uriToObject = new URIToObject(loader, uriObject);
+
+            String objType = uriToObject.getEntityName();
+            queryParameters.add("resource-version", resourceVersion);
+            QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject, queryParameters);
+
+            logger.info("Unmarshalling the payload to this {}", objType);
+
+            Introspector obj;
+            HttpMethod httpMethod;
+            if(uri.contains("/relationship-list/relationship")){
+                obj = loader.introspectorFromName("relationship");
+                httpMethod = HttpMethod.DELETE_EDGE;
+            } else {
+                obj = loader.introspectorFromName(objType);
+                httpMethod = HttpMethod.DELETE;
+            }
+
+            DBRequest dbRequest =
+                    new DBRequest.Builder(httpMethod, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                            .build();
+
+            List<DBRequest> dbRequestList = new ArrayList<>();
+            dbRequestList.add(dbRequest);
+
+            Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+            response = responsesTuple.getValue1().get(0).getValue1();
+
+        } catch (AAIException e) {
+            response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, e);
+            success = false;
+        } catch(Exception e){
+            AAIException ex = new AAIException("AAI_4000", e);
+            response = this.consumerExceptionResponseGenerator(httpHeaders, uriInfo, HttpMethod.PUT, ex);
+            success = false;
+        } finally {
+            if(success){
+                if(response != null){
+                    if((response.getStatus() / 100) == 2){
+                        logger.info("Successfully completed the DELETE request with status {} and committing it to DB", response.getStatus());
+                    } else {
+                        logFailure(HttpMethod.DELETE, response);
+                    }
+                }
+                dbEngine.commit();
+            } else {
+                logFailure(HttpMethod.DELETE, response);
+                dbEngine.rollback();
+            }
+        }
+
+        return response;
+    }
+
+    public static void logFailure(HttpMethod httpMethod, Response response){
+        logger.info("Unable to complete the {} request with status {} and rolling back", httpMethod.toString(), response.getStatus());
+        logger.info("Response body of failed request {}", response.getEntity());
+
+    }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/PayloadUtil.java b/aai-core/src/test/java/org/onap/aai/PayloadUtil.java
new file mode 100644 (file)
index 0000000..43fd290
--- /dev/null
@@ -0,0 +1,100 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.junit.Assert.assertNotNull;
+
+public class PayloadUtil {
+
+    private static final Map<String, String> cache = new HashMap<>();
+    private static final Pattern TEMPLATE_PATTERN = Pattern.compile("\\$\\{[^}]+\\}");
+
+    public static String getExpectedPayload(String fileName) throws IOException {
+
+        InputStream inputStream = PayloadUtil.class.getClassLoader().getResourceAsStream("payloads/expected/" + fileName);
+
+        String message = String.format("Unable to find the %s in src/test/resources", fileName);
+        assertNotNull(message, inputStream);
+
+        String resource = IOUtils.toString(inputStream);
+
+        inputStream.close();
+        return resource;
+    }
+
+    public static String getResourcePayload(String fileName) throws IOException {
+
+        InputStream inputStream = PayloadUtil.class.getClassLoader().getResourceAsStream("payloads/resource/" + fileName);
+
+        String message = String.format("Unable to find the %s in src/test/resources", fileName);
+        assertNotNull(message, inputStream);
+
+        String resource = IOUtils.toString(inputStream);
+
+        inputStream.close();
+        return resource;
+    }
+
+    public static String getTemplatePayload(String fileName, Map<String, String> templateValueMap) throws Exception {
+
+        InputStream inputStream = PayloadUtil.class.getClassLoader().getResourceAsStream("payloads/templates/" + fileName);
+
+        String message = String.format("Unable to find the %s in src/test/resources", fileName);
+        assertNotNull(message, inputStream);
+
+        String resource;
+
+        if(cache.containsKey(fileName)){
+            resource = cache.get(fileName);
+        } else {
+            resource = IOUtils.toString(inputStream);
+            cache.put(fileName, resource);
+        }
+
+        Matcher matcher = TEMPLATE_PATTERN.matcher(resource);
+
+        String resourceWithTemplateValues = resource;
+
+        while(matcher.find()){
+            int start = matcher.start() + 2;
+            int end = matcher.end() - 1;
+            String key = resource.substring(start, end);
+            if(templateValueMap.containsKey(key)){
+                resourceWithTemplateValues = resourceWithTemplateValues.replaceAll("\\$\\{" + key +"\\}", templateValueMap.get(key));
+            } else {
+                throw new RuntimeException("Unable to find the key value pair in map for the template processing for key " + key);
+            }
+        }
+
+        inputStream.close();
+        return resourceWithTemplateValues;
+    }
+}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/PserverTest.java b/aai-core/src/test/java/org/onap/aai/rest/PserverTest.java
new file mode 100644 (file)
index 0000000..843d993
--- /dev/null
@@ -0,0 +1,136 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import com.jayway.jsonpath.JsonPath;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.AAIJunitRunner;
+import org.onap.aai.HttpTestUtil;
+import org.onap.aai.PayloadUtil;
+import org.onap.aai.introspection.*;
+import org.skyscreamer.jsonassert.JSONAssert;
+
+import javax.ws.rs.core.Response;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(AAIJunitRunner.class)
+public class PserverTest {
+
+    private static EELFLogger logger = EELFManager.getInstance().getLogger(PserverTest.class);
+    private HttpTestUtil httpTestUtil;
+    private Map<String, String> relationshipMap;
+
+    @Before
+    public void setup(){
+        httpTestUtil = new HttpTestUtil();
+        relationshipMap = new HashMap<>();
+    }
+
+    @Test
+    public void testPutPServerCreateGetAndDeleteAndCreateRelationshipBetweenPserverAndCloudRegion() throws Exception {
+
+        logger.info("Starting the pserver testPutServerCreateGetAndDelete");
+
+        String pserverUri = "/aai/v12/cloud-infrastructure/pservers/pserver/test-pserver";
+        String cloudRegionUri = "/aai/v12/cloud-infrastructure/cloud-regions/cloud-region/test1/test2";
+        String cloudRegionRelationshipUri = cloudRegionUri + "/relationship-list/relationship";
+
+        Response response = httpTestUtil.doGet(pserverUri);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the pserver to be not found", 404, response.getStatus());
+        logger.info("Verifying that the pserver is already not in the database successfully");
+
+        Map<String, String> templateValueMap = new HashMap<>();
+        templateValueMap.put("hostname", "test-pserver");
+        String pserverPayload = PayloadUtil.getTemplatePayload("pserver.json", templateValueMap);
+
+        response = httpTestUtil.doPut(pserverUri, pserverPayload);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the pserver to be created", 201, response.getStatus());
+        logger.info("Successfully created the pserver into db");
+
+        response = httpTestUtil.doGet(pserverUri);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the pserver to be found", 200, response.getStatus());
+
+        JSONAssert.assertEquals(pserverPayload, response.getEntity().toString(), false);
+        logger.info("Successfully retrieved the created pserver from db and verified with put data");
+
+        response = httpTestUtil.doPut(cloudRegionUri, "{}");
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expect the cloud region to be created", 201, response.getStatus());
+        logger.info("Successfully able to create the cloud region with payload that has no keys to be retrieved from uri");
+
+        response = httpTestUtil.doGet(cloudRegionUri);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the cloud region to be found", 200, response.getStatus());
+        logger.info("Successfully retrieved the cloud region from db");
+
+        relationshipMap.put("related-to", "pserver");
+        relationshipMap.put("related-link", pserverUri);
+
+        String pserverRelationshipPayload = PayloadUtil.getTemplatePayload("relationship.json", relationshipMap);
+        // Creates the relationship between cloud region and pserver
+        response = httpTestUtil.doPut(cloudRegionRelationshipUri, pserverRelationshipPayload);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expect the cloud region relationship to pserver to be created", 200, response.getStatus());
+        logger.info("Successfully created the relationship between cloud region and pserver");
+
+        response =  httpTestUtil.doGet(cloudRegionUri);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expect the cloud region to be created", 200, response.getStatus());
+        logger.info("Successfully retrieved the cloud region from db");
+
+        Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.getLatest());
+        Introspector in = loader.unmarshal("cloud-region", response.getEntity().toString());
+
+        System.out.println(in.marshal(true));
+        String resourceVersion = JsonPath.read(response.getEntity().toString(), "$.resource-version");
+
+        response = httpTestUtil.doDelete(cloudRegionUri, resourceVersion);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the cloud region to be deleted", 204, response.getStatus());
+        logger.info("Successfully deleted the cloud region from db");
+
+        response = httpTestUtil.doGet(pserverUri);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the pserver to be not found", 200, response.getStatus());
+        resourceVersion = JsonPath.read(response.getEntity().toString(), "$.resource-version");
+        logger.info("Successfully retrieved the cloud region from db to get the latest resource version");
+
+        response = httpTestUtil.doDelete(pserverUri, resourceVersion);
+        assertNotNull("Expected the response to be not null", response);
+        assertEquals("Expecting the cloud region to be deleted", 204, response.getStatus());
+        logger.info("Successfully deleted the pserver from db");
+
+        logger.info("Ending the pserver testPutServerCreateGetAndDelete");
+    }
+
+}
diff --git a/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java b/aai-core/src/test/java/org/onap/aai/rest/db/HttpEntryTest.java
new file mode 100644 (file)
index 0000000..f643fc4
--- /dev/null
@@ -0,0 +1,298 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ *
+ * ECOMP is a trademark and service mark of AT&T Intellectual Property.
+ */
+package org.onap.aai.rest.db;
+
+import org.javatuples.Pair;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.runners.MethodSorters;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.aai.AAISetup;
+import org.onap.aai.dbmap.DBConnectionType;
+import org.onap.aai.domain.yang.Pserver;
+import org.onap.aai.domain.yang.Pservers;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.*;
+import org.onap.aai.parsers.query.QueryParser;
+import org.onap.aai.restcore.HttpMethod;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+import javax.ws.rs.core.*;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Mockito.when;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class HttpEntryTest extends AAISetup {
+
+    protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json");
+
+    private static final Set<Integer> VALID_HTTP_STATUS_CODES = new HashSet<>();
+
+    static {
+        VALID_HTTP_STATUS_CODES.add(200);
+        VALID_HTTP_STATUS_CODES.add(201);
+        VALID_HTTP_STATUS_CODES.add(204);
+    }
+
+    private HttpHeaders httpHeaders;
+
+    private UriInfo uriInfo;
+
+    private MultivaluedMap<String, String> headersMultiMap;
+    private MultivaluedMap<String, String> queryParameters;
+
+    private List<String> aaiRequestContextList;
+
+    private List<MediaType> outputMediaTypes;
+
+    @Before
+    public void setup(){
+
+        httpHeaders         = Mockito.mock(HttpHeaders.class);
+        uriInfo             = Mockito.mock(UriInfo.class);
+
+        headersMultiMap     = new MultivaluedHashMap<>();
+        queryParameters     = Mockito.spy(new MultivaluedHashMap<>());
+
+        headersMultiMap.add("X-FromAppId", "JUNIT");
+        headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString());
+        headersMultiMap.add("Real-Time", "true");
+        headersMultiMap.add("Accept", "application/json");
+        headersMultiMap.add("aai-request-context", "");
+
+        outputMediaTypes = new ArrayList<>();
+        outputMediaTypes.add(APPLICATION_JSON);
+
+        aaiRequestContextList = new ArrayList<>();
+        aaiRequestContextList.add("");
+
+        when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes);
+        when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap);
+
+        when(httpHeaders.getRequestHeader("aai-request-context")).thenReturn(aaiRequestContextList);
+
+
+        when(uriInfo.getQueryParameters()).thenReturn(queryParameters);
+        when(uriInfo.getQueryParameters(false)).thenReturn(queryParameters);
+
+        // TODO - Check if this is valid since RemoveDME2QueryParameters seems to be very unreasonable
+        Mockito.doReturn(null).when(queryParameters).remove(anyObject());
+
+        when(httpHeaders.getMediaType()).thenReturn(APPLICATION_JSON);
+    }
+
+    
+    @Test
+    public void test1PutOnPserver() throws UnsupportedEncodingException, AAIException {
+
+        DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test1").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "{\"hostname\":\"junit-test1\"}";
+
+        Introspector obj = loader.unmarshal("pserver", content, org.onap.aai.restcore.MediaType.getEnum("application/json"));
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.PUT, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+        assertEquals("Expected the pserver to be created", 201, response.getStatus());
+    }
+
+    @Test
+    public void test2GetOnPserver() throws UnsupportedEncodingException, AAIException {
+
+        DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test1").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "";
+
+        Introspector obj = loader.introspectorFromName("pserver");
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.GET, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+        assertEquals("Expected the pserver to be returned", 200, response.getStatus());
+    }
+  
+    @Test
+    public void test3MergePatchOnPserver() throws UnsupportedEncodingException, AAIException {
+
+        DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test1").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "{\"hostname\":\"junit-test1\", \"equip-type\":\"junit-equip-type\"}";
+
+        Introspector obj = loader.unmarshal("pserver", content, org.onap.aai.restcore.MediaType.getEnum("application/json"));
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.MERGE_PATCH, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+        assertEquals("Expected the pserver to be updated", 200, response.getStatus());
+    }
+    
+    private int doDelete(String resourceVersion) throws UnsupportedEncodingException, AAIException {
+       queryParameters.add("resource-version", resourceVersion);
+       DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test1").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "";
+
+        Introspector obj = loader.introspectorFromName("pserver");
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.DELETE, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+        return response.getStatus();
+    }
+    
+    @Test
+    public void test4DeleteOnPserver() throws UnsupportedEncodingException, AAIException {
+
+        DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test1").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "";
+
+        Introspector obj = loader.introspectorFromName("pserver");
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.GET, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+        String msg = response.getEntity().toString();
+        JsonObject jsonObj = new JsonParser().parse(msg).getAsJsonObject();
+        String resourceVersion = "";
+        if ( jsonObj.isJsonObject()) {
+               resourceVersion = jsonObj.get("resource-version").getAsString();
+        }
+        assertEquals("Expected the pserver to be deleted", 204, doDelete(resourceVersion));
+    }
+
+    @Test
+    public void test5FailedGetOnPserver() throws UnsupportedEncodingException, AAIException {
+
+        DBConnectionType type = DBConnectionType.REALTIME;
+        HttpEntry httpEntry = new HttpEntry(Version.getLatest(), ModelType.MOXY, QueryStyle.TRAVERSAL, type);
+        Loader loader = httpEntry.getLoader();
+        TransactionalGraphEngine dbEngine = httpEntry.getDbEngine();
+
+        URI uriObject = UriBuilder.fromPath("/cloud-infrastructure/pservers/pserver/junit-test2").build();
+
+        QueryParser uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(uriObject);
+
+        String content = "";
+
+        Introspector obj = loader.introspectorFromName("pserver");
+
+        DBRequest dbRequest =
+                new DBRequest.Builder(HttpMethod.GET, uriObject, uriQuery, obj, httpHeaders, uriInfo, "JUNIT-TRANSACTION")
+                        .rawRequestContent(content).build();
+
+        List<DBRequest> dbRequestList = new ArrayList<>();
+        dbRequestList.add(dbRequest);
+
+        Pair<Boolean, List<Pair<URI, Response>>> responsesTuple  = httpEntry.process(dbRequestList, "JUNIT");
+        Response response = responsesTuple.getValue1().get(0).getValue1();
+        dbEngine.commit();
+
+        assertEquals("Expected the pserver to be deleted", 404, response.getStatus());
+    }
+}
index 4d46c02..5fade2e 100644 (file)
@@ -38,6 +38,7 @@ import java.util.List;
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
 import org.apache.tinkerpop.gremlin.structure.Edge;
 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.junit.After;
@@ -319,11 +320,11 @@ public class DbSerializerTest extends AAISetup {
                rules.addTreeEdge(engine.tx().traversal(), cr, ten);
                rules.addTreeEdge(engine.tx().traversal(), ten, vs);
 
-               List<Vertex> vertices = new ArrayList<Vertex>(Arrays.asList(cr, ten, vs));
+               List<Vertex> vertices = Arrays.asList(cr, ten, vs);
                Introspector crIn = dbser.getVertexProperties(cr);
                Introspector tenIn = dbser.getVertexProperties(ten);
                Introspector vsIn = dbser.getVertexProperties(vs);
-               List<Introspector> intros = new ArrayList<Introspector>(Arrays.asList(crIn, tenIn, vsIn));
+               List<Introspector> intros = Arrays.asList(crIn, tenIn, vsIn);
 
                dbser.setCachedURIs(vertices, intros);
 
@@ -1009,4 +1010,135 @@ public class DbSerializerTest extends AAISetup {
                return localDbser;
        }
 
+       @Test
+       public void addRelatedToPropertyTest() throws AAIException {
+               Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.v11);
+               Introspector gv = loader.introspectorFromName("generic-vnf");
+               gv.setValue("vnf-name", "myname");
+               Introspector rel = loader.introspectorFromName("relationship");
+               DBSerializer dbser = new DBSerializer(Version.v11, dbEngine, 
+                                                                                               ModelType.MOXY, "AAI-TEST");
+               
+               dbser.addRelatedToProperty(rel, gv);
+               List<Introspector> relToProps = rel.getWrappedListValue("related-to-property");
+               assertTrue(relToProps.size() == 1);
+               Introspector relToProp = relToProps.get(0);
+               assertTrue("generic-vnf.vnf-name".equals(relToProp.getValue("property-key")));
+               assertTrue("myname".equals(relToProp.getValue("property-value")));
+       }
+       
+       @Test
+       public void dbToObjectContainerMismatchTest() throws AAIException, UnsupportedEncodingException {
+               DBSerializer dbser = new DBSerializer(Version.v11, dbEngine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               Graph vertexMaker = TinkerGraph.open();
+               Vertex a = vertexMaker.addVertex(T.id, "0");
+               Vertex b = vertexMaker.addVertex(T.id, "1");
+               List<Vertex> vertices = Arrays.asList(a,b);
+               
+               Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.v11);
+               Introspector intro = loader.introspectorFromName("image"); //just need any non-container object
+               
+               thrown.expect(AAIException.class);
+               thrown.expectMessage("query object mismatch: this object cannot hold multiple items.");
+               
+               dbser.dbToObject(vertices, intro, Integer.MAX_VALUE, true, "doesn't matter");
+       }
+       
+       @Test
+       public void dbToObjectTest() throws AAIException, UnsupportedEncodingException {
+               engine.startTransaction();
+               
+               DBSerializer dbser = new DBSerializer(Version.getLatest(), engine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               Vertex gv1 = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "id1");
+               Vertex gv2 = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "id2");
+               List<Vertex> vertices = Arrays.asList(gv1, gv2);
+               
+               Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.getLatest());
+               Introspector gvContainer = loader.introspectorFromName("generic-vnfs");
+               
+               Introspector res = dbser.dbToObject(vertices, gvContainer, 0, true, "true");
+               List<Introspector> gvs = res.getWrappedListValue("generic-vnf");
+               assertTrue(gvs.size() == 2);
+               for (Introspector i : gvs) {
+                       String vnfId = i.getValue("vnf-id");
+                       assertTrue("id1".equals(vnfId) || "id2".equals(vnfId));
+               }
+               
+               engine.rollback();
+       }
+       
+       @Test
+       public void getEdgeBetweenNoLabelTest() throws AAIException {
+               DBSerializer dbser = new DBSerializer(Version.getLatest(), engine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               engine.startTransaction();
+               Vertex gv = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "id1");
+               Vertex lint = engine.tx().addVertex("aai-node-type", "l-interface", "interface-name", "name1");
+               rules.addTreeEdge(engine.tx().traversal(), gv, lint);
+               
+               Edge res = dbser.getEdgeBetween(EdgeType.TREE, gv, lint);
+               assertTrue("hasLInterface".equals(res.label()));
+               engine.rollback();
+       }
+
+       @Test
+       public void deleteItemsWithTraversal() throws AAIException {
+               DBSerializer dbser = new DBSerializer(Version.getLatest(), engine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               engine.startTransaction();
+               Vertex gv = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "id1");
+               Vertex lint = engine.tx().addVertex("aai-node-type", "l-interface", "interface-name", "name1");
+               
+               assertTrue(engine.tx().traversal().V().has("vnf-id", "id1").hasNext());
+               assertTrue(engine.tx().traversal().V().has("interface-name", "name1").hasNext());
+               
+               dbser.deleteItemsWithTraversal(Arrays.asList(gv, lint));
+               
+               assertTrue(!engine.tx().traversal().V().has("vnf-id", "id1").hasNext());
+               assertTrue(!engine.tx().traversal().V().has("interface-name", "name1").hasNext());
+               
+               engine.rollback();
+       }
+       
+       @Test
+       public void serializeToDbWithParentTest() throws AAIException, UnsupportedEncodingException, URISyntaxException {
+               DBSerializer dbser = new DBSerializer(Version.getLatest(), engine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               engine.startTransaction();
+               Vertex gv = engine.tx().addVertex("aai-node-type", "generic-vnf", "vnf-id", "id1");
+               Vertex lint = engine.tx().addVertex("aai-node-type", "l-interface", "interface-name", "name1");
+               rules.addTreeEdge(engine.tx().traversal(), gv, lint);
+               
+               Introspector lintIntro = loader.introspectorFromName("l-interface");
+               lintIntro.setValue("interface-role", "actor");
+               URI lintURI = new URI("/network/generic-vnfs/generic-vnf/id1/l-interfaces/l-interface/name1");
+               QueryParser uriQuery = dbEngine.getQueryBuilder(gv).createQueryFromURI(lintURI);
+               dbser.serializeToDb(lintIntro, lint, uriQuery, "test-identifier", "AAI-TEST");
+               
+               assertTrue(engine.tx().traversal().V(lint).has("interface-role", "actor").hasNext());
+               
+               engine.rollback();
+       }
+       
+       @Test
+       public void getLatestVersionViewTest() throws AAIException, UnsupportedEncodingException {
+               DBSerializer dbser = new DBSerializer(Version.getLatest(), engine, 
+                               ModelType.MOXY, "AAI-TEST");
+               
+               engine.startTransaction();
+               Vertex phys = engine.tx().addVertex("aai-node-type", "physical-link", "link-name", "zaldo", 
+                                                                                               "speed-value", "very-fast", "service-provider-bandwidth-up-units", "things");
+               
+               Introspector res = dbser.getLatestVersionView(phys);
+               assertTrue("zaldo".equals(res.getValue("link-name")));
+               assertTrue("very-fast".equals(res.getValue("speed-value")));
+               assertTrue("things".equals(res.getValue("service-provider-bandwidth-up-units")));
+       }
 }
\ No newline at end of file
index 4e3b7d0..4b4a0e6 100644 (file)
@@ -26,18 +26,156 @@ import static org.junit.Assert.*;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.step.util.Tree;
+import org.apache.tinkerpop.gremlin.structure.Direction;
+import org.apache.tinkerpop.gremlin.structure.Edge;
+import org.apache.tinkerpop.gremlin.structure.Element;
 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.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex;
 import org.junit.Test;
+import org.onap.aai.AAISetup;
 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.introspection.Version;
 import org.onap.aai.serialization.db.EdgeRules;
 
-public class GraphTraversalQueryEngineTest {
+public class GraphTraversalQueryEngineTest extends AAISetup {
+       
+       @Test
+       public void testFindParents() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex cloudreg = graph.addVertex(T.id, "00", "aai-node-type", "cloud-region");
+               Vertex tenant = graph.addVertex(T.id, "10", "aai-node-type", "tenant");
+               Vertex vserver = graph.addVertex(T.id, "20", "aai-node-type", "vserver");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, cloudreg, tenant);
+               rules.addTreeEdge(g, tenant, vserver);
+               
+               //expect start vertex back plus any parents
+               List<Vertex> crExpected = new ArrayList<>(Arrays.asList(cloudreg)); //no parents
+               List<Vertex> tenExpected = new ArrayList<>(Arrays.asList(tenant, cloudreg)); //only has the immediate parent
+               List<Vertex> vsExpected = new ArrayList<>(Arrays.asList(vserver, tenant, cloudreg)); //parent & grandparent
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               List<Vertex> crRes = engine.findParents(cloudreg);
+               assertTrue(crRes.containsAll(crExpected) && crExpected.containsAll(crRes));
+               
+               List<Vertex> tenRes = engine.findParents(tenant);
+               assertTrue(tenRes.containsAll(tenExpected) && tenExpected.containsAll(tenRes));
+               
+               List<Vertex> vsRes = engine.findParents(vserver);
+               assertTrue(vsRes.containsAll(vsExpected) && vsExpected.containsAll(vsRes));
+               //verify expected ordering - start, parent, grandparent
+               assertTrue(vsRes.get(0).equals(vserver));
+               assertTrue(vsRes.get(1).equals(tenant));
+               assertTrue(vsRes.get(2).equals(cloudreg));
+       }
+       
+       @Test
+       public void testFindAllChildren() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex cloudreg = graph.addVertex(T.id, "00", "aai-node-type", "cloud-region");
+               Vertex tenant = graph.addVertex(T.id, "10", "aai-node-type", "tenant");
+               Vertex vserver = graph.addVertex(T.id, "20", "aai-node-type", "vserver");
+               Vertex vserver2 = graph.addVertex(T.id, "21", "aai-node-type", "vserver");
+               Vertex oam = graph.addVertex(T.id, "30", "aai-node-type", "oam-network");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, cloudreg, tenant);
+               rules.addTreeEdge(g, tenant, vserver);
+               rules.addTreeEdge(g, tenant, vserver2);
+               rules.addTreeEdge(g, cloudreg, oam);
+               
+               List<Vertex> crExpected = new ArrayList<>(Arrays.asList(cloudreg, tenant, vserver, vserver2, oam));
+               List<Vertex> vsExpected = new ArrayList<>(Arrays.asList(vserver));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               List<Vertex> crRes = engine.findAllChildren(cloudreg);
+               assertTrue(crRes.containsAll(crExpected) && crExpected.containsAll(crRes));
+               
+               List<Vertex> vsRes = engine.findAllChildren(vserver);
+               assertTrue(vsRes.containsAll(vsExpected) && vsExpected.containsAll(vsRes));
+       }
+       
+       @Test
+       public void testFindChildrenOfType() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex gv = graph.addVertex(T.id, "00", "aai-node-type", "generic-vnf");
+               Vertex lint1 = graph.addVertex(T.id, "10", "aai-node-type", "l-interface");
+               Vertex lint2 = graph.addVertex(T.id, "11", "aai-node-type", "l-interface");
+               Vertex lag = graph.addVertex(T.id, "20", "aai-node-type", "lag-interface");
+               Vertex lint3 = graph.addVertex(T.id, "12", "aai-node-type", "l-interface");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, gv, lint1);
+               rules.addTreeEdge(g, gv, lint2);
+               rules.addTreeEdge(g, gv, lag);
+               rules.addTreeEdge(g, lag, lint3);
+               
+               List<Vertex> expected = new ArrayList<>(Arrays.asList(lint1, lint2));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               List<Vertex> results = engine.findChildrenOfType(gv, "l-interface");
+               assertTrue(results.containsAll(expected) && expected.containsAll(results));
+       }
+       
+       @Test
+       public void testFindChildren() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex gv = graph.addVertex(T.id, "00", "aai-node-type", "generic-vnf");
+               Vertex lint1 = graph.addVertex(T.id, "10", "aai-node-type", "l-interface");
+               Vertex lint2 = graph.addVertex(T.id, "11", "aai-node-type", "l-interface");
+               Vertex lag = graph.addVertex(T.id, "20", "aai-node-type", "lag-interface");
+               Vertex lint3 = graph.addVertex(T.id, "12", "aai-node-type", "l-interface");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, gv, lint1);
+               rules.addTreeEdge(g, gv, lint2);
+               rules.addTreeEdge(g, gv, lag);
+               rules.addTreeEdge(g, lag, lint3);
+               
+               List<Vertex> expected = new ArrayList<>(Arrays.asList(lint1, lint2, lag));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               List<Vertex> results = engine.findChildren(gv);
+               assertTrue(results.containsAll(expected) && expected.containsAll(results));
+       }
 
        @Test
        public void testFindDeletable() throws AAIException {
@@ -72,4 +210,172 @@ public class GraphTraversalQueryEngineTest {
                List<Vertex> cousinDeletes = engine.findDeletable(cousin);
                assertTrue(cousinExpected.containsAll(cousinDeletes) && cousinDeletes.containsAll(cousinExpected));
        }
+       
+       @Test
+       public void testFindRelatedVertices() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               
+               Graph graph = TinkerGraph.open();
+               
+               Vertex gv = graph.addVertex(T.id, "00", "aai-node-type", "generic-vnf");
+               Vertex lint = graph.addVertex(T.id, "10", "aai-node-type", "l-interface");
+               Vertex lint2 = graph.addVertex(T.id, "11", "aai-node-type", "l-interface");
+               Vertex log = graph.addVertex(T.id, "20", "aai-node-type", "logical-link");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, gv, lint);
+               rules.addEdge(g, lint, log);
+               rules.addEdge(g, log, lint2);
+               
+               List<Vertex> outExpected = new ArrayList<>(Arrays.asList(lint));
+               List<Vertex> inExpected = new ArrayList<>(Arrays.asList(lint, lint2));
+               List<Vertex> bothExpected = new ArrayList<>(Arrays.asList(log));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+                       
+               //test
+               List<Vertex> outRes = engine.findRelatedVertices(gv, Direction.OUT, "hasLInterface", "l-interface");
+               assertTrue(outRes.containsAll(outExpected) && outExpected.containsAll(outRes));
+               
+               List<Vertex> inRes = engine.findRelatedVertices(log, Direction.IN, "usesLogicalLink", "l-interface");
+               assertTrue(inRes.containsAll(inExpected) && inExpected.containsAll(inRes));
+               
+               List<Vertex> bothRes = engine.findRelatedVertices(lint, Direction.BOTH, "usesLogicalLink", "logical-link");
+               assertTrue(bothRes.containsAll(bothExpected) && bothExpected.containsAll(bothRes));
+       }
+       
+       @Test
+       public void testFindSubGraph() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex cr = graph.addVertex(T.id, "00", "aai-node-type", "cloud-region");
+               Vertex ten = graph.addVertex(T.id, "10", "aai-node-type", "tenant");
+               Vertex ten2 = graph.addVertex(T.id, "11", "aai-node-type", "tenant");
+               Vertex vs = graph.addVertex(T.id, "20", "aai-node-type", "vserver");
+               Vertex vs2 = graph.addVertex(T.id, "21", "aai-node-type", "vserver");
+               Vertex lint = graph.addVertex(T.id, "30", "aai-node-type", "l-interface");
+               Vertex comp = graph.addVertex(T.id, "40", "aai-node-type", "complex");
+               Vertex ctag = graph.addVertex(T.id, "50", "aai-node-type", "ctag-pool");
+               Vertex gv = graph.addVertex(T.id, "60", "aai-node-type", "generic-vnf");
+               Vertex lag = graph.addVertex(T.id, "70", "aai-node-type", "lag-interface");
+               Vertex lint2 = graph.addVertex(T.id, "31", "aai-node-type", "l-interface");
+               Vertex log = graph.addVertex(T.id, "80", "aai-node-type", "logical-link");
+               Vertex vnfc = graph.addVertex(T.id, "90", "aai-node-type", "vnfc");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               Edge crTen = rules.addTreeEdge(g, cr, ten);
+               Edge crTen2 = rules.addTreeEdge(g, cr, ten2);
+               Edge tenVs = rules.addTreeEdge(g, ten, vs);
+               Edge tenVs2 = rules.addTreeEdge(g, ten, vs2);
+               Edge vsLInt = rules.addTreeEdge(g, vs, lint);
+               Edge lintLog = rules.addEdge(g, lint, log);
+               Edge vsGv = rules.addEdge(g, vs, gv);
+               rules.addEdge(g, gv, vnfc);
+               
+               rules.addTreeEdge(g, gv, lag);
+               rules.addTreeEdge(g, lag, lint2);
+               
+               rules.addTreeEdge(g, comp, ctag);
+               Edge crComp = rules.addEdge(g, cr, comp);
+               
+               //findSubGraph(cr, 0, true)
+               List<Element> expected1 = new ArrayList<>(Arrays.asList(cr));
+               //findSubGraph(cr, 2, true)
+               List<Element> expected2 = new ArrayList<>(Arrays.asList(cr, ten, ten2, vs, vs2,
+                                                                                                                                       crTen, crTen2, tenVs, tenVs2));
+               //findSubGraph(cr)
+               List<Element> expected3 = new ArrayList<>(Arrays.asList(cr, ten, ten2, comp, vs, vs2, lint, gv, log,
+                                                                                                                               crTen, crTen2, crComp, tenVs, tenVs2, vsLInt, 
+                                                                                                                               vsGv, lintLog));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               Tree<Element> res1 = engine.findSubGraph(cr, 0, true);
+               Set<Element> resList1 = treeToList(res1);
+               assertTrue(resList1.containsAll(expected1) && expected1.containsAll(resList1));
+               
+               Tree<Element> res2 = engine.findSubGraph(cr, 2, true);
+               Set<Element> resList2 = treeToList(res2);
+               assertTrue(resList2.containsAll(expected2) && expected2.containsAll(resList2));
+               
+               Tree<Element> res3 = engine.findSubGraph(cr);
+               Set<Element> resList3 = treeToList(res3);
+               assertTrue(resList3.containsAll(expected3) && expected3.containsAll(resList3));
+       }
+       
+       /**
+        * convenience helper method to make it easier to check the contents of the tree against 
+        * a list of expected results
+        * @param tree - the tree whose contents you want in collection form
+        * @return set of the contents of the tree
+        */
+       private Set<Element> treeToList(Tree<Element> tree) {
+               Set<Element> ret = new HashSet<>();
+               
+               for (Element key : tree.keySet()) {
+                       ret.add(key);
+                       ret.addAll(treeToList(tree.get(key)));
+               }
+               
+               return ret;
+       }
+       
+       @Test
+       public void testFindEdgesForVersion() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex gv = graph.addVertex(T.id, "00", "aai-node-type", "generic-vnf");
+               Vertex vnfc = graph.addVertex(T.id, "10", "aai-node-type", "vnfc");
+               Vertex lob = graph.addVertex(T.id, "20", "aai-node-type", "line-of-business");
+               Vertex lint = graph.addVertex(T.id, "30", "aai-node-type", "l-interface");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, gv, lint); //tree edge so shouldn't appear in results
+               Edge gvVnfc = rules.addEdge(g, gv, vnfc);
+               rules.addEdge(g, gv, lob); //v11/12 not v10
+               
+               List<Edge> expected = new ArrayList<>(Arrays.asList(gvVnfc));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, Version.v10);
+               List<Edge> results = engine.findEdgesForVersion(gv, loader);
+               assertTrue(results.containsAll(expected) && expected.containsAll(results));
+       }
+       
+       @Test
+       public void testFindCousinVertices() throws AAIException {
+               //setup
+               EdgeRules rules = EdgeRules.getInstance();
+               Graph graph = TinkerGraph.open();
+               
+               Vertex gv = graph.addVertex(T.id, "00", "aai-node-type", "generic-vnf");
+               Vertex vnfc = graph.addVertex(T.id, "10", "aai-node-type", "vnfc");
+               Vertex lob = graph.addVertex(T.id, "20", "aai-node-type", "line-of-business");
+               Vertex lint = graph.addVertex(T.id, "30", "aai-node-type", "l-interface");
+               
+               GraphTraversalSource g = graph.traversal();
+               
+               rules.addTreeEdge(g, gv, lint); //tree edge so shouldn't appear in results
+               rules.addEdge(g, gv, vnfc);
+               rules.addEdge(g, gv, lob); 
+               
+               List<Vertex> expected = new ArrayList<>(Arrays.asList(vnfc, lob));
+               
+               GraphTraversalQueryEngine engine = new GraphTraversalQueryEngine(g);
+               
+               //test
+               List<Vertex> results = engine.findCousinVertices(gv);
+               assertTrue(results.containsAll(expected) && expected.containsAll(results));
+       }
 }
index 3da0247..c91976f 100644 (file)
@@ -25,3 +25,8 @@ aai.resourceversion.enableflag=true
 aai.logging.maxStackTraceEntries=10
 aai.default.api.version=v9
 
+aai.server.rebind=g
+aai.run.migrations=false
+ecm.auth.password.x=OBF:1igd1i9a1jnb1yte1vv11vu91yt81jk71i6o1idt
+
+aai.jms.enable=false
diff --git a/aai-core/src/test/resources/payloads/templates/pserver.json b/aai-core/src/test/resources/payloads/templates/pserver.json
new file mode 100644 (file)
index 0000000..c1c261a
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "hostname": "${hostname}",
+  "ptnii-equip-name": "example-ptnii-equip-name-val-36969",
+  "number-of-cpus": 62220,
+  "disk-in-gigabytes": 872,
+  "ram-in-megabytes": 35331,
+  "equip-type": "example-equip-type-val-22986",
+  "equip-vendor": "example-equip-vendor-val-37452",
+  "equip-model": "example-equip-model-val-14665",
+  "fqdn": "example-fqdn-val-33429",
+  "pserver-selflink": "example-pserver-selflink-val-10125",
+  "ipv4-oam-address": "example-ipv4-oam-address-val-3155",
+  "serial-number": "example-serial-number-val-12010",
+  "ipaddress-v4-loopback-0": "example-ipaddress-v4-loopback0-val-77686",
+  "ipaddress-v6-loopback-0": "example-ipaddress-v6-loopback0-val-17856",
+  "ipaddress-v4-aim": "example-ipaddress-v4-aim-val-33665",
+  "ipaddress-v6-aim": "example-ipaddress-v6-aim-val-6210",
+  "ipaddress-v6-oam": "example-ipaddress-v6-oam-val-40977",
+  "inv-status": "example-inv-status-val-3682",
+  "pserver-id": "example-pserver-id-val-82142",
+  "internet-topology": "example-internet-topology-val-56425",
+  "in-maint": true,
+  "pserver-name2": "example-pserver-name2-val-53802",
+  "purpose": "example-purpose-val-90218",
+  "prov-status": "example-prov-status-val-11642",
+  "management-option": "example-management-option-val-91111",
+  "host-profile": "example-host-profile-val-36247"
+}
\ No newline at end of file
diff --git a/aai-core/src/test/resources/payloads/templates/relationship.json b/aai-core/src/test/resources/payloads/templates/relationship.json
new file mode 100644 (file)
index 0000000..ea07d5e
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "related-to": "${related-to}",
+  "related-link": "${related-link}"
+}
\ No newline at end of file
index 54e3bd7..69cd382 100644 (file)
@@ -3283,28 +3283,28 @@ xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
             </xs:appinfo>
           </xs:annotation>
         </xs:element>
-        <xs:element name="bandwidth-up-wan1" type="xs:string">
+        <xs:element name="bandwidth-up-wan1" type="xs:string" minOccurs="0">
           <xs:annotation>
             <xs:appinfo>
               <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the upstream bandwidth this service will use on the WAN1 port of the physical device.")</annox:annotate>
             </xs:appinfo>
           </xs:annotation>
         </xs:element>
-        <xs:element name="bandwidth-down-wan1" type="xs:string">
+        <xs:element name="bandwidth-down-wan1" type="xs:string" minOccurs="0">
           <xs:annotation>
             <xs:appinfo>
               <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the downstream bandwidth this service will use on the WAN1 port of the physical device.")</annox:annotate>
             </xs:appinfo>
           </xs:annotation>
         </xs:element>
-        <xs:element name="bandwidth-up-wan2" type="xs:string">
+        <xs:element name="bandwidth-up-wan2" type="xs:string" minOccurs="0">
           <xs:annotation>
             <xs:appinfo>
               <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the upstream bandwidth this service will use on the WAN2 port of the physical device.")</annox:annotate>
             </xs:appinfo>
           </xs:annotation>
         </xs:element>
-        <xs:element name="bandwidth-down-wan2" type="xs:string">
+        <xs:element name="bandwidth-down-wan2" type="xs:string" minOccurs="0">
           <xs:annotation>
             <xs:appinfo>
               <annox:annotate target="field">@org.onap.aai.annotations.Metadata(description="indicates the downstream bandwidth this service will use on the WAN2 port of the physical device.")</annox:annotate>
index fdd6cd6..f91de49 100644 (file)
                                                <xml-property name="description" value="Indicates the total bandwidth to be used for this service." />
                                        </xml-properties>
                                </xml-element>
-                               <xml-element java-attribute="bandwidthUpWan1" name="bandwidth-up-wan1" required="true" type="java.lang.String">
+                               <xml-element java-attribute="bandwidthUpWan1" name="bandwidth-up-wan1" type="java.lang.String">
                                        <xml-properties>
                                                <xml-property name="description" value="indicates the upstream bandwidth this service will use on the WAN1 port of the physical device." />
                                        </xml-properties>
                                </xml-element>
-                               <xml-element java-attribute="bandwidthDownWan1" name="bandwidth-down-wan1" required="true" type="java.lang.String">
+                               <xml-element java-attribute="bandwidthDownWan1" name="bandwidth-down-wan1" type="java.lang.String">
                                        <xml-properties>
                                                <xml-property name="description" value="indicates the downstream bandwidth this service will use on the WAN1 port of the physical device." />
                                        </xml-properties>
                                </xml-element>
-                               <xml-element java-attribute="bandwidthUpWan2" name="bandwidth-up-wan2" required="true" type="java.lang.String">
+                               <xml-element java-attribute="bandwidthUpWan2" name="bandwidth-up-wan2" type="java.lang.String">
                                        <xml-properties>
                                                <xml-property name="description" value="indicates the upstream bandwidth this service will use on the WAN2 port of the physical device." />
                                        </xml-properties>
                                </xml-element>
-                               <xml-element java-attribute="bandwidthDownWan2" name="bandwidth-down-wan2" required="true" type="java.lang.String">
+                               <xml-element java-attribute="bandwidthDownWan2" name="bandwidth-down-wan2" type="java.lang.String">
                                        <xml-properties>
                                                <xml-property name="description" value="indicates the downstream bandwidth this service will use on the WAN2 port of the physical device." />
                                        </xml-properties>