import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
import org.opendaylight.controller.config.api.ConflictingVersionException;
import org.opendaylight.controller.config.api.ValidationException;
import org.opendaylight.controller.config.api.jmx.CommitStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
public class TransactionProvider implements AutoCloseable {
- private static final Logger logger = LoggerFactory.getLogger(TransactionProvider.class);
+ private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class);
private final ConfigRegistryClient configRegistryClient;
private final String netconfSessionIdForReporting;
- private ObjectName transaction;
+ private ObjectName candidateTx;
+ private ObjectName readTx;
private final List<ObjectName> allOpenedTransactions = new ArrayList<>();
private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No transaction found for session ";
configRegistryClient.getConfigTransactionClient(tx).abortConfig();
}
} catch (Exception e) {
- logger.debug("Ignoring exception while closing transaction {}", tx, e);
+ LOG.debug("Ignoring exception while closing transaction {}", tx, e);
}
}
allOpenedTransactions.clear();
}
- public Optional<ObjectName> getTransaction() {
+ public synchronized Optional<ObjectName> getTransaction() {
- if (transaction == null){
+ if (candidateTx == null){
return Optional.absent();
}
// Transaction was already closed somehow
- if (!isStillOpenTransaction(transaction)) {
- logger.warn("Fixing illegal state: transaction {} was closed in {}", transaction,
+ if (!isStillOpenTransaction(candidateTx)) {
+ LOG.warn("Fixing illegal state: transaction {} was closed in {}", candidateTx,
netconfSessionIdForReporting);
- transaction = null;
+ candidateTx = null;
return Optional.absent();
}
- return Optional.of(transaction);
+ return Optional.of(candidateTx);
+ }
+
+ public synchronized Optional<ObjectName> getReadTransaction() {
+
+ if (readTx == null){
+ return Optional.absent();
+ }
+
+ // Transaction was already closed somehow
+ if (!isStillOpenTransaction(readTx)) {
+ LOG.warn("Fixing illegal state: transaction {} was closed in {}", readTx,
+ netconfSessionIdForReporting);
+ readTx = null;
+ return Optional.absent();
+ }
+ return Optional.of(readTx);
}
private boolean isStillOpenTransaction(ObjectName transaction) {
public synchronized ObjectName getOrCreateTransaction() {
Optional<ObjectName> ta = getTransaction();
- if (ta.isPresent())
+ if (ta.isPresent()) {
+ return ta.get();
+ }
+ candidateTx = configRegistryClient.beginConfig();
+ allOpenedTransactions.add(candidateTx);
+ return candidateTx;
+ }
+
+ public synchronized ObjectName getOrCreateReadTransaction() {
+ Optional<ObjectName> ta = getReadTransaction();
+
+ if (ta.isPresent()) {
return ta.get();
- transaction = configRegistryClient.beginConfig();
- allOpenedTransactions.add(transaction);
- return transaction;
+ }
+ readTx = configRegistryClient.beginConfig();
+ allOpenedTransactions.add(readTx);
+ return readTx;
}
/**
try {
CommitStatus status = configRegistryClient.commitConfig(taON);
// clean up
- allOpenedTransactions.remove(transaction);
- transaction = null;
+ allOpenedTransactions.remove(candidateTx);
+ candidateTx = null;
return status;
} catch (ValidationException validationException) {
// no clean up: user can reconfigure and recover this transaction
- logger.warn("Transaction {} failed on {}", taON, validationException.toString());
+ LOG.warn("Transaction {} failed on {}", taON, validationException.toString());
throw validationException;
} catch (ConflictingVersionException e) {
- logger.error("Exception while commit of {}, aborting transaction", taON, e);
+ LOG.error("Exception while commit of {}, aborting transaction", taON, e);
// clean up
abortTransaction();
throw e;
}
public synchronized void abortTransaction() {
- logger.debug("Aborting current transaction");
+ LOG.debug("Aborting current transaction");
Optional<ObjectName> taON = getTransaction();
Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
transactionClient.abortConfig();
- allOpenedTransactions.remove(transaction);
- transaction = null;
+ allOpenedTransactions.remove(candidateTx);
+ candidateTx = null;
+ }
+
+ public synchronized void closeReadTransaction() {
+ LOG.debug("Closing read transaction");
+ Optional<ObjectName> taON = getReadTransaction();
+ Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
+
+ ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON.get());
+ transactionClient.abortConfig();
+ allOpenedTransactions.remove(readTx);
+ readTx = null;
}
public synchronized void abortTestTransaction(ObjectName testTx) {
- logger.debug("Aborting transaction {}", testTx);
+ LOG.debug("Aborting transaction {}", testTx);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(testTx);
allOpenedTransactions.remove(testTx);
transactionClient.abortConfig();
}
public void wipeTestTransaction(ObjectName taON) {
- wipeInternal(taON, true, null);
+ wipeInternal(taON, true);
}
/**
* Wiping means removing all module instances keeping the transaction open + service references.
*/
- synchronized void wipeInternal(ObjectName taON, boolean isTest, String moduleName) {
+ synchronized void wipeInternal(ObjectName taON, boolean isTest) {
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(taON);
- Set<ObjectName> lookupConfigBeans = moduleName == null ? transactionClient.lookupConfigBeans()
- : transactionClient.lookupConfigBeans(moduleName);
+ Set<ObjectName> lookupConfigBeans = transactionClient.lookupConfigBeans();
int i = lookupConfigBeans.size();
for (ObjectName instance : lookupConfigBeans) {
try {
transactionClient.destroyModule(instance);
} catch (InstanceNotFoundException e) {
if (isTest){
- logger.debug("Unable to clean configuration in transactiom {}", taON, e);
+ LOG.debug("Unable to clean configuration in transactiom {}", taON, e);
} else {
- logger.warn("Unable to clean configuration in transactiom {}", taON, e);
+ LOG.warn("Unable to clean configuration in transactiom {}", taON, e);
}
throw new IllegalStateException("Unable to clean configuration in transactiom " + taON, e);
}
}
- logger.debug("Transaction {} wiped clean of {} config beans", taON, i);
+ LOG.debug("Transaction {} wiped clean of {} config beans", taON, i);
transactionClient.removeAllServiceReferences();
- logger.debug("Transaction {} wiped clean of all service references", taON);
+ LOG.debug("Transaction {} wiped clean of all service references", taON);
}
public void wipeTransaction() {
Optional<ObjectName> taON = getTransaction();
Preconditions.checkState(taON.isPresent(), NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting);
- wipeInternal(taON.get(), false, null);
+ wipeInternal(taON.get(), false);
}
}