* Commit and notification send must be atomic
*/
public synchronized CommitStatus commitTransaction() throws NetconfDocumentedException {
- final Optional<ObjectName> taON = getTransaction();
- Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
- CommitStatus status = configRegistryClient.commitConfig(taON.get());
- allOpenedTransactions.remove(transaction);
- transaction = null;
- return status;
+ final Optional<ObjectName> maybeTaON = getTransaction();
+ Preconditions.checkState(maybeTaON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
+ ObjectName taON = maybeTaON.get();
+ try {
+ CommitStatus status = configRegistryClient.commitConfig(taON);
+ // clean up
+ allOpenedTransactions.remove(transaction);
+ transaction = null;
+ return status;
+ } catch (ValidationException validationException) {
+ // no clean up: user can reconfigure and recover this transaction
+ logger.warn("Transaction {} failed on {}", taON, validationException.toString());
+ throw validationException;
+ } catch (Exception e) {
+ logger.error("Exception while commit of {}, aborting transaction", taON, e);
+ // clean up
+ abortTransaction();
+ throw e;
+ }
}
public synchronized void abortTransaction() {
+ logger.debug("Aborting current transaction");
Optional<ObjectName> taON = getTransaction();
Preconditions.checkState(taON.isPresent(), "No transaction found for session " + netconfSessionIdForReporting);
}
public synchronized void abortTestTransaction(ObjectName testTx) {
+ logger.debug("Aborting transaction {}", testTx);
ConfigTransactionClient transactionClient = configRegistryClient.getConfigTransactionClient(testTx);
allOpenedTransactions.remove(testTx);
transactionClient.abortConfig();
}
private synchronized NetconfClient pushAllConfigs(List<ConfigSnapshotHolder> configs) throws InterruptedException {
+ // first just make sure we can connect to netconf, even if nothing is being pushed
NetconfClient netconfClient = makeNetconfConnection(Collections.<String>emptySet(), Optional.<NetconfClient>absent());
+ // start pushing snapshots:
for (ConfigSnapshotHolder configSnapshotHolder: configs){
netconfClient = pushSnapshotWithRetries(configSnapshotHolder, Optional.of(netconfClient));
}
/**
* @param expectedCaps capabilities that server hello must contain. Will retry until all are found or throws RuntimeException.
* If empty set is provided, will only make sure netconf client successfuly connected to the server.
- * @param oldClientForPossibleReuse if present, try to get expected capabilities from it before closing it and retrying with
- * new client connection.
+ * @param maybeOldClient if present, close it.
* @return NetconfClient that has all required capabilities from server.
*/
private synchronized NetconfClient makeNetconfConnection(Set<String> expectedCaps,
- Optional<NetconfClient> oldClientForPossibleReuse)
+ Optional<NetconfClient> maybeOldClient)
throws InterruptedException {
- if (oldClientForPossibleReuse.isPresent()) {
- NetconfClient oldClient = oldClientForPossibleReuse.get();
- if (Util.isSubset(oldClient, expectedCaps)) {
- return oldClient;
- } else {
- Util.closeClientAndDispatcher(oldClient);
- }
+ if (maybeOldClient.isPresent()) {
+ NetconfClient oldClient = maybeOldClient.get();
+ Util.closeClientAndDispatcher(oldClient);
}
// TODO think about moving capability subset check to netconf client