2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.serialization.db;
24 import com.thinkaurelius.titan.core.TitanFactory;
25 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
26 import org.apache.tinkerpop.gremlin.structure.Edge;
27 import org.apache.tinkerpop.gremlin.structure.Graph;
28 import org.apache.tinkerpop.gremlin.structure.Vertex;
29 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
30 import org.junit.After;
31 import org.junit.Before;
32 import org.junit.Rule;
33 import org.junit.Test;
34 import org.junit.rules.ExpectedException;
35 import org.onap.aai.AAISetup;
36 import org.onap.aai.db.props.AAIProperties;
37 import org.onap.aai.dbmap.DBConnectionType;
38 import org.onap.aai.exceptions.AAIException;
39 import org.onap.aai.introspection.Introspector;
40 import org.onap.aai.introspection.Loader;
41 import org.onap.aai.introspection.LoaderFactory;
42 import org.onap.aai.introspection.ModelType;
43 import org.onap.aai.introspection.Version;
44 import org.onap.aai.serialization.engines.QueryStyle;
45 import org.onap.aai.serialization.engines.TitanDBEngine;
46 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
48 import static org.junit.Assert.*;
49 import static org.mockito.Mockito.spy;
50 import static org.mockito.Mockito.when;
52 import java.io.UnsupportedEncodingException;
54 import java.net.URISyntaxException;
55 import java.util.ArrayList;
56 import java.util.Arrays;
57 import java.util.List;
59 public class DbSerializerTest extends AAISetup {
61 //to use, set thrown.expect to whatever your test needs
62 //this line establishes default of expecting no exception to be thrown
64 public ExpectedException thrown = ExpectedException.none();
66 protected Graph graph;
67 protected final EdgeRules rules = EdgeRules.getInstance();
69 private final Version version = Version.getLatest();
70 private final ModelType introspectorFactoryType = ModelType.MOXY;
71 private final QueryStyle queryStyle = QueryStyle.TRAVERSAL;
72 private final DBConnectionType type = DBConnectionType.REALTIME;
73 private Loader loader;
74 private TransactionalGraphEngine dbEngine;
75 private TransactionalGraphEngine engine; //for tests that aren't mocking the engine
76 private DBSerializer dbser;
77 TransactionalGraphEngine spy;
78 TransactionalGraphEngine.Admin adminSpy;
81 public void setup() throws Exception {
82 graph = TitanFactory.build().set("storage.backend", "inmemory").open();
83 loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version);
84 dbEngine = new TitanDBEngine(queryStyle, type, loader);
86 adminSpy = spy(dbEngine.asAdmin());
90 engine = new TitanDBEngine(queryStyle, type, loader);
91 dbser = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST");
94 public void createGraph() throws AAIException {
96 * This setus up the test graph, For future junits , add more vertices
100 Vertex l3interipv4addresslist_1 = graph.traversal().addV("aai-node-type", "l3-interface-ipv4-address-list",
101 "l3-interface-ipv4-address", "l3-interface-ipv4-address-1").next();
102 Vertex subnet_2 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-2").next();
103 Vertex l3interipv6addresslist_3 = graph.traversal().addV("aai-node-type", "l3-interface-ipv6-address-list",
104 "l3-interface-ipv6-address", "l3-interface-ipv6-address-3").next();
105 Vertex subnet_4 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-4").next();
106 Vertex subnet_5 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-5").next();
107 Vertex l3network_6 = graph.traversal()
108 .addV("aai-node-type", "l3-network", "network-id", "network-id-6", "network-name", "network-name-6")
111 GraphTraversalSource g = graph.traversal();
112 rules.addEdge(g, l3interipv4addresslist_1, subnet_2);
113 rules.addEdge(g, l3interipv6addresslist_3, subnet_4);
114 rules.addTreeEdge(g, subnet_5, l3network_6);
119 public void tearDown() throws Exception {
124 public void subnetDelwithInEdgesIpv4Test() throws AAIException {
125 String expected_message = "Object is being reference by additional objects preventing it from being deleted. Please clean up references from the following types [l3-interface-ipv4-address-list]";
128 * This subnet has in-edges with l3-ipv4 and NOT ok to delete
130 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-2").next();
132 String exceptionMessage = testDelete(subnet);
133 assertEquals(expected_message, exceptionMessage);
138 public void subnetDelwithInEdgesIpv6Test() throws AAIException {
139 String expected_message = "Object is being reference by additional objects preventing it from being deleted. Please clean up references from the following types [l3-interface-ipv6-address-list]";
142 * This subnet has in-edges with l3-ipv6 and NOT ok to delete
144 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-4").next();
145 String exceptionMessage = testDelete(subnet);
146 assertEquals(expected_message, exceptionMessage);
151 public void subnetDelwithInEdgesL3network() throws AAIException {
152 String expected_message = "";
155 * This subnet has in-edges with l3-network and ok to delete
157 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-5").next();
159 String exceptionMessage = testDelete(subnet);
160 assertEquals(expected_message, exceptionMessage);
164 public String testDelete(Vertex v) throws AAIException {
166 // Graph g_tx = graph.newTransaction();
167 GraphTraversalSource traversal = graph.traversal();
168 when(spy.asAdmin()).thenReturn(adminSpy);
169 when(adminSpy.getTraversalSource()).thenReturn(traversal);
170 when(adminSpy.getReadOnlyTraversalSource()).thenReturn(traversal);
172 String exceptionMessage = "";
173 DBSerializer serializer = new DBSerializer(version, spy, introspectorFactoryType, "AAI_TEST");
175 serializer.delete(v, "resourceVersion", false);
176 } catch (AAIException exception) {
177 exceptionMessage = exception.getMessage();
180 return exceptionMessage;
185 public void createNewVertexTest() throws AAIException {
186 engine.startTransaction();
188 Introspector testObj = loader.introspectorFromName("generic-vnf");
190 Vertex testVertex = dbser.createNewVertex(testObj);
191 Vertex fromGraph = engine.tx().traversal().V().has("aai-node-type","generic-vnf").toList().get(0);
192 assertEquals(testVertex.id(), fromGraph.id());
193 assertEquals("AAI-TEST", fromGraph.property(AAIProperties.SOURCE_OF_TRUTH.toString()).value());
198 public void touchStandardVertexPropertiesTest() throws AAIException, InterruptedException {
199 engine.startTransaction();
200 DBSerializer dbser2 = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST-2");
202 Graph graph = TinkerGraph.open();
203 Vertex vert = graph.addVertex("aai-node-type", "generic-vnf");
205 dbser.touchStandardVertexProperties(vert, true);
206 String resverStart = (String)vert.property(AAIProperties.RESOURCE_VERSION.toString()).value();
207 String lastModTimeStart = (String)vert.property(AAIProperties.LAST_MOD_TS.toString()).value();
209 Thread.sleep(10); //bc the resource version is set based on current time in milliseconds,
210 //if this test runs through too fast the value may not change
211 //causing the test to fail. sleeping ensures a different value
213 dbser2.touchStandardVertexProperties(vert, false);
214 assertFalse(resverStart.equals((String)vert.property(AAIProperties.RESOURCE_VERSION.toString()).value()));
215 assertFalse(lastModTimeStart.equals((String)vert.property(AAIProperties.LAST_MOD_TS.toString()).value()));
216 assertEquals("AAI-TEST-2", (String)vert.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH.toString()).value());
221 public void verifyResourceVersion_SunnyDayTest() throws AAIException {
222 engine.startTransaction();
224 assertTrue(dbser.verifyResourceVersion("delete", "vnfc", "abc", "abc", "vnfcs/vnfc/vnfcId"));
229 public void verifyResourceVersion_CreateWithRVTest() throws AAIException {
230 engine.startTransaction();
232 thrown.expect(AAIException.class);
233 thrown.expectMessage("resource-version passed for create of generic-vnfs/generic-vnf/myid");
235 dbser.verifyResourceVersion("create", "generic-vnf", null, "old-res-ver", "generic-vnfs/generic-vnf/myid");
242 public void verifyResourceVersion_MissingRVTest() throws AAIException {
243 engine.startTransaction();
245 thrown.expect(AAIException.class);
246 thrown.expectMessage("resource-version not passed for update of generic-vnfs/generic-vnf/myid");
248 dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", null, "generic-vnfs/generic-vnf/myid");
255 public void verifyResourceVersion_MismatchRVTest() throws AAIException {
256 engine.startTransaction();
258 thrown.expect(AAIException.class);
259 thrown.expectMessage("resource-version MISMATCH for update of generic-vnfs/generic-vnf/myid");
261 dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", "old-res-ver", "generic-vnfs/generic-vnf/myid");
268 public void trimClassNameTest() throws AAIException {
269 assertEquals("GenericVnf", dbser.trimClassName("GenericVnf"));
270 assertEquals("GenericVnf", dbser.trimClassName("org.onap.aai.GenericVnf"));
274 public void getURIForVertexTest() throws AAIException, URISyntaxException, UnsupportedEncodingException {
275 engine.startTransaction();
277 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
278 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
279 EdgeRules rules = EdgeRules.getInstance();
280 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
282 URI compare = new URI("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453");
283 assertEquals(compare, dbser.getURIForVertex(ten));
285 cr.property("aai-node-type").remove();
286 URI compareFailure = new URI("/unknown-uri");
287 assertEquals(compareFailure, dbser.getURIForVertex(ten));
292 public void getVertexPropertiesTest() throws AAIException, UnsupportedEncodingException {
293 engine.startTransaction();
295 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
297 Introspector crIntro = dbser.getVertexProperties(cr);
298 assertEquals("cloud-region", crIntro.getDbName());
299 assertEquals("me", crIntro.getValue("cloud-owner"));
300 assertEquals("123", crIntro.getValue("cloud-region-id"));
305 public void setCachedURIsTest() throws AAIException, UnsupportedEncodingException, URISyntaxException {
306 engine.startTransaction();
308 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
309 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
310 Vertex vs = engine.tx().addVertex("aai-node-type", "vserver", "vserver-id", "vs1",
311 AAIProperties.AAI_URI.toString(),
312 "/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453/vservers/vserver/vs1");
313 EdgeRules rules = EdgeRules.getInstance();
314 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
315 rules.addTreeEdge(engine.tx().traversal(), ten, vs);
317 List<Vertex> vertices = new ArrayList<Vertex>(Arrays.asList(cr, ten, vs));
318 Introspector crIn = dbser.getVertexProperties(cr);
319 Introspector tenIn = dbser.getVertexProperties(ten);
320 Introspector vsIn = dbser.getVertexProperties(vs);
321 List<Introspector> intros = new ArrayList<Introspector>(Arrays.asList(crIn, tenIn, vsIn));
323 dbser.setCachedURIs(vertices, intros);
325 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123",
326 (String)cr.property(AAIProperties.AAI_URI.toString()).value());
327 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453",
328 (String)ten.property(AAIProperties.AAI_URI.toString()).value());
329 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453/vservers/vserver/vs1",
330 (String)vs.property(AAIProperties.AAI_URI.toString()).value());
335 public void getEdgeBetweenTest() throws AAIException {
336 engine.startTransaction();
338 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
339 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
340 EdgeRules rules = EdgeRules.getInstance();
341 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
343 Edge e = dbser.getEdgeBetween(EdgeType.TREE, ten, cr);
344 assertEquals("has", e.label());
349 public void deleteEdgeTest() throws AAIException, UnsupportedEncodingException {
350 engine.startTransaction();
352 Vertex gvnf = engine.tx().addVertex("aai-node-type","generic-vnf","vnf-id","myvnf");
353 Vertex vnfc = engine.tx().addVertex("aai-node-type","vnfc","vnfc-name","a-name");
354 EdgeRules rules = EdgeRules.getInstance();
355 rules.addEdge(engine.tx().traversal(), gvnf, vnfc);
357 Introspector relData = loader.introspectorFromName("relationship-data");
358 relData.setValue("relationship-key", "vnfc.vnfc-name");
359 relData.setValue("relationship-value", "a-name");
360 Introspector relationship = loader.introspectorFromName("relationship");
361 relationship.setValue("related-to", "vnfc");
362 relationship.setValue("related-link", "/network/vnfcs/vnfc/a-name");
363 relationship.setValue("relationship-data",relData);
365 assertTrue(dbser.deleteEdge(relationship, gvnf));
367 assertFalse(engine.tx().traversal().V(gvnf).both("uses").hasNext());
368 assertFalse(engine.tx().traversal().V(vnfc).both("uses").hasNext());
373 public void createEdgeTest() throws AAIException, UnsupportedEncodingException {
374 engine.startTransaction();
376 Vertex gvnf = engine.tx().addVertex("aai-node-type","generic-vnf","vnf-id","myvnf");
377 Vertex vnfc = engine.tx().addVertex("aai-node-type","vnfc","vnfc-name","a-name");
380 Introspector relData = loader.introspectorFromName("relationship-data");
381 relData.setValue("relationship-key", "vnfc.vnfc-name");
382 relData.setValue("relationship-value", "a-name");
383 Introspector relationship = loader.introspectorFromName("relationship");
384 relationship.setValue("related-to", "vnfc");
385 relationship.setValue("related-link", "/network/vnfcs/vnfc/a-name");
386 relationship.setValue("relationship-data",relData);
388 assertTrue(dbser.createEdge(relationship, gvnf));
389 assertTrue(engine.tx().traversal().V(gvnf).both("uses").hasNext());
390 assertTrue(engine.tx().traversal().V(vnfc).both("uses").hasNext());
392 //rainy day case, edge to nonexistant object
393 Introspector relData2 = loader.introspectorFromName("relationship-data");
394 relData2.setValue("relationship-key", "vnfc.vnfc-name");
395 relData2.setValue("relationship-value", "b-name");
396 Introspector relationship2 = loader.introspectorFromName("relationship");
397 relationship2.setValue("related-to", "vnfc");
398 relationship2.setValue("related-link", "/network/vnfcs/vnfc/b-name");
399 relationship2.setValue("relationship-data",relData2);
401 thrown.expect(AAIException.class);
402 thrown.expectMessage("Node of type vnfc. Could not find object at: /network/vnfcs/vnfc/b-name");
404 dbser.createEdge(relationship2, gvnf);
411 public void serializeSingleVertexTopLevelTest() throws AAIException, UnsupportedEncodingException {
412 engine.startTransaction();
414 Introspector gvnf = loader.introspectorFromName("generic-vnf");
415 Vertex gvnfVert = dbser.createNewVertex(gvnf);
417 gvnf.setValue("vnf-id", "myvnf");
418 dbser.serializeSingleVertex(gvnfVert, gvnf, "test");
419 assertTrue(engine.tx().traversal().V().has("aai-node-type","generic-vnf").has("vnf-id","myvnf").hasNext());
424 public void serializeSingleVertexChildTest() throws AAIException, UnsupportedEncodingException {
425 engine.startTransaction();
427 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
428 Introspector tenIn = loader.introspectorFromName("tenant");
429 Vertex ten = dbser.createNewVertex(tenIn);
430 EdgeRules rules = EdgeRules.getInstance();
431 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
433 tenIn.setValue("tenant-id", "453");
434 tenIn.setValue("tenant-name", "mytenant");
436 dbser.serializeSingleVertex(ten, tenIn, "test");
438 assertTrue(engine.tx().traversal().V().has("aai-node-type","tenant").has("tenant-id","453").has("tenant-name","mytenant").hasNext());