Use Optional.isEmpty()
[netconf.git] / netconf / mdsal-netconf-connector / src / main / java / org / opendaylight / netconf / mdsal / connector / TransactionProvider.java
index a39042f881cdc5bbd00f4263c710fa63986083f0..e41f019c9fdb37ceed08785023127ab4edb1d880 100644 (file)
@@ -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<DOMDataReadWriteTransaction> allOpenReadWriteTransactions = new ArrayList<>();
+    private DOMDataTreeReadWriteTransaction candidateTransaction = null;
+    private DOMDataTreeReadWriteTransaction runningTransaction = null;
+    private final List<DOMDataTreeReadWriteTransaction> 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<DOMDataReadWriteTransaction> getCandidateTransaction() {
-        if (candidateTransaction == null) {
-            return Optional.absent();
-        }
-
-        return Optional.of(candidateTransaction);
+    public synchronized Optional<DOMDataTreeReadWriteTransaction> 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<Void, TransactionCommitFailedException> future = candidateTransaction.submit();
+        final FluentFuture<? extends CommitInfo> 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<DOMDataReadWriteTransaction> otx = getCandidateTransaction();
-        if (!otx.isPresent()) {
-            LOG.warn("discard-changes triggerd on an empty transaction for session: {}", netconfSessionIdForReporting );
+        final Optional<DOMDataTreeReadWriteTransaction> otx = getCandidateTransaction();
+        if (otx.isEmpty()) {
+            LOG.warn("discard-changes triggerd on an empty transaction for session: {}", netconfSessionIdForReporting);
             return;
         }
         candidateTransaction.cancel();
@@ -106,17 +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 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);
     }
-
 }