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