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.graph.impl;
23 import java.security.SecureRandom;
25 import org.apache.tinkerpop.gremlin.structure.Graph;
26 import org.onap.aai.champcore.ChampCoreMsgs;
27 import org.onap.aai.champcore.ChampTransaction;
28 import org.onap.aai.champcore.exceptions.ChampTransactionException;
29 import org.onap.aai.cl.api.Logger;
30 import org.onap.aai.cl.eelf.LoggerFactory;
32 public class TinkerpopTransaction extends ChampTransaction {
34 private static final int COMMIT_RETRY_COUNT = 3;
36 /** Threaded Tinkerpop transaction. */
37 protected Graph threadedTransaction;
40 private static final Logger LOGGER = LoggerFactory.getInstance().getLogger(TinkerpopTransaction.class);
42 protected TinkerpopTransaction() { }
46 * Creates a new transaction instance.
48 * @param aGraphInstance - Instance of the graph to request the transaction from.
50 public TinkerpopTransaction(Graph aGraphInstance) {
53 if(!aGraphInstance.features().graph().supportsTransactions()) {
54 throw new UnsupportedOperationException();
57 // Request a threaded transaction object from the graph.
58 this.threadedTransaction = aGraphInstance.tx().createThreadedTx();
60 LOGGER.info(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_INFO,
61 "Open transaction - id: " + id);
69 public Graph getGraphInstance() {
70 return threadedTransaction;
74 public void commit() throws ChampTransactionException {
76 LOGGER.debug("Commiting transaction - " + id);
78 final long initialBackoff = (int)(new SecureRandom().nextDouble() * 50);
80 // If something goes wrong, we will retry a couple of times before
82 for (int i = 0; i < COMMIT_RETRY_COUNT; i++) {
87 threadedTransaction.tx().commit();
88 LOGGER.info(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_INFO,
89 "Committed transaction - id: " + id);
92 } catch (Throwable e) {
94 LOGGER.debug("Transaction " + id + " failed to commit due to: " + e.getMessage());
96 // Have we used up all of our retries?
97 if (i == COMMIT_RETRY_COUNT - 1) {
99 LOGGER.error(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_ERROR,
100 "Maxed out commit attempt retries, client must handle exception and retry. " + e.getMessage());
101 threadedTransaction.tx().rollback();
102 throw new ChampTransactionException(e);
105 // Calculate how long we will wait before retrying...
106 final long backoff = (long) Math.pow(2, i) * initialBackoff;
107 LOGGER.warn(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_WARN,
108 "Caught exception while retrying transaction commit, retrying in " + backoff + " ms");
110 // ...and sleep before trying the commit again.
112 Thread.sleep(backoff);
114 } catch (InterruptedException ie) {
116 LOGGER.info(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_INFO,
117 "Interrupted while backing off on transaction commit");
118 Thread.currentThread().interrupt();
126 public void rollback() throws ChampTransactionException {
128 long initialBackoff = (int)(new SecureRandom().nextDouble() * 50);
131 // If something goes wrong, we will retry a couple of times before
133 for (int i = 0; i < COMMIT_RETRY_COUNT; i++) {
137 threadedTransaction.tx().rollback();
138 LOGGER.info(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_INFO,
139 "Rolled back transaction - id: " + id);
142 } catch (Throwable e) {
144 LOGGER.debug("Transaction " + id + " failed to roll back due to: " + e.getMessage());
146 // Have we used up all of our retries?
147 if (i == COMMIT_RETRY_COUNT - 1) {
149 LOGGER.error(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_ERROR,
150 "Maxed out rollback attempt retries, client must handle exception and retry. " + e.getMessage());
151 throw new ChampTransactionException(e);
154 // Calculate how long we will wait before retrying...
155 final long backoff = (long) Math.pow(2, i) * initialBackoff;
156 LOGGER.warn(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_WARN,
157 "Caught exception while retrying transaction roll back, retrying in " + backoff + " ms");
159 // ...and sleep before trying the commit again.
161 Thread.sleep(backoff);
163 } catch (InterruptedException ie) {
165 LOGGER.info(ChampCoreMsgs.CHAMPCORE_TINKERPOP_TRANSACTION_INFO,
166 "Interrupted while backing off on transaction rollback");
167 Thread.currentThread().interrupt();