2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 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=========================================================
21 package org.openecomp.aai.serialization.db;
23 import com.thinkaurelius.titan.core.TitanFactory;
24 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
25 import org.apache.tinkerpop.gremlin.structure.Edge;
26 import org.apache.tinkerpop.gremlin.structure.Graph;
27 import org.apache.tinkerpop.gremlin.structure.Vertex;
28 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Rule;
32 import org.junit.Test;
33 import org.junit.rules.ExpectedException;
34 import org.openecomp.aai.AAISetup;
35 import org.openecomp.aai.db.props.AAIProperties;
36 import org.openecomp.aai.dbmap.DBConnectionType;
37 import org.openecomp.aai.exceptions.AAIException;
38 import org.openecomp.aai.introspection.Introspector;
39 import org.openecomp.aai.introspection.Loader;
40 import org.openecomp.aai.introspection.LoaderFactory;
41 import org.openecomp.aai.introspection.ModelType;
42 import org.openecomp.aai.introspection.Version;
43 import org.openecomp.aai.serialization.engines.QueryStyle;
44 import org.openecomp.aai.serialization.engines.TitanDBEngine;
45 import org.openecomp.aai.serialization.engines.TransactionalGraphEngine;
47 import static org.junit.Assert.*;
48 import static org.mockito.Mockito.spy;
49 import static org.mockito.Mockito.when;
51 import java.io.UnsupportedEncodingException;
53 import java.net.URISyntaxException;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.List;
58 public class DbSerializerTest extends AAISetup {
60 //to use, set thrown.expect to whatever your test needs
61 //this line establishes default of expecting no exception to be thrown
63 public ExpectedException thrown = ExpectedException.none();
65 protected Graph graph;
66 protected final EdgeRules rules = EdgeRules.getInstance();
68 private final Version version = Version.getLatest();
69 private final ModelType introspectorFactoryType = ModelType.MOXY;
70 private final QueryStyle queryStyle = QueryStyle.TRAVERSAL;
71 private final DBConnectionType type = DBConnectionType.REALTIME;
72 private Loader loader;
73 private TransactionalGraphEngine dbEngine;
74 private TransactionalGraphEngine engine; //for tests that aren't mocking the engine
75 private DBSerializer dbser;
76 TransactionalGraphEngine spy;
77 TransactionalGraphEngine.Admin adminSpy;
80 public void setup() throws Exception {
81 graph = TitanFactory.build().set("storage.backend", "inmemory").open();
82 loader = LoaderFactory.createLoaderForVersion(introspectorFactoryType, version);
83 dbEngine = new TitanDBEngine(queryStyle, type, loader);
85 adminSpy = spy(dbEngine.asAdmin());
89 engine = new TitanDBEngine(queryStyle, type, loader);
90 dbser = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST");
93 public void createGraph() throws AAIException {
95 * This setus up the test graph, For future junits , add more vertices
99 Vertex l3interipv4addresslist_1 = graph.traversal().addV("aai-node-type", "l3-interface-ipv4-address-list",
100 "l3-interface-ipv4-address", "l3-interface-ipv4-address-1").next();
101 Vertex subnet_2 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-2").next();
102 Vertex l3interipv6addresslist_3 = graph.traversal().addV("aai-node-type", "l3-interface-ipv6-address-list",
103 "l3-interface-ipv6-address", "l3-interface-ipv6-address-3").next();
104 Vertex subnet_4 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-4").next();
105 Vertex subnet_5 = graph.traversal().addV("aai-node-type", "subnet", "subnet-id", "subnet-id-5").next();
106 Vertex l3network_6 = graph.traversal()
107 .addV("aai-node-type", "l3-network", "network-id", "network-id-6", "network-name", "network-name-6")
110 GraphTraversalSource g = graph.traversal();
111 rules.addEdge(g, l3interipv4addresslist_1, subnet_2);
112 rules.addEdge(g, l3interipv6addresslist_3, subnet_4);
113 rules.addTreeEdge(g, subnet_5, l3network_6);
118 public void tearDown() throws Exception {
123 public void subnetDelwithInEdgesIpv4Test() throws AAIException {
124 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]";
127 * This subnet has in-edges with l3-ipv4 and NOT ok to delete
129 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-2").next();
131 String exceptionMessage = testDelete(subnet);
132 assertEquals(expected_message, exceptionMessage);
137 public void subnetDelwithInEdgesIpv6Test() throws AAIException {
138 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]";
141 * This subnet has in-edges with l3-ipv6 and NOT ok to delete
143 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-4").next();
144 String exceptionMessage = testDelete(subnet);
145 assertEquals(expected_message, exceptionMessage);
150 public void subnetDelwithInEdgesL3network() throws AAIException {
151 String expected_message = "";
154 * This subnet has in-edges with l3-network and ok to delete
156 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-5").next();
158 String exceptionMessage = testDelete(subnet);
159 assertEquals(expected_message, exceptionMessage);
163 public String testDelete(Vertex v) throws AAIException {
165 // Graph g_tx = graph.newTransaction();
166 GraphTraversalSource traversal = graph.traversal();
167 when(spy.asAdmin()).thenReturn(adminSpy);
168 when(adminSpy.getTraversalSource()).thenReturn(traversal);
169 when(adminSpy.getReadOnlyTraversalSource()).thenReturn(traversal);
171 String exceptionMessage = "";
172 DBSerializer serializer = new DBSerializer(version, spy, introspectorFactoryType, "AAI_TEST");
174 serializer.delete(v, "resourceVersion", false);
175 } catch (AAIException exception) {
176 exceptionMessage = exception.getMessage();
179 return exceptionMessage;
184 public void createNewVertexTest() throws AAIException {
185 engine.startTransaction();
187 Introspector testObj = loader.introspectorFromName("generic-vnf");
189 Vertex testVertex = dbser.createNewVertex(testObj);
190 Vertex fromGraph = engine.tx().traversal().V().has("aai-node-type","generic-vnf").toList().get(0);
191 assertEquals(testVertex.id(), fromGraph.id());
192 assertEquals("AAI-TEST", fromGraph.property(AAIProperties.SOURCE_OF_TRUTH.toString()).value());
197 public void touchStandardVertexPropertiesTest() throws AAIException, InterruptedException {
198 engine.startTransaction();
199 DBSerializer dbser2 = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST-2");
201 Graph graph = TinkerGraph.open();
202 Vertex vert = graph.addVertex("aai-node-type", "generic-vnf");
204 dbser.touchStandardVertexProperties(vert, true);
205 String resverStart = (String)vert.property(AAIProperties.RESOURCE_VERSION.toString()).value();
206 String lastModTimeStart = (String)vert.property(AAIProperties.LAST_MOD_TS.toString()).value();
208 Thread.sleep(10); //bc the resource version is set based on current time in milliseconds,
209 //if this test runs through too fast the value may not change
210 //causing the test to fail. sleeping ensures a different value
212 dbser2.touchStandardVertexProperties(vert, false);
213 assertFalse(resverStart.equals((String)vert.property(AAIProperties.RESOURCE_VERSION.toString()).value()));
214 assertFalse(lastModTimeStart.equals((String)vert.property(AAIProperties.LAST_MOD_TS.toString()).value()));
215 assertEquals("AAI-TEST-2", (String)vert.property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH.toString()).value());
220 public void verifyResourceVersion_SunnyDayTest() throws AAIException {
221 engine.startTransaction();
223 assertTrue(dbser.verifyResourceVersion("delete", "vnfc", "abc", "abc", "vnfcs/vnfc/vnfcId"));
228 public void verifyResourceVersion_CreateWithRVTest() throws AAIException {
229 engine.startTransaction();
231 thrown.expect(AAIException.class);
232 thrown.expectMessage("resource-version passed for create of generic-vnfs/generic-vnf/myid");
234 dbser.verifyResourceVersion("create", "generic-vnf", null, "old-res-ver", "generic-vnfs/generic-vnf/myid");
241 public void verifyResourceVersion_MissingRVTest() throws AAIException {
242 engine.startTransaction();
244 thrown.expect(AAIException.class);
245 thrown.expectMessage("resource-version not passed for update of generic-vnfs/generic-vnf/myid");
247 dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", null, "generic-vnfs/generic-vnf/myid");
254 public void verifyResourceVersion_MismatchRVTest() throws AAIException {
255 engine.startTransaction();
257 thrown.expect(AAIException.class);
258 thrown.expectMessage("resource-version MISMATCH for update of generic-vnfs/generic-vnf/myid");
260 dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", "old-res-ver", "generic-vnfs/generic-vnf/myid");
267 public void trimClassNameTest() throws AAIException {
268 assertEquals("GenericVnf", dbser.trimClassName("GenericVnf"));
269 assertEquals("GenericVnf", dbser.trimClassName("org.onap.aai.GenericVnf"));
273 public void getURIForVertexTest() throws AAIException, URISyntaxException, UnsupportedEncodingException {
274 engine.startTransaction();
276 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
277 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
278 EdgeRules rules = EdgeRules.getInstance();
279 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
281 URI compare = new URI("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453");
282 assertEquals(compare, dbser.getURIForVertex(ten));
284 cr.property("aai-node-type").remove();
285 URI compareFailure = new URI("/unknown-uri");
286 assertEquals(compareFailure, dbser.getURIForVertex(ten));
291 public void getVertexPropertiesTest() throws AAIException, UnsupportedEncodingException {
292 engine.startTransaction();
294 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
296 Introspector crIntro = dbser.getVertexProperties(cr);
297 assertEquals("cloud-region", crIntro.getDbName());
298 assertEquals("me", crIntro.getValue("cloud-owner"));
299 assertEquals("123", crIntro.getValue("cloud-region-id"));
304 public void setCachedURIsTest() throws AAIException, UnsupportedEncodingException, URISyntaxException {
305 engine.startTransaction();
307 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
308 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
309 Vertex vs = engine.tx().addVertex("aai-node-type", "vserver", "vserver-id", "vs1",
310 AAIProperties.AAI_URI.toString(),
311 "/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453/vservers/vserver/vs1");
312 EdgeRules rules = EdgeRules.getInstance();
313 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
314 rules.addTreeEdge(engine.tx().traversal(), ten, vs);
316 List<Vertex> vertices = new ArrayList<Vertex>(Arrays.asList(cr, ten, vs));
317 Introspector crIn = dbser.getVertexProperties(cr);
318 Introspector tenIn = dbser.getVertexProperties(ten);
319 Introspector vsIn = dbser.getVertexProperties(vs);
320 List<Introspector> intros = new ArrayList<Introspector>(Arrays.asList(crIn, tenIn, vsIn));
322 dbser.setCachedURIs(vertices, intros);
324 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123",
325 (String)cr.property(AAIProperties.AAI_URI.toString()).value());
326 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453",
327 (String)ten.property(AAIProperties.AAI_URI.toString()).value());
328 assertEquals("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453/vservers/vserver/vs1",
329 (String)vs.property(AAIProperties.AAI_URI.toString()).value());
334 public void getEdgeBetweenTest() throws AAIException {
335 engine.startTransaction();
337 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
338 Vertex ten = engine.tx().addVertex("aai-node-type", "tenant", "tenant-id", "453");
339 EdgeRules rules = EdgeRules.getInstance();
340 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
342 Edge e = dbser.getEdgeBetween(EdgeType.TREE, ten, cr);
343 assertEquals("has", e.label());
348 public void deleteEdgeTest() throws AAIException, UnsupportedEncodingException {
349 engine.startTransaction();
351 Vertex gvnf = engine.tx().addVertex("aai-node-type","generic-vnf","vnf-id","myvnf");
352 Vertex vnfc = engine.tx().addVertex("aai-node-type","vnfc","vnfc-name","a-name");
353 EdgeRules rules = EdgeRules.getInstance();
354 rules.addEdge(engine.tx().traversal(), gvnf, vnfc);
356 Introspector relData = loader.introspectorFromName("relationship-data");
357 relData.setValue("relationship-key", "vnfc.vnfc-name");
358 relData.setValue("relationship-value", "a-name");
359 Introspector relationship = loader.introspectorFromName("relationship");
360 relationship.setValue("related-to", "vnfc");
361 relationship.setValue("related-link", "/network/vnfcs/vnfc/a-name");
362 relationship.setValue("relationship-data",relData);
364 assertTrue(dbser.deleteEdge(relationship, gvnf));
366 assertFalse(engine.tx().traversal().V(gvnf).both("uses").hasNext());
367 assertFalse(engine.tx().traversal().V(vnfc).both("uses").hasNext());
372 public void createEdgeTest() throws AAIException, UnsupportedEncodingException {
373 engine.startTransaction();
375 Vertex gvnf = engine.tx().addVertex("aai-node-type","generic-vnf","vnf-id","myvnf");
376 Vertex vnfc = engine.tx().addVertex("aai-node-type","vnfc","vnfc-name","a-name");
379 Introspector relData = loader.introspectorFromName("relationship-data");
380 relData.setValue("relationship-key", "vnfc.vnfc-name");
381 relData.setValue("relationship-value", "a-name");
382 Introspector relationship = loader.introspectorFromName("relationship");
383 relationship.setValue("related-to", "vnfc");
384 relationship.setValue("related-link", "/network/vnfcs/vnfc/a-name");
385 relationship.setValue("relationship-data",relData);
387 assertTrue(dbser.createEdge(relationship, gvnf));
388 assertTrue(engine.tx().traversal().V(gvnf).both("uses").hasNext());
389 assertTrue(engine.tx().traversal().V(vnfc).both("uses").hasNext());
391 //rainy day case, edge to nonexistant object
392 Introspector relData2 = loader.introspectorFromName("relationship-data");
393 relData2.setValue("relationship-key", "vnfc.vnfc-name");
394 relData2.setValue("relationship-value", "b-name");
395 Introspector relationship2 = loader.introspectorFromName("relationship");
396 relationship2.setValue("related-to", "vnfc");
397 relationship2.setValue("related-link", "/network/vnfcs/vnfc/b-name");
398 relationship2.setValue("relationship-data",relData2);
400 thrown.expect(AAIException.class);
401 thrown.expectMessage("Node of type vnfc. Could not find object at: /network/vnfcs/vnfc/b-name");
403 dbser.createEdge(relationship2, gvnf);
410 public void serializeSingleVertexTopLevelTest() throws AAIException, UnsupportedEncodingException {
411 engine.startTransaction();
413 Introspector gvnf = loader.introspectorFromName("generic-vnf");
414 Vertex gvnfVert = dbser.createNewVertex(gvnf);
416 gvnf.setValue("vnf-id", "myvnf");
417 dbser.serializeSingleVertex(gvnfVert, gvnf, "test");
418 assertTrue(engine.tx().traversal().V().has("aai-node-type","generic-vnf").has("vnf-id","myvnf").hasNext());
423 public void serializeSingleVertexChildTest() throws AAIException, UnsupportedEncodingException {
424 engine.startTransaction();
426 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
427 Introspector tenIn = loader.introspectorFromName("tenant");
428 Vertex ten = dbser.createNewVertex(tenIn);
429 EdgeRules rules = EdgeRules.getInstance();
430 rules.addTreeEdge(engine.tx().traversal(), cr, ten);
432 tenIn.setValue("tenant-id", "453");
433 tenIn.setValue("tenant-name", "mytenant");
435 dbser.serializeSingleVertex(ten, tenIn, "test");
437 assertTrue(engine.tx().traversal().V().has("aai-node-type","tenant").has("tenant-id","453").has("tenant-name","mytenant").hasNext());