b30c9367095d493a531c29cf3bcc1a98c31cd754
[aai/aai-common.git] / aai-core / src / test / java / org / openecomp / aai / serialization / db / DbSerializerTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * org.openecomp.aai
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.aai.serialization.db;
22
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;
46
47 import static org.junit.Assert.*;
48 import static org.mockito.Mockito.spy;
49 import static org.mockito.Mockito.when;
50
51 import java.io.UnsupportedEncodingException;
52 import java.net.URI;
53 import java.net.URISyntaxException;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 import java.util.List;
57
58 public class DbSerializerTest extends AAISetup {
59
60         //to use, set thrown.expect to whatever your test needs
61         //this line establishes default of expecting no exception to be thrown
62         @Rule
63         public ExpectedException thrown = ExpectedException.none();
64
65         protected Graph graph;
66         protected final EdgeRules rules = EdgeRules.getInstance();
67
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;
78
79         @Before
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);
84                 spy = spy(dbEngine);
85                 adminSpy = spy(dbEngine.asAdmin());
86
87                 createGraph();
88
89                 engine = new TitanDBEngine(queryStyle, type, loader);
90                 dbser = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST");
91         }
92
93         public void createGraph() throws AAIException {
94                 /*
95                  * This setus up the test graph, For future junits , add more vertices
96                  * and edges
97                  */
98
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")
108                                 .next();
109
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);
114
115         }
116
117         @After
118         public void tearDown() throws Exception {
119                 graph.close();
120         }
121
122         @Test
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]";
125
126                 /*
127                  * This subnet has in-edges with l3-ipv4 and NOT ok to delete
128                  */
129                 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-2").next();
130
131                 String exceptionMessage = testDelete(subnet);
132                 assertEquals(expected_message, exceptionMessage);
133
134         }
135
136         @Test
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]";
139
140                 /*
141                  * This subnet has in-edges with l3-ipv6 and NOT ok to delete
142                  */
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);
146
147         }
148
149         @Test
150         public void subnetDelwithInEdgesL3network() throws AAIException {
151                 String expected_message = "";
152
153                 /*
154                  * This subnet has in-edges with l3-network and ok to delete
155                  */
156                 Vertex subnet = graph.traversal().V().has("aai-node-type", "subnet").has("subnet-id", "subnet-id-5").next();
157
158                 String exceptionMessage = testDelete(subnet);
159                 assertEquals(expected_message, exceptionMessage);
160
161         }
162
163         public String testDelete(Vertex v) throws AAIException {
164
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);
170
171                 String exceptionMessage = "";
172                 DBSerializer serializer = new DBSerializer(version, spy, introspectorFactoryType, "AAI_TEST");
173                 try {
174                         serializer.delete(v, "resourceVersion", false);
175                 } catch (AAIException exception) {
176                         exceptionMessage = exception.getMessage();
177
178                 }
179                 return exceptionMessage;
180
181         }
182
183         @Test
184         public void createNewVertexTest() throws AAIException {
185                 engine.startTransaction();
186
187                 Introspector testObj = loader.introspectorFromName("generic-vnf");
188
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());
193                 engine.rollback();
194         }
195
196         @Test
197         public void touchStandardVertexPropertiesTest() throws AAIException, InterruptedException {
198                 engine.startTransaction();
199                 DBSerializer dbser2 = new DBSerializer(Version.getLatest(), engine, introspectorFactoryType, "AAI-TEST-2");
200
201                 Graph graph = TinkerGraph.open();
202                 Vertex vert = graph.addVertex("aai-node-type", "generic-vnf");
203
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();
207
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
211
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());
216                 engine.rollback();
217         }
218
219         @Test
220         public void verifyResourceVersion_SunnyDayTest() throws AAIException {
221                 engine.startTransaction();
222
223                 assertTrue(dbser.verifyResourceVersion("delete", "vnfc", "abc", "abc", "vnfcs/vnfc/vnfcId"));
224                 engine.rollback();
225         }
226
227         @Test
228         public void verifyResourceVersion_CreateWithRVTest() throws AAIException {
229                 engine.startTransaction();
230
231                 thrown.expect(AAIException.class);
232                 thrown.expectMessage("resource-version passed for create of generic-vnfs/generic-vnf/myid");
233                 try {
234                         dbser.verifyResourceVersion("create", "generic-vnf", null, "old-res-ver", "generic-vnfs/generic-vnf/myid");
235                 } finally {
236                         engine.rollback();
237                 }
238         }
239
240         @Test
241         public void verifyResourceVersion_MissingRVTest() throws AAIException {
242                 engine.startTransaction();
243
244                 thrown.expect(AAIException.class);
245                 thrown.expectMessage("resource-version not passed for update of generic-vnfs/generic-vnf/myid");
246                 try {
247                         dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", null, "generic-vnfs/generic-vnf/myid");
248                 } finally {
249                         engine.rollback();
250                 }
251         }
252
253         @Test
254         public void verifyResourceVersion_MismatchRVTest() throws AAIException {
255                 engine.startTransaction();
256
257                 thrown.expect(AAIException.class);
258                 thrown.expectMessage("resource-version MISMATCH for update of generic-vnfs/generic-vnf/myid");
259                 try {
260                         dbser.verifyResourceVersion("update", "generic-vnf", "current-res-ver", "old-res-ver", "generic-vnfs/generic-vnf/myid");
261                 } finally {
262                         engine.rollback();
263                 }
264         }
265
266         @Test
267         public void trimClassNameTest() throws AAIException {
268                 assertEquals("GenericVnf", dbser.trimClassName("GenericVnf"));
269                 assertEquals("GenericVnf", dbser.trimClassName("org.onap.aai.GenericVnf"));
270         }
271
272         @Test
273         public void getURIForVertexTest() throws AAIException, URISyntaxException, UnsupportedEncodingException {
274                 engine.startTransaction();
275
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);
280
281                 URI compare = new URI("/cloud-infrastructure/cloud-regions/cloud-region/me/123/tenants/tenant/453");
282                 assertEquals(compare, dbser.getURIForVertex(ten));
283
284                 cr.property("aai-node-type").remove();
285                 URI compareFailure = new URI("/unknown-uri");
286                 assertEquals(compareFailure, dbser.getURIForVertex(ten));
287                 engine.rollback();
288         }
289
290         @Test
291         public void getVertexPropertiesTest() throws AAIException, UnsupportedEncodingException {
292                 engine.startTransaction();
293
294                 Vertex cr = engine.tx().addVertex("aai-node-type", "cloud-region", "cloud-owner", "me", "cloud-region-id", "123");
295
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"));
300                 engine.rollback();
301         }
302
303         @Test
304         public void setCachedURIsTest() throws AAIException, UnsupportedEncodingException, URISyntaxException {
305                 engine.startTransaction();
306
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);
315
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));
321
322                 dbser.setCachedURIs(vertices, intros);
323
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());
330                 engine.rollback();
331         }
332
333         @Test
334         public void getEdgeBetweenTest() throws AAIException {
335                 engine.startTransaction();
336
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);
341
342                 Edge e = dbser.getEdgeBetween(EdgeType.TREE, ten, cr);
343                 assertEquals("has", e.label());
344                 engine.rollback();
345         }
346
347         @Test
348         public void deleteEdgeTest() throws AAIException, UnsupportedEncodingException {
349                 engine.startTransaction();
350
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);
355
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);
363
364                 assertTrue(dbser.deleteEdge(relationship, gvnf));
365
366                 assertFalse(engine.tx().traversal().V(gvnf).both("uses").hasNext());
367                 assertFalse(engine.tx().traversal().V(vnfc).both("uses").hasNext());
368                 engine.rollback();
369         }
370
371         @Test
372         public void createEdgeTest() throws AAIException, UnsupportedEncodingException {
373                 engine.startTransaction();
374
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");
377
378                 //sunny day case
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);
386
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());
390
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);
399
400                 thrown.expect(AAIException.class);
401                 thrown.expectMessage("Node of type vnfc. Could not find object at: /network/vnfcs/vnfc/b-name");
402                 try {
403                         dbser.createEdge(relationship2, gvnf);
404                 } finally {
405                         engine.rollback();
406                 }
407         }
408
409         @Test
410         public void serializeSingleVertexTopLevelTest() throws AAIException, UnsupportedEncodingException {
411                 engine.startTransaction();
412
413                 Introspector gvnf = loader.introspectorFromName("generic-vnf");
414                 Vertex gvnfVert = dbser.createNewVertex(gvnf);
415
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());
419                 engine.rollback();
420         }
421
422         @Test
423         public void serializeSingleVertexChildTest() throws AAIException, UnsupportedEncodingException {
424                 engine.startTransaction();
425
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);
431
432                 tenIn.setValue("tenant-id", "453");
433                 tenIn.setValue("tenant-name", "mytenant");
434
435                 dbser.serializeSingleVertex(ten, tenIn, "test");
436
437                 assertTrue(engine.tx().traversal().V().has("aai-node-type","tenant").has("tenant-id","453").has("tenant-name","mytenant").hasNext());
438                 engine.rollback();
439         }
440 }