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.champcore.core;
24 import static org.junit.Assert.assertNotNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
29 import java.util.function.Consumer;
30 import java.util.function.Function;
31 import java.util.stream.Stream;
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;
58 public class ChampTransactionTest {
68 * This test validates the behaviour when the underlying graph implementation
69 * does not support transactions.
72 public void testNoTransactionSupport() {
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);
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...
82 // Now, configure our graph to specify that transactions are NOT supported.
83 g.setTransactionSupport(false);
87 // Now, try to start a new transaction against our graph.
88 t = new TinkerpopTransaction(g);
90 } catch (UnsupportedOperationException e) {
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).
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.");
104 * This test validates the behaviour when committing a transaction under various
106 * @throws ChampTransactionException
109 public void testCommit() throws ChampTransactionException {
111 // By default our test graph should simulate successful commits, but set
112 // the configuration anyway, just to be sure.
113 g.setFailCommits(false);
115 // Now, start a transaction.
116 TinkerpopTransaction t = new TinkerpopTransaction(g);
118 // Call commit against the transaction - it should complete successfully.
121 // Now, configure our test graph to simulate failing to commit.
122 g.setFailCommits(true);
124 // Open another transaction...
125 t = new TinkerpopTransaction(g);
126 boolean exceptionThrown = false;
129 //...and try to commit it.
132 } catch (Throwable e) {
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;
139 assertTrue("Failed commit should have produced an exception.", exceptionThrown);
144 public void testRollback() throws ChampTransactionException {
146 // By default our test graph should simulate successful commits, but set
147 // the configuration anyway, just to be sure.
148 g.setFailCommits(false);
150 // Now, start a transaction.
151 TinkerpopTransaction t = new TinkerpopTransaction(g);
153 // Call rollback against the transaction - it should complete successfully.
156 // Now, configure our test graph to simulate failing to commit.
157 g.setFailCommits(true);
159 // Open another transaction...
160 t = new TinkerpopTransaction(g);
161 boolean exceptionThrown = false;
164 //...and try to commit it.
167 } catch (Throwable e) {
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;
174 assertTrue("Failed rollback should have produced an exception.", exceptionThrown);
178 public void test() throws ChampTransactionException {
180 AbstractTinkerpopChampGraph graph = new AbstractTinkerpopChampGraph(new HashMap<String, Object>()) {
183 protected Graph getGraph() {
184 return TinkerGraph.open();
188 protected ChampSchemaEnforcer getSchemaEnforcer() {
193 public void executeStoreObjectIndex(ChampObjectIndex index) { }
196 public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
201 public Stream<ChampObjectIndex> retrieveObjectIndices() {
206 public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {}
209 public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {}
212 public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
217 public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
222 public void executeDeleteRelationshipIndex(String indexName) throws ChampIndexNotExistsException {}
225 public ChampCapabilities capabilities() {
230 public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
231 // TODO Auto-generated method stub
236 TinkerpopTransaction t = new TinkerpopTransaction(g);
238 graph.commitTransaction(t);
239 graph.rollbackTransaction(t);
243 private class TestGraph implements Graph {
245 private boolean supportsTransactions = true;
246 private boolean failCommits = false;
249 public void setTransactionSupport(boolean supportsTransactions) {
250 this.supportsTransactions = supportsTransactions;
253 public void setFailCommits(boolean failCommits) {
254 this.failCommits = failCommits;
257 public Vertex addVertex(Object... keyValues) {
258 // TODO Auto-generated method stub
263 public void close() throws Exception {
264 // TODO Auto-generated method stub
269 public GraphComputer compute() throws IllegalArgumentException {
270 // TODO Auto-generated method stub
275 public <C extends GraphComputer> C compute(Class<C> graphComputerClass)
276 throws IllegalArgumentException {
277 // TODO Auto-generated method stub
282 public Configuration configuration() {
283 // TODO Auto-generated method stub
288 public Iterator<Edge> edges(Object... edgeIds) {
289 // TODO Auto-generated method stub
294 public Transaction tx() {
295 return new TestTransaction();
299 public Variables variables() {
300 // TODO Auto-generated method stub
305 public Iterator<Vertex> vertices(Object... vertexIds) {
306 // TODO Auto-generated method stub
311 * Gets the {@link Features} exposed by the underlying {@code Graph} implementation.
313 public Features features() {
314 return new TestFeatures() {
318 public class TestFeatures implements Graph.Features {
321 * Gets the features related to "graph" operation.
323 public GraphFeatures graph() {
324 return new TestGraphFeatures() {
328 public class TestGraphFeatures implements Graph.Features.GraphFeatures {
331 * Determines if the {@code Graph} implementations supports transactions.
333 @FeatureDescriptor(name = FEATURE_TRANSACTIONS)
334 public boolean supportsTransactions() {
335 return supportsTransactions;
341 private class TestTransaction implements Transaction {
344 public void addTransactionListener(Consumer<Status> listener) {
345 // TODO Auto-generated method stub
350 public void clearTransactionListeners() {
351 // TODO Auto-generated method stub
356 public void close() {
357 // TODO Auto-generated method stub
362 public void commit() {
365 throw new UnsupportedOperationException();
370 public <G extends Graph> G createThreadedTx() {
375 public boolean isOpen() {
376 // TODO Auto-generated method stub
381 public Transaction onClose(Consumer<Transaction> consumer) {
382 // TODO Auto-generated method stub
387 public Transaction onReadWrite(Consumer<Transaction> consumer) {
388 // TODO Auto-generated method stub
394 // TODO Auto-generated method stub
399 public void readWrite() {
400 // TODO Auto-generated method stub
405 public void removeTransactionListener(Consumer<Status> listener) {
406 // TODO Auto-generated method stub
411 public void rollback() {
413 throw new UnsupportedOperationException();
418 public <R> Workload<R> submit(Function<Graph, R> work) {
419 // TODO Auto-generated method stub
425 private class TestTinkerpopGraph extends AbstractTinkerpopChampGraph {
427 protected TestTinkerpopGraph(Map<String, Object> properties) {
432 protected Graph getGraph() {
433 return TinkerGraph.open();
438 protected ChampSchemaEnforcer getSchemaEnforcer() {
443 public void executeStoreObjectIndex(ChampObjectIndex index) {
447 public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) {
448 // TODO Auto-generated method stub
453 public Stream<ChampObjectIndex> retrieveObjectIndices() {
454 // TODO Auto-generated method stub
459 public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException {
460 // TODO Auto-generated method stub
465 public void executeStoreRelationshipIndex(ChampRelationshipIndex index) {
466 // TODO Auto-generated method stub
471 public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) {
472 // TODO Auto-generated method stub
477 public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() {
478 // TODO Auto-generated method stub
483 public void executeDeleteRelationshipIndex(String indexName)
484 throws ChampIndexNotExistsException {
485 // TODO Auto-generated method stub
490 public ChampCapabilities capabilities() {
491 // TODO Auto-generated method stub
496 public GraphTraversal<?, ?> hasLabel(GraphTraversal<?, ?> query, Object type) {
497 // TODO Auto-generated method stub