2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017 Amdocs
7 * ===================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END============================================
20 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 package org.onap.aai.champtitan.core;
24 import static org.junit.Assert.assertFalse;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
28 import java.util.Optional;
29 import java.util.concurrent.CountDownLatch;
31 import org.junit.Before;
32 import org.junit.Test;
33 import org.onap.aai.champcore.ChampTransaction;
34 import org.onap.aai.champcore.exceptions.ChampMarshallingException;
35 import org.onap.aai.champcore.exceptions.ChampObjectNotExistsException;
36 import org.onap.aai.champcore.exceptions.ChampRelationshipNotExistsException;
37 import org.onap.aai.champcore.exceptions.ChampSchemaViolationException;
38 import org.onap.aai.champcore.exceptions.ChampTransactionException;
39 import org.onap.aai.champcore.exceptions.ChampUnmarshallingException;
40 import org.onap.aai.champcore.model.ChampObject;
41 import org.onap.aai.champcore.model.ChampRelationship;
42 import org.onap.aai.champtitan.graph.impl.TitanChampGraphImpl;
44 public class ChampTransactionTest {
46 public TitanChampGraphImpl graph = null;
47 public CountDownLatch latch = new CountDownLatch(2);
48 public ChampObject[] storedVertices = new ChampObject[2];
53 graph = new TitanChampGraphImpl.Builder("TransactionTestGraph")
54 .property("storage.backend", "inmemory")
60 * This test validates that multiple CRUD operations can be performed against vertices within
61 * the same transactional context and that, once the transaction is committed, the final
62 * state of the vertices reflects the sum of all of the operations performed within the
65 * @throws ChampMarshallingException
66 * @throws ChampSchemaViolationException
67 * @throws ChampObjectNotExistsException
68 * @throws ChampUnmarshallingException
69 * @throws ChampTransactionException
72 public void champObjectSingleTxTest() throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampUnmarshallingException, ChampTransactionException {
74 ChampObject v1 = ChampObject.create()
77 .withProperty("property1", "value1")
78 .withProperty("property2", "value2")
81 ChampObject v2 = ChampObject.create()
84 .withProperty("property3", "value3")
85 .withProperty("property4", "value4")
88 ChampObject v3 = ChampObject.create()
91 .withProperty("property5", "value5")
92 .withProperty("property6", "value6")
95 ChampObject v4 = ChampObject.create()
98 .withProperty("property7", "value7")
99 .withProperty("property8", "value8")
103 // Open a transaction with the graph data store.
104 ChampTransaction tx = graph.openTransaction();
106 // Create all of our vertices.
107 ChampObject storedV1 = graph.storeObject(v1, Optional.of(tx));
108 ChampObject storedV2 = graph.storeObject(v2, Optional.of(tx));
109 ChampObject storedV3 = graph.storeObject(v3, Optional.of(tx));
110 ChampObject storedV4 = graph.storeObject(v4, Optional.of(tx));
112 // Now, within the same transactional context, do a replacement against one of the
113 // vertices that we just created.
114 ChampObject replacedV2 = graph.replaceObject(ChampObject.create()
116 .withKey(storedV2.getKey().get())
117 .withProperty("replacedProperty3", "replacedValue3")
118 .withProperty("replacedProperty4", "replacedValue4")
122 // Within the same transactional context, do an update against one of the vertices
123 // that we just created.
124 final ChampObject updatedV3 = graph.storeObject(ChampObject.create()
126 .withKey(storedV3.getKey().get())
127 .withProperty("updatedProperty", "updatedValue")
128 .build(), Optional.of(tx));
130 // Within the same transactional context, delete one of the vertices that we just
132 graph.deleteObject(storedV4.getKey().get(), Optional.of(tx));
134 // Finally, commit our transaction.
137 tx = graph.openTransaction();
139 Optional<ChampObject> retrievedV1 = graph.retrieveObject(storedV1.getKey().get(), Optional.of(tx));
140 assertTrue(retrievedV1.isPresent());
141 assertTrue(retrievedV1.get().getProperty("property1").get().equals("value1"));
142 assertTrue(retrievedV1.get().getProperty("property2").get().equals("value2"));
145 Optional<ChampObject> retrievedV2 = graph.retrieveObject(storedV2.getKey().get(), Optional.of(tx));
146 assertTrue(retrievedV2.isPresent());
147 assertTrue(retrievedV2.get().getProperty("replacedProperty3").get().equals("replacedValue3"));
148 assertTrue(retrievedV2.get().getProperty("replacedProperty4").get().equals("replacedValue4"));
149 assertFalse(retrievedV2.get().getProperty("value3").isPresent());
150 assertFalse(retrievedV2.get().getProperty("value4").isPresent());
152 Optional<ChampObject> retrievedV3 = graph.retrieveObject(storedV3.getKey().get(), Optional.of(tx));
153 assertTrue(retrievedV3.isPresent());
154 assertTrue(retrievedV3.get().getProperty("property5").get().equals("value5"));
155 assertTrue(retrievedV3.get().getProperty("property6").get().equals("value6"));
156 assertTrue(retrievedV3.get().getProperty("updatedProperty").get().equals("updatedValue"));
159 Optional<ChampObject> retrievedV4 = graph.retrieveObject(storedV4.getKey().get(), Optional.of(tx));
160 assertFalse("Deleted vertex should not be present in graph", retrievedV4.isPresent());
167 * This test validates that multiple threads can each open their own transactions with the
168 * graph data store, and that there is no leakage between each thread's transactions.
170 * @throws ChampMarshallingException
171 * @throws ChampSchemaViolationException
172 * @throws ChampObjectNotExistsException
173 * @throws ChampUnmarshallingException
174 * @throws ChampTransactionException
177 public void multipleTransactionTest() throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampUnmarshallingException, ChampTransactionException {
179 ChampObject v1 = ChampObject.create()
182 .withProperty("property1", "value1")
183 .withProperty("property2", "value2")
186 ChampObject v2 = ChampObject.create()
189 .withProperty("property3", "value3")
190 .withProperty("property4", "value4")
193 // Instantiate and start our two transactional worker threads...
194 Thread thread1 = new Thread(new VertexWriter(v1, 0));
195 Thread thread2 = new Thread(new VertexWriter(v2, 1));
199 // and wait for the threads to complete.
204 } catch (InterruptedException e) { }
206 // Now that all of our data has been committed, let's open a new transaction
207 // and verify that all of our vertices can be retrieved.
208 ChampTransaction tx3 = graph.openTransaction();
210 Optional<ChampObject> retrievedV1 = graph.retrieveObject(storedVertices[0].getKey().get(), Optional.of(tx3));
211 assertTrue(retrievedV1.isPresent());
212 Optional<ChampObject> retrievedV2 = graph.retrieveObject(storedVertices[1].getKey().get(), Optional.of(tx3));
213 assertTrue(retrievedV2.isPresent());
220 * This method validates that edges can be successfully created within a single transaction.
222 * @throws ChampMarshallingException
223 * @throws ChampSchemaViolationException
224 * @throws ChampObjectNotExistsException
225 * @throws ChampUnmarshallingException
226 * @throws ChampRelationshipNotExistsException
227 * @throws ChampTransactionException
230 public void edgeTest() throws ChampMarshallingException, ChampSchemaViolationException, ChampObjectNotExistsException, ChampUnmarshallingException, ChampRelationshipNotExistsException, ChampTransactionException {
232 // Create the source and target vertices for our edge.
233 final ChampObject source = ChampObject.create()
236 .withProperty("property1", "value1")
239 final ChampObject target = ChampObject.create()
244 // Open a transaction with the graph data store.
245 ChampTransaction tx = graph.openTransaction();
247 // Now, create our vertices.
248 ChampObject storedSource = graph.storeObject(source, Optional.of(tx));
249 ChampObject storedTarget = graph.storeObject(target, Optional.of(tx));
251 // Create the edge between the vertices.
252 ChampRelationship relationship = new ChampRelationship.Builder(storedSource, storedTarget, "relationship")
253 .property("property-1", "value-1")
254 .property("property-2", 3)
256 ChampRelationship storedRelationship = graph.storeRelationship(relationship, Optional.of(tx));
258 // Validate that we can read back the edge within the transactional context.
259 Optional<ChampRelationship> retrievedRelationship = graph.retrieveRelationship(storedRelationship.getKey().get(), Optional.of(tx));
260 assertTrue("Failed to retrieve stored relationship", retrievedRelationship.isPresent());
262 // Commit our transaction.
263 graph.commitTransaction(tx);
265 // Now, open a new transaction.
266 tx = graph.openTransaction();
268 // Now, read back the edge that we just created again, validating that it was
269 // successfully committed to the graph.
270 retrievedRelationship = graph.retrieveRelationship(storedRelationship.getKey().get(), Optional.of(tx));
271 assertTrue("Failed to retrieve stored relationship", retrievedRelationship.isPresent());
273 graph.commitTransaction(tx);
276 private class VertexWriter implements Runnable {
281 public VertexWriter(ChampObject vertex, int index) {
282 this.vertex = vertex;
288 ChampTransaction tx=null;
291 // Open a threaded transaction to do some work in.
292 tx = graph.openTransaction();
294 // Now store one of our two vertices within the context of this transaction.
295 storedVertices[index] = graph.storeObject(vertex, Optional.of(tx));
297 // Use our latch to indicate that we are done creating vertices, and wait for
298 // the other thread to do the same.
302 // Validate that the vertex we created is visible to us in the graph, but the
303 // one that the other thread created is not.
304 Optional<ChampObject> retrievedV2 = graph.retrieveObject(storedVertices[index].getKey().get(), Optional.of(tx));
305 assertTrue(retrievedV2.isPresent());
306 Optional<ChampObject> retrievedV1 = graph.retrieveObject(storedVertices[(index+1)%2].getKey().get(), Optional.of(tx));
307 assertFalse(retrievedV1.isPresent());
309 } catch (InterruptedException |
310 ChampUnmarshallingException |
311 ChampMarshallingException |
312 ChampSchemaViolationException |
313 ChampObjectNotExistsException | ChampTransactionException e) {
315 fail("Thread failed to interact with graph due to " + e.getMessage());
320 Thread.sleep(index * 500);
321 } catch (InterruptedException e) {
322 // TODO Auto-generated catch block
325 // Now, commit our transaction and bail...
327 graph.commitTransaction(tx);
328 } catch (ChampTransactionException e) {