30f033c8118247a18107007ed7ae849cfc6ed881
[aai/champ.git] / champ-lib / champ-core / src / test / java / org / onap / aai / champcore / core / ChampTransactionTest.java
1 /**
2  * ============LICENSE_START==========================================
3  * org.onap.aai
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
11  *
12  *        http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
21  */
22 package org.onap.aai.champcore.core;
23
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27
28 import java.util.*;
29 import java.util.function.Consumer;
30 import java.util.function.Function;
31 import java.util.stream.Stream;
32
33 import org.apache.commons.configuration.Configuration;
34 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
35 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
36 import org.apache.tinkerpop.gremlin.structure.Edge;
37 import org.apache.tinkerpop.gremlin.structure.Graph;
38 import org.apache.tinkerpop.gremlin.structure.Transaction;
39 import org.apache.tinkerpop.gremlin.structure.Vertex;
40 import org.apache.tinkerpop.gremlin.structure.util.FeatureDescriptor;
41 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.onap.aai.champcore.ChampAPI;
45 import org.onap.aai.champcore.ChampCapabilities;
46 import org.onap.aai.champcore.ChampGraph;
47 import org.onap.aai.champcore.ChampTransaction;
48 import org.onap.aai.champcore.NoOpTinkerPopTransaction;
49 import org.onap.aai.champcore.exceptions.ChampIndexNotExistsException;
50 import org.onap.aai.champcore.exceptions.ChampTransactionException;
51 import org.onap.aai.champcore.graph.impl.AbstractTinkerpopChampGraph;
52 import org.onap.aai.champcore.graph.impl.TinkerpopTransaction;
53 import org.onap.aai.champcore.model.ChampObjectIndex;
54 import org.onap.aai.champcore.model.ChampRelationshipIndex;
55 import org.onap.aai.champcore.schema.ChampSchemaEnforcer;
56
57
58 public class ChampTransactionTest {
59   
60   TestGraph g = null;
61   
62   @Before
63   public void setup() {
64     g = new TestGraph();
65   }
66     
67   /**
68    * This test validates the behaviour when the underlying graph implementation
69    * does not support transactions.
70    */
71   @Test
72   public void testNoTransactionSupport() {
73     
74     // By default our test graph should be configured to support transactions, but
75     // set it explicitly anyway just to be sure.
76     g.setTransactionSupport(true);
77     
78     // Now, try to start a new transaction against our graph - it should succeed.
79     TinkerpopTransaction t = new TinkerpopTransaction(g);
80     Graph gi = t.getGraphInstance(); // GDF: Making jacoco happy...
81     
82     // Now, configure our graph to specify that transactions are NOT supported.
83     g.setTransactionSupport(false);
84     
85     try {
86       
87       // Now, try to start a new transaction against our graph.
88       t = new TinkerpopTransaction(g);
89       
90     } catch (UnsupportedOperationException e) {
91       
92       // If we're here, it's all good since we expected an exception to be thrown (since our
93       // graph does NOT support transactions).
94       return;
95     }
96
97     // If we're here then we were able to open a transaction even though our graph does 
98     // not support that functionality.
99     fail("Attempt to open a transaction against a graph with no transaction support should not succeed.");
100   }
101   
102   
103   /**
104    * This test validates the behaviour when committing a transaction under various
105    * circumstances.
106    * @throws ChampTransactionException 
107    */
108   @Test
109   public void testCommit() throws ChampTransactionException {
110     
111     // By default our test graph should simulate successful commits, but set
112     // the configuration anyway, just to be sure.
113     g.setFailCommits(false);
114     
115     // Now, start a transaction.
116     TinkerpopTransaction t = new TinkerpopTransaction(g);
117     
118     // Call commit against the transaction - it should complete successfully.
119     t.commit();
120     
121     // Now, configure our test graph to simulate failing to commit.
122     g.setFailCommits(true);
123     
124     // Open another transaction...
125     t = new TinkerpopTransaction(g);
126     boolean exceptionThrown = false;
127     try {
128       
129       //...and try to commit it.
130       t.commit();
131       
132     } catch (Throwable e) {
133       
134       // Our commit should have failed and ultimately thrown an exception - so if we
135       // are here then it's all good.
136       exceptionThrown = true;
137     }
138     
139     assertTrue("Failed commit should have produced an exception.", exceptionThrown);
140   }
141
142   
143   @Test
144   public void testRollback() throws ChampTransactionException {
145     
146     // By default our test graph should simulate successful commits, but set
147     // the configuration anyway, just to be sure.
148     g.setFailCommits(false);
149     
150     // Now, start a transaction.
151     TinkerpopTransaction t = new TinkerpopTransaction(g);
152     
153     // Call rollback against the transaction - it should complete successfully.
154     t.rollback();
155     
156     // Now, configure our test graph to simulate failing to commit.
157     g.setFailCommits(true);
158     
159     // Open another transaction...
160     t = new TinkerpopTransaction(g);
161     boolean exceptionThrown = false;
162     try {
163       
164       //...and try to commit it.
165       t.rollback();
166       
167     } catch (Throwable e) {
168       
169       // Our commit should have failed and ultimately thrown an exception - so if we
170       // are here then it's all good.
171       exceptionThrown = true;
172     }
173     
174     assertTrue("Failed rollback should have produced an exception.", exceptionThrown);
175   }
176
177   @Test
178   public void test() throws ChampTransactionException {
179     
180     AbstractTinkerpopChampGraph graph = new AbstractTinkerpopChampGraph(new HashMap<String, Object>()) { 
181       
182       @Override
183       protected Graph getGraph() {
184         return TinkerGraph.open();
185       }
186
187       @Override
188       protected ChampSchemaEnforcer getSchemaEnforcer() {
189         return null;
190       }
191
192       @Override
193       public void executeStoreObjectIndex(ChampObjectIndex index) { }
194
195       @Override
196       public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
197         return null;
198       }
199
200       @Override
201       public Stream<ChampObjectIndex> retrieveObjectIndices() {
202         return null;
203       }
204
205       @Override
206       public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {}
207
208       @Override
209       public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {}
210
211       @Override
212       public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
213         return null;
214       }
215
216       @Override
217       public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
218         return null;
219       }
220
221       @Override
222       public void executeDeleteRelationshipIndex(String indexName) throws ChampIndexNotExistsException {}
223
224       @Override
225       public ChampCapabilities capabilities() {
226         return null;
227       }
228
229         @Override
230         public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
231                 // TODO Auto-generated method stub
232                 return null;
233         }
234     };
235     
236     TinkerpopTransaction t = new TinkerpopTransaction(g);
237     t.id();
238     graph.commitTransaction(t);
239     graph.rollbackTransaction(t);
240     
241   }
242   
243   private class TestGraph implements Graph {
244
245     private boolean supportsTransactions = true;
246     private boolean failCommits = false;
247     
248     
249     public void setTransactionSupport(boolean supportsTransactions) {
250       this.supportsTransactions = supportsTransactions;
251     }
252     
253     public void setFailCommits(boolean failCommits) {
254       this.failCommits = failCommits;
255     }
256     @Override
257     public Vertex addVertex(Object... keyValues) {
258       // TODO Auto-generated method stub
259       return null;
260     }
261
262     @Override
263     public void close() throws Exception {
264       // TODO Auto-generated method stub
265       
266     }
267
268     @Override
269     public GraphComputer compute() throws IllegalArgumentException {
270       // TODO Auto-generated method stub
271       return null;
272     }
273
274     @Override
275     public <C extends GraphComputer> C compute(Class<C> graphComputerClass)
276         throws IllegalArgumentException {
277       // TODO Auto-generated method stub
278       return null;
279     }
280
281     @Override
282     public Configuration configuration() {
283       // TODO Auto-generated method stub
284       return null;
285     }
286
287     @Override
288     public Iterator<Edge> edges(Object... edgeIds) {
289       // TODO Auto-generated method stub
290       return null;
291     }
292
293     @Override
294     public Transaction tx() {
295       return new TestTransaction();
296     }
297
298     @Override
299     public Variables variables() {
300       // TODO Auto-generated method stub
301       return null;
302     }
303
304     @Override
305     public Iterator<Vertex> vertices(Object... vertexIds) {
306       // TODO Auto-generated method stub
307       return null;
308     }
309     
310     /**
311      * Gets the {@link Features} exposed by the underlying {@code Graph} implementation.
312      */
313     public Features features() {
314       return new TestFeatures() {
315       };
316     }
317     
318     public class TestFeatures implements Graph.Features {
319       
320       /**
321        * Gets the features related to "graph" operation.
322        */
323       public GraphFeatures graph() {
324           return new TestGraphFeatures() {
325           };
326       }
327       
328       public class TestGraphFeatures implements Graph.Features.GraphFeatures {
329         
330         /**
331          * Determines if the {@code Graph} implementations supports transactions.
332          */
333         @FeatureDescriptor(name = FEATURE_TRANSACTIONS)
334         public boolean supportsTransactions() {
335             return supportsTransactions;
336         }
337       }
338     }
339   }
340   
341   private class TestTransaction implements Transaction {
342
343     @Override
344     public void addTransactionListener(Consumer<Status> listener) {
345       // TODO Auto-generated method stub
346       
347     }
348
349     @Override
350     public void clearTransactionListeners() {
351       // TODO Auto-generated method stub
352       
353     }
354
355     @Override
356     public void close() {
357       // TODO Auto-generated method stub
358       
359     }
360
361     @Override
362     public void commit() {
363       
364       if(g.failCommits) {
365         throw new UnsupportedOperationException();
366       } 
367     }
368
369     @Override
370     public <G extends Graph> G createThreadedTx() {
371      return (G) g;
372     }
373
374     @Override
375     public boolean isOpen() {
376       // TODO Auto-generated method stub
377       return false;
378     }
379
380     @Override
381     public Transaction onClose(Consumer<Transaction> consumer) {
382       // TODO Auto-generated method stub
383       return null;
384     }
385
386     @Override
387     public Transaction onReadWrite(Consumer<Transaction> consumer) {
388       // TODO Auto-generated method stub
389       return null;
390     }
391
392     @Override
393     public void open() {
394       // TODO Auto-generated method stub
395       
396     }
397
398     @Override
399     public void readWrite() {
400       // TODO Auto-generated method stub
401       
402     }
403
404     @Override
405     public void removeTransactionListener(Consumer<Status> listener) {
406       // TODO Auto-generated method stub
407       
408     }
409
410     @Override
411     public void rollback() {
412       if(g.failCommits) {
413         throw new UnsupportedOperationException();
414       } 
415     }
416
417     @Override
418     public <R> Workload<R> submit(Function<Graph, R> work) {
419       // TODO Auto-generated method stub
420       return null;
421     }
422     
423   }
424
425   private class TestTinkerpopGraph extends AbstractTinkerpopChampGraph {
426
427     protected TestTinkerpopGraph(Map<String, Object> properties) {
428       super(properties);
429     }
430
431     @Override
432     protected Graph getGraph() {
433       return TinkerGraph.open();
434     }
435
436     
437     @Override
438     protected ChampSchemaEnforcer getSchemaEnforcer() {
439       return null;
440     }
441
442     @Override
443     public void executeStoreObjectIndex(ChampObjectIndex index) {      
444     }
445
446     @Override
447     public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
448       // TODO Auto-generated method stub
449       return null;
450     }
451
452     @Override
453     public Stream<ChampObjectIndex> retrieveObjectIndices() {
454       // TODO Auto-generated method stub
455       return null;
456     }
457
458     @Override
459     public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
460       // TODO Auto-generated method stub
461       
462     }
463
464     @Override
465     public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
466       // TODO Auto-generated method stub
467       
468     }
469
470     @Override
471     public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
472       // TODO Auto-generated method stub
473       return null;
474     }
475
476     @Override
477     public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
478       // TODO Auto-generated method stub
479       return null;
480     }
481
482     @Override
483     public void executeDeleteRelationshipIndex(String indexName)
484         throws ChampIndexNotExistsException {
485       // TODO Auto-generated method stub
486       
487     }
488
489     @Override
490     public ChampCapabilities capabilities() {
491       // TODO Auto-generated method stub
492       return null;
493     }
494
495         @Override
496         public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
497                 // TODO Auto-generated method stub
498                 return null;
499         }
500     
501   }
502 }