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 public void createDefaultIndexes() {
236 // TODO Auto-generated method stub
241 TinkerpopTransaction t = new TinkerpopTransaction(g);
243 graph.commitTransaction(t);
244 graph.rollbackTransaction(t);
248 private class TestGraph implements Graph {
250 private boolean supportsTransactions = true;
251 private boolean failCommits = false;
254 public void setTransactionSupport(boolean supportsTransactions) {
255 this.supportsTransactions = supportsTransactions;
258 public void setFailCommits(boolean failCommits) {
259 this.failCommits = failCommits;
262 public Vertex addVertex(Object... keyValues) {
263 // TODO Auto-generated method stub
268 public void close() throws Exception {
269 // TODO Auto-generated method stub
274 public GraphComputer compute() throws IllegalArgumentException {
275 // TODO Auto-generated method stub
280 public <C extends GraphComputer> C compute(Class<C> graphComputerClass)
281 throws IllegalArgumentException {
282 // TODO Auto-generated method stub
287 public Configuration configuration() {
288 // TODO Auto-generated method stub
293 public Iterator<Edge> edges(Object... edgeIds) {
294 // TODO Auto-generated method stub
299 public Transaction tx() {
300 return new TestTransaction();
304 public Variables variables() {
305 // TODO Auto-generated method stub
310 public Iterator<Vertex> vertices(Object... vertexIds) {
311 // TODO Auto-generated method stub
316 * Gets the {@link Features} exposed by the underlying {@code Graph} implementation.
318 public Features features() {
319 return new TestFeatures() {
323 public class TestFeatures implements Graph.Features {
326 * Gets the features related to "graph" operation.
328 public GraphFeatures graph() {
329 return new TestGraphFeatures() {
333 public class TestGraphFeatures implements Graph.Features.GraphFeatures {
336 * Determines if the {@code Graph} implementations supports transactions.
338 @FeatureDescriptor(name = FEATURE_TRANSACTIONS)
339 public boolean supportsTransactions() {
340 return supportsTransactions;
346 private class TestTransaction implements Transaction {
349 public void addTransactionListener(Consumer<Status> listener) {
350 // TODO Auto-generated method stub
355 public void clearTransactionListeners() {
356 // TODO Auto-generated method stub
361 public void close() {
362 // TODO Auto-generated method stub
367 public void commit() {
370 throw new UnsupportedOperationException();
375 public <G extends Graph> G createThreadedTx() {
380 public boolean isOpen() {
381 // TODO Auto-generated method stub
386 public Transaction onClose(Consumer<Transaction> consumer) {
387 // TODO Auto-generated method stub
392 public Transaction onReadWrite(Consumer<Transaction> consumer) {
393 // TODO Auto-generated method stub
399 // TODO Auto-generated method stub
404 public void readWrite() {
405 // TODO Auto-generated method stub
410 public void removeTransactionListener(Consumer<Status> listener) {
411 // TODO Auto-generated method stub
416 public void rollback() {
418 throw new UnsupportedOperationException();
423 public <R> Workload<R> submit(Function<Graph, R> work) {
424 // TODO Auto-generated method stub
430 private class TestTinkerpopGraph extends AbstractTinkerpopChampGraph {
432 protected TestTinkerpopGraph(Map<String, Object> properties) {
437 protected Graph getGraph() {
438 return TinkerGraph.open();
443 protected ChampSchemaEnforcer getSchemaEnforcer() {
448 public void executeStoreObjectIndex(ChampObjectIndex index) {
452 public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
453 // TODO Auto-generated method stub
458 public Stream<ChampObjectIndex> retrieveObjectIndices() {
459 // TODO Auto-generated method stub
464 public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
465 // TODO Auto-generated method stub
470 public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
471 // TODO Auto-generated method stub
476 public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
477 // TODO Auto-generated method stub
482 public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
483 // TODO Auto-generated method stub
488 public void executeDeleteRelationshipIndex(String indexName)
489 throws ChampIndexNotExistsException {
490 // TODO Auto-generated method stub
495 public ChampCapabilities capabilities() {
496 // TODO Auto-generated method stub
501 public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
502 // TODO Auto-generated method stub
507 public void createDefaultIndexes() {
508 // TODO Auto-generated method stub