2 * ============LICENSE_START=======================================================
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
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.onap.aai.introspection.sideeffect;
23 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
24 import org.apache.tinkerpop.gremlin.structure.Graph;
25 import org.apache.tinkerpop.gremlin.structure.Vertex;
26 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
27 import org.janusgraph.core.Cardinality;
28 import org.janusgraph.core.JanusGraph;
29 import org.janusgraph.core.JanusGraphFactory;
30 import org.janusgraph.core.schema.JanusGraphManagement;
32 import org.junit.rules.ExpectedException;
33 import org.junit.runner.RunWith;
34 import org.junit.runners.Parameterized;
35 import org.mockito.Mock;
36 import org.mockito.MockitoAnnotations;
37 import org.onap.aai.DataLinkSetup;
38 import org.onap.aai.db.props.AAIProperties;
39 import org.onap.aai.edges.enums.EdgeProperty;
40 import org.onap.aai.exceptions.AAIException;
41 import org.onap.aai.introspection.Introspector;
42 import org.onap.aai.introspection.Loader;
43 import org.onap.aai.introspection.ModelType;
44 import org.onap.aai.parsers.query.QueryParser;
45 import org.onap.aai.serialization.db.DBSerializer;
46 import org.onap.aai.serialization.engines.JanusGraphDBEngine;
47 import org.onap.aai.serialization.engines.QueryStyle;
48 import org.onap.aai.serialization.engines.TransactionalGraphEngine;
50 import java.io.UnsupportedEncodingException;
51 import java.util.Arrays;
52 import java.util.Collection;
53 import java.util.List;
54 import java.util.UUID;
56 import static org.hamcrest.MatcherAssert.assertThat;
57 import static org.hamcrest.Matchers.is;
58 import static org.hamcrest.Matchers.not;
59 import static org.junit.Assert.*;
60 import static org.mockito.Mockito.spy;
61 import static org.mockito.Mockito.when;
63 @RunWith(value = Parameterized.class)
64 public class DataLinkTest extends DataLinkSetup {
66 private static JanusGraph graph;
67 private final static ModelType introspectorFactoryType = ModelType.MOXY;
68 private static Loader loader;
69 private static TransactionalGraphEngine dbEngine;
71 private QueryParser parser;
75 private VertexProperty<String> prop;
77 public ExpectedException thrown = ExpectedException.none();
79 @Parameterized.Parameter
80 public QueryStyle queryStyle;
82 @Parameterized.Parameters(name = "QueryStyle.{0}")
83 public static Collection<Object[]> data() {
84 return Arrays.asList(new Object[][] {{QueryStyle.TRAVERSAL}, {QueryStyle.TRAVERSAL_URI}});
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)
93 graphMgt.makePropertyKey(AAIProperties.LAST_MOD_TS).dataType(Long.class).cardinality(Cardinality.SINGLE)
99 .property("aai-node-type", "vpn-binding")
100 .property("vpn-id", "addKey")
101 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/addKey")
102 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
103 .property(AAIProperties.CREATED_TS, 123)
104 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
105 .property(AAIProperties.RESOURCE_VERSION, "123")
106 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
107 .property(AAIProperties.LAST_MOD_TS, 333)
110 .property("aai-node-type", "vpn-binding")
111 .property("vpn-id", "modifyKey")
112 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey")
113 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
114 .property(AAIProperties.CREATED_TS, 123)
115 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
116 .property(AAIProperties.RESOURCE_VERSION, "123")
117 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
118 .property(AAIProperties.LAST_MOD_TS, 333)
121 .property("aai-node-type", "route-target")
122 .property("global-route-target", "modifyTargetKey")
123 .property("route-target-role", "modifyRoleKey")
124 .property("linked", true)
125 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/modifyKey/route-targets/route-target/modifyTargetKey/modifyRoleKey")
126 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
127 .property(AAIProperties.CREATED_TS, 123)
128 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
129 .property(AAIProperties.RESOURCE_VERSION, "123")
130 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
131 .property(AAIProperties.LAST_MOD_TS, 333)
133 .addE("org.onap.relationships.inventory.BelongsTo").to("v2").from("v3")
134 .property(EdgeProperty.CONTAINS.toString(), true)
136 .property("aai-node-type", "vpn-binding")
137 .property("vpn-id", "deleteKey")
138 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey")
139 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
140 .property(AAIProperties.CREATED_TS, 123)
141 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
142 .property(AAIProperties.RESOURCE_VERSION, "123")
143 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
144 .property(AAIProperties.LAST_MOD_TS, 333)
147 .property("aai-node-type", "route-target")
148 .property("global-route-target", "deleteTargetKey")
149 .property("route-target-role", "deleteRoleKey")
150 .property("linked", true)
151 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/deleteKey/route-targets/route-target/deleteTargetKey/deleteRoleKey")
152 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
153 .property(AAIProperties.CREATED_TS, 123)
154 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
155 .property(AAIProperties.RESOURCE_VERSION, "123")
156 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
157 .property(AAIProperties.LAST_MOD_TS, 333)
159 .addE("org.onap.relationships.inventory.BelongsTo").to("v4").from("v5")
160 .property(EdgeProperty.CONTAINS.toString(), true)
162 .property("aai-node-type", "vpn-binding")
163 .property("vpn-id", "getKey")
164 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey")
165 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
166 .property(AAIProperties.CREATED_TS, 123)
167 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
168 .property(AAIProperties.RESOURCE_VERSION, "123")
169 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
170 .property(AAIProperties.LAST_MOD_TS, 333)
173 .property("aai-node-type", "route-target")
174 .property("global-route-target", "getTargetKey")
175 .property("route-target-role", "getRoleKey")
176 .property("linked", true)
177 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKey/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink")
178 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
179 .property(AAIProperties.CREATED_TS, 123)
180 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
181 .property(AAIProperties.RESOURCE_VERSION, "123")
182 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
183 .property(AAIProperties.LAST_MOD_TS, 333)
185 .addE("org.onap.relationships.inventory.BelongsTo").to("v6").from("v7")
186 .property(EdgeProperty.CONTAINS.toString(), true)
188 .property("aai-node-type", "vpn-binding")
189 .property("vpn-id", "getKeyNoLink")
190 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink")
191 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
192 .property(AAIProperties.CREATED_TS, 123)
193 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
194 .property(AAIProperties.RESOURCE_VERSION, "123")
195 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
196 .property(AAIProperties.LAST_MOD_TS, 333)
199 .property("aai-node-type", "route-target")
200 .property("global-route-target", "getTargetKeyNoLink")
201 .property("route-target-role", "getRoleKeyNoLink")
202 .property(AAIProperties.AAI_URI, "/network/vpn-bindings/vpn-binding/getKeyNoLink/route-targets/route-target/getTargetKeyNoLink/getRoleKeyNoLink")
203 .property(AAIProperties.AAI_UUID, UUID.randomUUID().toString())
204 .property(AAIProperties.CREATED_TS, 123)
205 .property(AAIProperties.SOURCE_OF_TRUTH, "sot")
206 .property(AAIProperties.RESOURCE_VERSION, "123")
207 .property(AAIProperties.LAST_MOD_SOURCE_OF_TRUTH, "lmsot")
208 .property(AAIProperties.LAST_MOD_TS, 333)
210 .addE("org.onap.relationships.inventory.BelongsTo").to("v8").from("v9")
211 .property(EdgeProperty.CONTAINS.toString(), true)
218 public static void tearDown() {
219 graph.tx().rollback();
224 public void initMock() {
225 loader = loaderFactory.createLoaderForVersion(introspectorFactoryType, schemaVersions.getDefaultVersion());
226 MockitoAnnotations.initMocks(this);
227 dbEngine = new JanusGraphDBEngine(queryStyle, loader);
231 public void verifyCreationOfVertex() throws AAIException, UnsupportedEncodingException,
232 IllegalArgumentException, SecurityException {
234 final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
235 final Introspector obj = loader.introspectorFromName("vpn-binding");
236 obj.setValue("vpn-id", "addKey");
237 obj.setValue("global-route-target", "key1");
238 obj.setValue("route-target-role", "key2");
239 TransactionalGraphEngine spy = spy(dbEngine);
240 TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
241 Graph g = graph.newTransaction();
242 GraphTraversalSource traversal = g.traversal();
243 when(spy.asAdmin()).thenReturn(adminSpy);
244 when(adminSpy.getTraversalSource()).thenReturn(traversal);
245 when(spy.tx()).thenReturn(g);
246 when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
247 when(prop.orElse(null)).thenReturn(obj.getURI());
248 DBSerializer serializer =
249 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
250 SideEffectRunner runner =
251 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
253 runner.execute(obj, self);
255 assertTrue("route-target vertex found", traversal.V().has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "key1").has("route-target-role", "key2").has("linked", true).hasNext());
261 public void verifyModificationOfVertex() throws AAIException, UnsupportedEncodingException,
262 IllegalArgumentException, SecurityException {
264 final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
265 final Introspector obj = loader.introspectorFromName("vpn-binding");
266 obj.setValue("vpn-id", "modifyKey");
267 obj.setValue("global-route-target", "modifyTargetKey2");
268 obj.setValue("route-target-role", "modifyRoleKey2");
269 TransactionalGraphEngine spy = spy(dbEngine);
270 TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
271 Graph g = graph.newTransaction();
272 GraphTraversalSource traversal = g.traversal();
274 when(spy.asAdmin()).thenReturn(adminSpy);
275 when(adminSpy.getTraversalSource()).thenReturn(traversal);
276 when(spy.tx()).thenReturn(g);
277 when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
278 when(prop.orElse(null)).thenReturn(obj.getURI());
279 DBSerializer serializer =
280 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
281 SideEffectRunner runner =
282 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
283 runner.execute(obj, self);
285 assertThat("new route-target vertex found with/or without link",
286 traversal.V().has(AAIProperties.NODE_TYPE, "route-target")
287 .has("global-route-target", "modifyTargetKey2").has("route-target-role", "modifyRoleKey2")
290 assertThat("new route-target vertex found",
291 traversal.V().has(AAIProperties.NODE_TYPE, "route-target")
292 .has("global-route-target", "modifyTargetKey2").has("route-target-role", "modifyRoleKey2")
293 .has("linked", true).hasNext(),
295 assertThat("previous link removed",
296 traversal.V().has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "modifyTargetKey")
297 .has("route-target-role", "modifyRoleKey").has("linked").hasNext(),
299 assertThat("previous vertex still exists", traversal.V().has(AAIProperties.NODE_TYPE, "route-target")
300 .has("global-route-target", "modifyTargetKey").has("route-target-role", "modifyRoleKey").hasNext(),
307 public void verifyDeleteOfVertex() throws Exception {
309 final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
310 final Introspector obj = loader.introspectorFromName("vpn-binding");
311 obj.setValue("vpn-id", "deleteKey");
312 TransactionalGraphEngine spy = spy(dbEngine);
313 TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
314 Graph g = graph.newTransaction();
315 GraphTraversalSource traversal = g.traversal();
316 when(spy.asAdmin()).thenReturn(adminSpy);
317 when(adminSpy.getTraversalSource()).thenReturn(traversal);
318 when(adminSpy.getReadOnlyTraversalSource()).thenReturn(traversal);
319 when(spy.tx()).thenReturn(g);
320 when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
321 when(prop.orElse(null)).thenReturn(obj.getURI());
322 DBSerializer serializer =
323 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
324 SideEffectRunner runner =
325 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkWriter.class).build();
327 runner.execute(obj, self);
329 assertFalse("route-target vertex not found", traversal.V().has(AAIProperties.NODE_TYPE, "route-target").has("global-route-target", "deleteTargetKey").has("route-target-role", "deleteRoleKey").has("linked", true).hasNext());
336 public void verifyPropertyPopulation() throws Exception {
338 final Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDepthVersion());
339 final Introspector obj = loader.introspectorFromName("vpn-binding");
340 obj.setValue("vpn-id", "getKey");
341 TransactionalGraphEngine spy = spy(dbEngine);
342 TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
343 Graph g = graph.newTransaction();
344 GraphTraversalSource traversal = g.traversal();
345 when(spy.asAdmin()).thenReturn(adminSpy);
346 when(adminSpy.getTraversalSource()).thenReturn(traversal);
347 when(spy.tx()).thenReturn(g);
348 when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
349 when(prop.orElse(null)).thenReturn(obj.getURI());
350 DBSerializer serializer =
351 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
352 SideEffectRunner runner =
353 new SideEffectRunner.Builder(spy, serializer).addSideEffect(DataLinkReader.class).build();
355 runner.execute(obj, self);
357 assertTrue("both properties have been populated in target object", obj.getValue("global-route-target").equals("getTargetKey") && obj.getValue("route-target-role").equals("getRoleKey"));
363 public void verifyPropertyPopulationWithV10OnlyPut() throws AAIException,
364 UnsupportedEncodingException, IllegalArgumentException, SecurityException {
365 final Introspector obj = loader.introspectorFromName("vpn-binding");
366 obj.setValue("vpn-id", "getKeyNoLink");
367 final Introspector routeTargets = loader.introspectorFromName("route-targets");
368 obj.setValue("route-targets", routeTargets.getUnderlyingObject());
369 List<Object> targets = routeTargets.getValue("route-target");
370 final Introspector routeTargetOne = loader.introspectorFromName("route-target");
371 routeTargetOne.setValue("global-route-target", "getTargetKeyNoLink");
372 routeTargetOne.setValue("route-target-role", "getRoleKeyNoLink");
373 targets.add(routeTargetOne.getUnderlyingObject());
374 final Introspector routeTargetTwo = loader.introspectorFromName("route-target");
375 routeTargetTwo.setValue("global-route-target", "getTargetKeyNoLink2");
376 routeTargetTwo.setValue("route-target-role", "getRoleKeyNoLink2");
377 targets.add(routeTargetTwo.getUnderlyingObject());
378 TransactionalGraphEngine spy = spy(dbEngine);
379 TransactionalGraphEngine.Admin adminSpy = spy(dbEngine.asAdmin());
380 Graph g = graph.newTransaction();
381 GraphTraversalSource traversal = g.traversal();
382 when(spy.tx()).thenReturn(g);
383 when(spy.asAdmin()).thenReturn(adminSpy);
384 when(adminSpy.getTraversalSource()).thenReturn(traversal);
385 when(spy.tx()).thenReturn(g);
386 when(parser.isDependent()).thenReturn(false);
387 when(self.<String>property(AAIProperties.AAI_URI)).thenReturn(prop);
388 when(prop.orElse(null)).thenReturn(obj.getURI());
389 DBSerializer serializer =
390 new DBSerializer(schemaVersions.getDefaultVersion(), spy, introspectorFactoryType, "AAI_TEST");
391 Vertex v = serializer.createNewVertex(obj);
392 serializer.serializeToDb(obj, v, parser, obj.getURI(), "testing");
393 Vertex routeTargetOneV = traversal.V().has("global-route-target", "getTargetKeyNoLink").next();
394 Vertex routeTargetTwoV = traversal.V().has("global-route-target", "getTargetKeyNoLink2").next();
396 assertEquals("first route target put has linked", true,
397 routeTargetOneV.property(AAIProperties.LINKED).orElse(false));
398 assertEquals("second route target put does not have linked", false,
399 routeTargetTwoV.property(AAIProperties.LINKED).orElse(false));