X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=netconf%2Fmdsal-netconf-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetconf%2Fmdsal%2Fconnector%2FTransactionProvider.java;h=e41f019c9fdb37ceed08785023127ab4edb1d880;hb=98a820a6085dc303a39b0c1d9098abfde963416a;hp=f5e303ebd660fb745335f20b1bd9bee09ad8caef;hpb=5a68db96acc2e92c82cbaee71f09df1634b81d10;p=netconf.git diff --git a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/TransactionProvider.java b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/TransactionProvider.java index f5e303ebd6..e41f019c9f 100644 --- a/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/TransactionProvider.java +++ b/netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/TransactionProvider.java @@ -5,62 +5,59 @@ * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ - package org.opendaylight.netconf.mdsal.connector; -import com.google.common.base.Optional; -import com.google.common.base.Preconditions; -import com.google.common.util.concurrent.CheckedFuture; +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.util.concurrent.FluentFuture; import java.util.ArrayList; import java.util.List; -import org.opendaylight.controller.config.util.xml.DocumentedException; -import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorSeverity; -import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorTag; -import org.opendaylight.controller.config.util.xml.DocumentedException.ErrorType; -import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadWriteTransaction; +import java.util.Optional; +import java.util.concurrent.ExecutionException; +import org.opendaylight.mdsal.common.api.CommitInfo; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; +import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction; +import org.opendaylight.netconf.api.DocumentedException; +import org.opendaylight.netconf.api.DocumentedException.ErrorSeverity; +import org.opendaylight.netconf.api.DocumentedException.ErrorTag; +import org.opendaylight.netconf.api.DocumentedException.ErrorType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class TransactionProvider implements AutoCloseable{ - +public class TransactionProvider implements AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(TransactionProvider.class); private final DOMDataBroker dataBroker; - private DOMDataReadWriteTransaction candidateTransaction = null; - private DOMDataReadWriteTransaction runningTransaction = null; - private final List allOpenReadWriteTransactions = new ArrayList<>(); + private DOMDataTreeReadWriteTransaction candidateTransaction = null; + private DOMDataTreeReadWriteTransaction runningTransaction = null; + private final List allOpenReadWriteTransactions = new ArrayList<>(); + private final DOMDataTransactionValidator transactionValidator; private final String netconfSessionIdForReporting; - private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No candidateTransaction found for session "; + private static final String NO_TRANSACTION_FOUND_FOR_SESSION = "No candidateTransaction found for session "; - - public TransactionProvider(DOMDataBroker dataBroker, String netconfSessionIdForReporting) { + public TransactionProvider(final DOMDataBroker dataBroker, final String netconfSessionIdForReporting) { this.dataBroker = dataBroker; this.netconfSessionIdForReporting = netconfSessionIdForReporting; + this.transactionValidator = dataBroker.getExtensions().getInstance(DOMDataTransactionValidator.class); } @Override - public synchronized void close() throws Exception { - for (DOMDataReadWriteTransaction rwt : allOpenReadWriteTransactions) { + public synchronized void close() { + for (final DOMDataTreeReadWriteTransaction rwt : allOpenReadWriteTransactions) { rwt.cancel(); } allOpenReadWriteTransactions.clear(); } - public synchronized Optional getCandidateTransaction() { - if (candidateTransaction == null) { - return Optional.absent(); - } - - return Optional.of(candidateTransaction); + public synchronized Optional getCandidateTransaction() { + return Optional.ofNullable(candidateTransaction); } - public synchronized DOMDataReadWriteTransaction getOrCreateTransaction() { + public synchronized DOMDataTreeReadWriteTransaction getOrCreateTransaction() { if (getCandidateTransaction().isPresent()) { return getCandidateTransaction().get(); } @@ -70,22 +67,47 @@ public class TransactionProvider implements AutoCloseable{ return candidateTransaction; } + public synchronized void validateTransaction() throws DocumentedException { + if (transactionValidator == null) { + LOG.error("Validate capability is not supported"); + throw new DocumentedException("Validate capability is not supported", + ErrorType.PROTOCOL, ErrorTag.OPERATION_NOT_SUPPORTED, ErrorSeverity.ERROR); + } + + if (getCandidateTransaction().isEmpty()) { + // Validating empty transaction, just return true + LOG.debug("Validating empty candidate transaction for session {}", netconfSessionIdForReporting); + return; + } + + try { + transactionValidator.validate(candidateTransaction).get(); + } catch (final InterruptedException | ExecutionException e) { + LOG.debug("Candidate transaction validation {} failed on session {}", candidateTransaction, + netconfSessionIdForReporting, e); + final String cause = e.getCause() != null ? " Cause: " + e.getCause().getMessage() : ""; + throw new DocumentedException("Candidate transaction validate failed [sessionId=" + + netconfSessionIdForReporting + "]: " + e.getMessage() + cause, e, ErrorType.APPLICATION, + ErrorTag.OPERATION_FAILED, ErrorSeverity.ERROR); + } + } + public synchronized boolean commitTransaction() throws DocumentedException { - if (!getCandidateTransaction().isPresent()) { + if (getCandidateTransaction().isEmpty()) { //making empty commit without prior opened transaction, just return true LOG.debug("Making commit without open candidate transaction for session {}", netconfSessionIdForReporting); return true; } - CheckedFuture future = candidateTransaction.submit(); + final FluentFuture future = candidateTransaction.commit(); try { - future.checkedGet(); - } catch (TransactionCommitFailedException e) { + future.get(); + } catch (final InterruptedException | ExecutionException e) { LOG.debug("Transaction {} failed on", candidateTransaction, e); - final String cause = e.getCause() != null ? (" Cause: " + e.getCause().getMessage()) : ""; - throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting + - cause, - ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); + final String cause = e.getCause() != null ? " Cause: " + e.getCause().getMessage() : ""; + throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + + netconfSessionIdForReporting + cause, e, ErrorType.APPLICATION, ErrorTag.OPERATION_FAILED, + ErrorSeverity.ERROR); } finally { allOpenReadWriteTransactions.remove(candidateTransaction); candidateTransaction = null; @@ -96,9 +118,9 @@ public class TransactionProvider implements AutoCloseable{ public synchronized void abortTransaction() { LOG.debug("Aborting current candidateTransaction"); - Optional otx = getCandidateTransaction(); - if (!otx.isPresent()) { - LOG.warn("discard-changes triggerd on an empty transaction for session: {}", netconfSessionIdForReporting ); + final Optional otx = getCandidateTransaction(); + if (otx.isEmpty()) { + LOG.warn("discard-changes triggerd on an empty transaction for session: {}", netconfSessionIdForReporting); return; } candidateTransaction.cancel(); @@ -106,32 +128,16 @@ public class TransactionProvider implements AutoCloseable{ candidateTransaction = null; } - public synchronized DOMDataReadWriteTransaction createRunningTransaction() { + public synchronized DOMDataTreeReadWriteTransaction createRunningTransaction() { runningTransaction = dataBroker.newReadWriteTransaction(); allOpenReadWriteTransactions.add(runningTransaction); return runningTransaction; } - public synchronized boolean commitRunningTransaction(DOMDataReadWriteTransaction tx) throws DocumentedException { - allOpenReadWriteTransactions.remove(tx); - - CheckedFuture future = tx.submit(); - try { - future.checkedGet(); - } catch (TransactionCommitFailedException e) { - LOG.debug("Transaction {} failed on", tx, e); - throw new DocumentedException("Transaction commit failed on " + e.getMessage() + " " + netconfSessionIdForReporting, - ErrorType.application, ErrorTag.operation_failed, ErrorSeverity.error); - } - - return true; - } - - public synchronized void abortRunningTransaction(DOMDataReadWriteTransaction tx) { + public synchronized void abortRunningTransaction(final DOMDataTreeReadWriteTransaction tx) { LOG.debug("Aborting current running Transaction"); - Preconditions.checkState(runningTransaction != null, NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); + checkState(runningTransaction != null, NO_TRANSACTION_FOUND_FOR_SESSION + netconfSessionIdForReporting); tx.cancel(); allOpenReadWriteTransactions.remove(tx); } - }