2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 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============================================
21 package org.onap.aai.champcore.core;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
28 import java.util.function.Consumer;
29 import java.util.function.Function;
30 import java.util.stream.Stream;
32 import org.apache.commons.configuration.Configuration;
33 import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
34 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
35 import org.apache.tinkerpop.gremlin.structure.Edge;
36 import org.apache.tinkerpop.gremlin.structure.Graph;
37 import org.apache.tinkerpop.gremlin.structure.Transaction;
38 import org.apache.tinkerpop.gremlin.structure.Vertex;
39 import org.apache.tinkerpop.gremlin.structure.util.FeatureDescriptor;
40 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.onap.aai.champcore.ChampAPI;
44 import org.onap.aai.champcore.ChampCapabilities;
45 import org.onap.aai.champcore.ChampGraph;
46 import org.onap.aai.champcore.ChampTransaction;
47 import org.onap.aai.champcore.NoOpTinkerPopTransaction;
48 import org.onap.aai.champcore.exceptions.ChampIndexNotExistsException;
49 import org.onap.aai.champcore.exceptions.ChampTransactionException;
50 import org.onap.aai.champcore.graph.impl.AbstractTinkerpopChampGraph;
51 import org.onap.aai.champcore.graph.impl.TinkerpopTransaction;
52 import org.onap.aai.champcore.model.ChampObjectIndex;
53 import org.onap.aai.champcore.model.ChampRelationshipIndex;
54 import org.onap.aai.champcore.schema.ChampSchemaEnforcer;
57 public class ChampTransactionTest {
67 * This test validates the behaviour when the underlying graph implementation
68 * does not support transactions.
71 public void testNoTransactionSupport() {
73 // By default our test graph should be configured to support transactions, but
74 // set it explicitly anyway just to be sure.
75 g.setTransactionSupport(true);
77 // Now, try to start a new transaction against our graph - it should succeed.
78 TinkerpopTransaction t = new TinkerpopTransaction(g);
79 Graph gi = t.getGraphInstance(); // GDF: Making jacoco happy...
81 // Now, configure our graph to specify that transactions are NOT supported.
82 g.setTransactionSupport(false);
86 // Now, try to start a new transaction against our graph.
87 t = new TinkerpopTransaction(g);
89 } catch (UnsupportedOperationException e) {
91 // If we're here, it's all good since we expected an exception to be thrown (since our
92 // graph does NOT support transactions).
96 // If we're here then we were able to open a transaction even though our graph does
97 // not support that functionality.
98 fail("Attempt to open a transaction against a graph with no transaction support should not succeed.");
103 * This test validates the behaviour when committing a transaction under various
105 * @throws ChampTransactionException
108 public void testCommit() throws ChampTransactionException {
110 // By default our test graph should simulate successful commits, but set
111 // the configuration anyway, just to be sure.
112 g.setFailCommits(false);
114 // Now, start a transaction.
115 TinkerpopTransaction t = new TinkerpopTransaction(g);
117 // Call commit against the transaction - it should complete successfully.
120 // Now, configure our test graph to simulate failing to commit.
121 g.setFailCommits(true);
123 // Open another transaction...
124 t = new TinkerpopTransaction(g);
125 boolean exceptionThrown = false;
128 //...and try to commit it.
131 } catch (Throwable e) {
133 // Our commit should have failed and ultimately thrown an exception - so if we
134 // are here then it's all good.
135 exceptionThrown = true;
138 assertTrue("Failed commit should have produced an exception.", exceptionThrown);
143 public void testRollback() throws ChampTransactionException {
145 // By default our test graph should simulate successful commits, but set
146 // the configuration anyway, just to be sure.
147 g.setFailCommits(false);
149 // Now, start a transaction.
150 TinkerpopTransaction t = new TinkerpopTransaction(g);
152 // Call rollback against the transaction - it should complete successfully.
155 // Now, configure our test graph to simulate failing to commit.
156 g.setFailCommits(true);
158 // Open another transaction...
159 t = new TinkerpopTransaction(g);
160 boolean exceptionThrown = false;
163 //...and try to commit it.
166 } catch (Throwable e) {
168 // Our commit should have failed and ultimately thrown an exception - so if we
169 // are here then it's all good.
170 exceptionThrown = true;
173 assertTrue("Failed rollback should have produced an exception.", exceptionThrown);
177 public void test() throws ChampTransactionException {
179 AbstractTinkerpopChampGraph graph = new AbstractTinkerpopChampGraph(new HashMap<String, Object>()) {
182 protected Graph getGraph() {
183 return TinkerGraph.open();
187 protected ChampSchemaEnforcer getSchemaEnforcer() {
192 public void executeStoreObjectIndex(ChampObjectIndex index) { }
195 public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
200 public Stream<ChampObjectIndex> retrieveObjectIndices() {
205 public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {}
208 public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {}
211 public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
216 public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
221 public void executeDeleteRelationshipIndex(String indexName) throws ChampIndexNotExistsException {}
224 public ChampCapabilities capabilities() {
229 public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
230 // TODO Auto-generated method stub
235 TinkerpopTransaction t = new TinkerpopTransaction(g);
237 graph.commitTransaction(t);
238 graph.rollbackTransaction(t);
242 private class TestGraph implements Graph {
244 private boolean supportsTransactions = true;
245 private boolean failCommits = false;
248 public void setTransactionSupport(boolean supportsTransactions) {
249 this.supportsTransactions = supportsTransactions;
252 public void setFailCommits(boolean failCommits) {
253 this.failCommits = failCommits;
256 public Vertex addVertex(Object... keyValues) {
257 // TODO Auto-generated method stub
262 public void close() throws Exception {
263 // TODO Auto-generated method stub
268 public GraphComputer compute() throws IllegalArgumentException {
269 // TODO Auto-generated method stub
274 public <C extends GraphComputer> C compute(Class<C> graphComputerClass)
275 throws IllegalArgumentException {
276 // TODO Auto-generated method stub
281 public Configuration configuration() {
282 // TODO Auto-generated method stub
287 public Iterator<Edge> edges(Object... edgeIds) {
288 // TODO Auto-generated method stub
293 public Transaction tx() {
294 return new TestTransaction();
298 public Variables variables() {
299 // TODO Auto-generated method stub
304 public Iterator<Vertex> vertices(Object... vertexIds) {
305 // TODO Auto-generated method stub
310 * Gets the {@link Features} exposed by the underlying {@code Graph} implementation.
312 public Features features() {
313 return new TestFeatures() {
317 public class TestFeatures implements Graph.Features {
320 * Gets the features related to "graph" operation.
322 public GraphFeatures graph() {
323 return new TestGraphFeatures() {
327 public class TestGraphFeatures implements Graph.Features.GraphFeatures {
330 * Determines if the {@code Graph} implementations supports transactions.
332 @FeatureDescriptor(name = FEATURE_TRANSACTIONS)
333 public boolean supportsTransactions() {
334 return supportsTransactions;
340 private class TestTransaction implements Transaction {
343 public void addTransactionListener(Consumer<Status> listener) {
344 // TODO Auto-generated method stub
349 public void clearTransactionListeners() {
350 // TODO Auto-generated method stub
355 public void close() {
356 // TODO Auto-generated method stub
361 public void commit() {
364 throw new UnsupportedOperationException();
369 public <G extends Graph> G createThreadedTx() {
374 public boolean isOpen() {
375 // TODO Auto-generated method stub
380 public Transaction onClose(Consumer<Transaction> consumer) {
381 // TODO Auto-generated method stub
386 public Transaction onReadWrite(Consumer<Transaction> consumer) {
387 // TODO Auto-generated method stub
393 // TODO Auto-generated method stub
398 public void readWrite() {
399 // TODO Auto-generated method stub
404 public void removeTransactionListener(Consumer<Status> listener) {
405 // TODO Auto-generated method stub
410 public void rollback() {
412 throw new UnsupportedOperationException();
417 public <R> Workload<R> submit(Function<Graph, R> work) {
418 // TODO Auto-generated method stub
424 private class TestTinkerpopGraph extends AbstractTinkerpopChampGraph {
426 protected TestTinkerpopGraph(Map<String, Object> properties) {
431 protected Graph getGraph() {
432 return TinkerGraph.open();
437 protected ChampSchemaEnforcer getSchemaEnforcer() {
442 public void executeStoreObjectIndex(ChampObjectIndex index) {
446 public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
447 // TODO Auto-generated method stub
452 public Stream<ChampObjectIndex> retrieveObjectIndices() {
453 // TODO Auto-generated method stub
458 public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
459 // TODO Auto-generated method stub
464 public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
465 // TODO Auto-generated method stub
470 public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
471 // TODO Auto-generated method stub
476 public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
477 // TODO Auto-generated method stub
482 public void executeDeleteRelationshipIndex(String indexName)
483 throws ChampIndexNotExistsException {
484 // TODO Auto-generated method stub
489 public ChampCapabilities capabilities() {
490 // TODO Auto-generated method stub
495 public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
496 // TODO Auto-generated method stub