Update tinkerpop to 3.2.3 in aai-core
[aai/aai-common.git] / aai-core / src / test / java / org / onap / aai / introspection / sideeffect / DataLinkTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 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.onap.aai.introspection.sideeffect;
22
23 import static org.hamcrest.MatcherAssert.assertThat;
24 import static org.hamcrest.Matchers.is;
25 import static org.hamcrest.Matchers.not;
26 import static org.junit.Assert.*;
27 import static org.mockito.Mockito.spy;
28 import static org.mockito.Mockito.when;
29
30 import java.io.UnsupportedEncodingException;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.List;
34 import java.util.UUID;
35
36 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
37 import org.apache.tinkerpop.gremlin.structure.Graph;
38 import org.apache.tinkerpop.gremlin.structure.Vertex;
39 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
40 import org.janusgraph.core.Cardinality;
41 import org.janusgraph.core.JanusGraph;
42 import org.janusgraph.core.JanusGraphFactory;
43 import org.janusgraph.core.schema.JanusGraphManagement;
44 import org.junit.*;
45 import org.junit.rules.ExpectedException;
46 import org.junit.runner.RunWith;
47 import org.junit.runners.Parameterized;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 import org.onap.aai.DataLinkSetup;
51 import org.onap.aai.db.props.AAIProperties;
52 import org.onap.aai.edges.enums.EdgeProperty;
53 import org.onap.aai.exceptions.AAIException;
54 import org.onap.aai.introspection.Introspector;
55 import org.onap.aai.introspection.Loader;
56 import org.onap.aai.introspection.ModelType;
57 import org.onap.aai.parsers.query.QueryParser;
58 import org.onap.aai.serialization.db.DBSerializer;
59 import org.onap.aai.serialization.engines.JanusGraphDBEngine;
60 import org.onap.aai.serialization.engines.QueryStyle;
61 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
62
63 @RunWith(value = Parameterized.class)
64 public class DataLinkTest extends DataLinkSetup {
65
66     private static JanusGraph graph;
67     private final static ModelType introspectorFactoryType = ModelType.MOXY;
68     private static Loader loader;
69     private static TransactionalGraphEngine dbEngine;
70     @Mock
71     private QueryParser parser;
72     @Mock
73     private Vertex self;
74     @Mock
75     private VertexProperty<String> prop;
76     @Rule
77     public ExpectedException thrown = ExpectedException.none();
78
79     @Parameterized.Parameter
80     public QueryStyle queryStyle;
81
82     @Parameterized.Parameters(name = "QueryStyle.{0}")
83     public static Collection<Object[]> data() {
84         return Arrays.asList(new Object[][] {{QueryStyle.TRAVERSAL}, {QueryStyle.TRAVERSAL_URI}});
85     }
86
87     @BeforeClass
88     public static void setup() {
89         graph = JanusGraphFactory.build().set("storage.backend", "inmemory").open();
90         JanusGraphManagement graphMgt = graph.openManagement();
91         graphMgt.makePropertyKey(AAIProperties.CREATED_TS).dataType(Long.class).cardinality(Cardinality.SINGLE).make();
92         graphMgt.makePropertyKey(AAIProperties.LAST_MOD_TS).dataType(Long.class).cardinality(Cardinality.SINGLE).make();
93         graphMgt.commit();
94
95         graph.traversal()
96             .addV()
97             .property("aai-node-type", "vpn-binding")
98             .property("vpn-id", "addKey")
99             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/addKey")
100             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
101             .property(AAIProperties.CREATED_TS, 123)
102             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
103             .property(AAIProperties.RESOURCE_VERSION, "123")
104             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
105             .property(AAIProperties.LAST_MOD_TS, 333)
106             .as("v1")
107             .addV()
108             .property("aai-node-type", "vpn-binding")
109             .property("vpn-id", "modifyKey")
110             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey")
111             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
112             .property(AAIProperties.CREATED_TS, 123)
113             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
114             .property(AAIProperties.RESOURCE_VERSION, "123")
115             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
116             .property(AAIProperties.LAST_MOD_TS, 333)
117             .as("v2")
118             .addV()
119             .property("aai-node-type", "route-target")
120             .property("global-route-target", "modifyTargetKey")
121             .property("route-target-role", "modifyRoleKey")
122             .property("linked", true)
123             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey/route-targets/route-target/modifyTargetKey/modifyRoleKey")
124             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
125             .property(AAIProperties.CREATED_TS, 123)
126             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
127             .property(AAIProperties.RESOURCE_VERSION, "123")
128             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
129             .property(AAIProperties.LAST_MOD_TS, 333)
130             .as("v3")
131             .addE("org.onap.relationships.inventory.BelongsTo").to("v2").from("v3")
132             .property(EdgeProperty.CONTAINS.toString(), true)
133             .addV()
134             .property("aai-node-type", "vpn-binding")
135             .property("vpn-id", "deleteKey")
136             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey")
137             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
138             .property(AAIProperties.CREATED_TS, 123)
139             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
140             .property(AAIProperties.RESOURCE_VERSION, "123")
141             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
142             .property(AAIProperties.LAST_MOD_TS, 333)
143             .as("v4")
144             .addV()
145             .property("aai-node-type", "route-target")
146             .property("global-route-target", "deleteTargetKey")
147             .property("route-target-role", "deleteRoleKey")
148             .property("linked", true)
149             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey/route-targets/route-target/deleteTargetKey/deleteRoleKey")
150             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
151             .property(AAIProperties.CREATED_TS, 123)
152             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
153             .property(AAIProperties.RESOURCE_VERSION, "123")
154             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
155             .property(AAIProperties.LAST_MOD_TS, 333)
156             .as("v5")
157             .addE("org.onap.relationships.inventory.BelongsTo").to("v4").from("v5")
158             .property(EdgeProperty.CONTAINS.toString(), true)
159             .addV()
160             .property("aai-node-type", "vpn-binding")
161             .property("vpn-id", "getKey")
162             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey")
163             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
164             .property(AAIProperties.CREATED_TS, 123)
165             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
166             .property(AAIProperties.RESOURCE_VERSION, "123")
167             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
168             .property(AAIProperties.LAST_MOD_TS, 333)
169             .as("v6")
170             .addV()
171             .property("aai-node-type", "route-target")
172             .property("global-route-target", "getTargetKey")
173             .property("route-target-role", "getRoleKey")
174             .property("linked", true)
175             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink")
176             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
177             .property(AAIProperties.CREATED_TS, 123)
178             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
179             .property(AAIProperties.RESOURCE_VERSION, "123")
180             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
181             .property(AAIProperties.LAST_MOD_TS, 333)
182             .as("v7")
183             .addE("org.onap.relationships.inventory.BelongsTo").to("v6").from("v7")
184             .property(EdgeProperty.CONTAINS.toString(), true)
185             .addV()
186             .property("aai-node-type", "vpn-binding")
187             .property("vpn-id", "getKeyNoLink")
188             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink")
189             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
190             .property(AAIProperties.CREATED_TS, 123)
191             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
192             .property(AAIProperties.RESOURCE_VERSION, "123")
193             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
194             .property(AAIProperties.LAST_MOD_TS, 333)
195             .as("v8")
196             .addV()
197             .property("aai-node-type", "route-target")
198             .property("global-route-target", "getTargetKeyNoLink")
199             .property("route-target-role", "getRoleKeyNoLink")
200             .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink")
201             .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
202             .property(AAIProperties.CREATED_TS, 123)
203             .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
204             .property(AAIProperties.RESOURCE_VERSION, "123")
205             .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
206             .property(AAIProperties.LAST_MOD_TS, 333)
207             .as("v9")
208             .addE("org.onap.relationships.inventory.BelongsTo").to("v8").from("v9")
209             .property(EdgeProperty.CONTAINS.toString(), true)
210                 .next();
211         graph.tx().commit();
212
213     }
214
215     @AfterClass
216     public static void tearDown() {
217         graph.tx().rollback();
218         graph.close();
219     }
220
221     @Before
222     public void initMock() {
223         loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, schemaVersions.getDefaultVersion());
224         MockitoAnnotations.initMocks(this);
225         dbEngine = new JanusGraphDBEngine(queryStyle, loader);
226     }
227
228     @Test
229     public void verifyCreationOfVertex()
230             throws AAIException, UnsupportedEncodingException, IllegalArgumentException, SecurityException {
231
232         final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
233         final Introspector obj = loader.introspectorFromName("vpn-binding");
234         obj.setValue("vpn-id", "addKey");
235         obj.setValue("global-route-target", "key1");
236         obj.setValue("route-target-role", "key2");
237         TransactionalGraphEngine spy = spy(dbEngine);
238         TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
239         Graph g = graph.newTransaction();
240         GraphTraversalSource traversal = g.traversal();
241         when(spy.asAdmin()).thenReturn(adminSpy);
242         when(adminSpy.getTraversalSource()).thenReturn(traversal);
243         when(spy.tx()).thenReturn(g);
244         when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
245         when(prop.orElse(null)).thenReturn(obj.getURI());
246         DBSerializer serializer =
247                 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
248         SideEffectRunner runner =
249                 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
250
251         runner.execute(obj, self);
252
253         assertTrue("route-target vertex found", traversal.V().has(AAIProperties.NODE_TYPE, "route-target")
254                 .has("global-route-target", "key1").has("route-target-role", "key2").has("linked", true).hasNext());
255         g.tx().rollback();
256
257     }
258
259     @Test
260     public void verifyModificationOfVertex()
261             throws AAIException, UnsupportedEncodingException, IllegalArgumentException, SecurityException {
262
263         final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
264         final Introspector obj = loader.introspectorFromName("vpn-binding");
265         obj.setValue("vpn-id", "modifyKey");
266         obj.setValue("global-route-target", "modifyTargetKey2");
267         obj.setValue("route-target-role", "modifyRoleKey2");
268         TransactionalGraphEngine spy = spy(dbEngine);
269         TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
270         Graph g = graph.newTransaction();
271         GraphTraversalSource traversal = g.traversal();
272
273         when(spy.asAdmin()).thenReturn(adminSpy);
274         when(adminSpy.getTraversalSource()).thenReturn(traversal);
275         when(spy.tx()).thenReturn(g);
276         when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
277         when(prop.orElse(null)).thenReturn(obj.getURI());
278         DBSerializer serializer =
279                 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
280         SideEffectRunner runner =
281                 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
282         runner.execute(obj, self);
283
284         assertThat("new route-target vertex found with/or without link",
285                 traversal.V()
286                         .has(AAIProperties.NODE_TYPE, "route-target")
287                         .has("global-route-target", "modifyTargetKey2")
288                         .has("route-target-role", "modifyRoleKey2")
289                         .hasNext(),
290                 is(true));
291         assertThat("new route-target vertex has link",
292                 traversal.V()
293                         .has(AAIProperties.NODE_TYPE, "route-target")
294                         .has("global-route-target", "modifyTargetKey2")
295                         .has("route-target-role", "modifyRoleKey2")
296                         .has("linked", true)
297                         .hasNext(),
298                 is(true));
299         assertThat("previous vertex still exists",
300                 traversal.V()
301                         .has(AAIProperties.NODE_TYPE, "route-target")
302                         .has("global-route-target", "modifyTargetKey")
303                         .has("route-target-role", "modifyRoleKey")
304                         .hasNext(),
305                 is(true));
306         assertThat("link of previous vert removed",
307                 traversal.V()
308                         .has(AAIProperties.NODE_TYPE, "route-target")
309                         .has("global-route-target", "modifyTargetKey")
310                         .has("route-target-role", "modifyRoleKey")
311                         .has("linked")
312                         .hasNext(),
313                 is(not(true)));
314         assertThat("previous vertex still exists",
315                 traversal.V()
316                         .has(AAIProperties.NODE_TYPE, "route-target")
317                         .has("global-route-target", "modifyTargetKey")
318                         .has("route-target-role", "modifyRoleKey")
319                         .hasNext(),
320                 is(true));
321         g.tx().rollback();
322
323     }
324
325     @Test
326     public void verifyDeleteOfVertex() throws Exception {
327
328         final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
329         final Introspector obj = loader.introspectorFromName("vpn-binding");
330         obj.setValue("vpn-id", "deleteKey");
331         TransactionalGraphEngine spy = spy(dbEngine);
332         TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
333         Graph g = graph.newTransaction();
334         GraphTraversalSource traversal = g.traversal();
335         when(spy.asAdmin()).thenReturn(adminSpy);
336         when(adminSpy.getTraversalSource()).thenReturn(traversal);
337         when(adminSpy.getReadOnlyTraversalSource()).thenReturn(traversal);
338         when(spy.tx()).thenReturn(g);
339         when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
340         when(prop.orElse(null)).thenReturn(obj.getURI());
341         DBSerializer serializer =
342                 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
343         SideEffectRunner runner =
344                 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
345
346         runner.execute(obj, self);
347
348         assertFalse("route-target vertex not found",
349             traversal.V()
350                 .has(AAIProperties.NODE_TYPE, "route-target")
351                 .has("global-route-target", "deleteTargetKey")
352                 .has("route-target-role", "deleteRoleKey")
353                 .has("linked", true)
354                 .hasNext());
355
356         g.tx().rollback();
357     }
358
359     @Test
360     public void verifyPropertyPopulation() throws Exception {
361
362         final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
363         final Introspector obj = loader.introspectorFromName("vpn-binding");
364         obj.setValue("vpn-id", "getKey");
365         TransactionalGraphEngine spy = spy(dbEngine);
366         TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
367         Graph g = graph.newTransaction();
368         GraphTraversalSource traversal = g.traversal();
369         when(spy.asAdmin()).thenReturn(adminSpy);
370         when(adminSpy.getTraversalSource()).thenReturn(traversal);
371         when(spy.tx()).thenReturn(g);
372         when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
373         when(prop.orElse(null)).thenReturn(obj.getURI());
374         DBSerializer serializer =
375                 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
376         SideEffectRunner runner =
377                 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkReader.class).build();
378
379         runner.execute(obj, self);
380
381         assertTrue("both properties have been populated in target object",
382                 obj.getValue("global-route-target").equals("getTargetKey")
383                         && obj.getValue("route-target-role").equals("getRoleKey"));
384         g.tx().rollback();
385     }
386
387     @Test
388     public void verifyPropertyPopulationWithV10OnlyPut()
389             throws AAIException, UnsupportedEncodingException, IllegalArgumentException, SecurityException {
390         final Introspector obj = loader.introspectorFromName("vpn-binding");
391         obj.setValue("vpn-id", "getKeyNoLink");
392         final Introspector routeTargets = loader.introspectorFromName("route-targets");
393         obj.setValue("route-targets", routeTargets.getUnderlyingObject());
394         List<Object> targets = routeTargets.getValue("route-target");
395         final Introspector routeTargetOne = loader.introspectorFromName("route-target");
396         routeTargetOne.setValue("global-route-target", "getTargetKeyNoLink");
397         routeTargetOne.setValue("route-target-role", "getRoleKeyNoLink");
398         targets.add(routeTargetOne.getUnderlyingObject());
399         final Introspector routeTargetTwo = loader.introspectorFromName("route-target");
400         routeTargetTwo.setValue("global-route-target", "getTargetKeyNoLink2");
401         routeTargetTwo.setValue("route-target-role", "getRoleKeyNoLink2");
402         targets.add(routeTargetTwo.getUnderlyingObject());
403         TransactionalGraphEngine spy = spy(dbEngine);
404         TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
405         Graph g = graph.newTransaction();
406         GraphTraversalSource traversal = g.traversal();
407         when(spy.tx()).thenReturn(g);
408         when(spy.asAdmin()).thenReturn(adminSpy);
409         when(adminSpy.getTraversalSource()).thenReturn(traversal);
410         when(spy.tx()).thenReturn(g);
411         when(parser.isDependent()).thenReturn(false);
412         when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
413         when(prop.orElse(null)).thenReturn(obj.getURI());
414         DBSerializer serializer =
415                 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
416         Vertex v = serializer.createNewVertex(obj);
417         serializer.serializeToDb(obj, v, parser, obj.getURI(), "testing");
418         Vertex routeTargetOneV = traversal.V().has("global-route-target", "getTargetKeyNoLink").next();
419         Vertex routeTargetTwoV = traversal.V().has("global-route-target", "getTargetKeyNoLink2").next();
420
421         assertEquals("first route target put has linked", true,
422                 routeTargetOneV.property(AAIProperties.LINKED).orElse(false));
423         assertEquals("second route target put does not have linked", false,
424                 routeTargetTwoV.property(AAIProperties.LINKED).orElse(false));
425
426         g.tx().rollback();
427     }
428 }