Remove static TransactionChainHandler instance
[netconf.git] / restconf / restconf-nb-rfc8040 / src / main / java / org / opendaylight / restconf / nb / rfc8040 / handlers / TransactionChainHandler.java
index 573dc36e0144d2cf8bc2dbb80e89b5372934cea8..81cdb08d96bb29c45271f5d7f7dfb1796e95b958 100644 (file)
@@ -8,37 +8,65 @@
 
 package org.opendaylight.restconf.nb.rfc8040.handlers;
 
-import com.google.common.base.Preconditions;
+import java.util.Objects;
+import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
+import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
  * Implementation of {@link TransactionChainHandler}.
  *
  */
-public class TransactionChainHandler implements Handler<DOMTransactionChain> {
+public class TransactionChainHandler implements Handler<DOMTransactionChain>, AutoCloseable {
+    private static final Logger LOG = LoggerFactory.getLogger(TransactionChainHandler.class);
 
-    private DOMTransactionChain transactionChain;
+    private final TransactionChainListener transactionChainListener = new TransactionChainListener() {
+        @Override
+        public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
+                final AsyncTransaction<?, ?> transaction, final Throwable cause) {
+            LOG.warn("TransactionChain({}) {} FAILED!", chain, transaction.getIdentifier(), cause);
+            reset();
+            throw new RestconfDocumentedException("TransactionChain(" + chain + ") not committed correctly", cause);
+        }
+
+        @Override
+        public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+            LOG.trace("TransactionChain({}) {} SUCCESSFUL", chain);
+        }
+    };
+
+    @Nullable
+    private final DOMDataBroker dataBroker;
+    private volatile DOMTransactionChain transactionChain;
 
     /**
      * Prepare transaction chain service for Restconf services.
-     *
-     * @param transactionChain Transaction chain
      */
-    public TransactionChainHandler(final DOMTransactionChain transactionChain) {
-        Preconditions.checkNotNull(transactionChain);
-        this.transactionChain = transactionChain;
+    public TransactionChainHandler(final DOMDataBroker dataBroker) {
+        this.dataBroker = Objects.requireNonNull(dataBroker);
+        transactionChain = Objects.requireNonNull(dataBroker.createTransactionChain(transactionChainListener));
     }
 
     @Override
-    @SuppressWarnings("checkstyle:hiddenField")
-    public void update(final DOMTransactionChain transactionChain) {
-        Preconditions.checkNotNull(transactionChain);
-        this.transactionChain = transactionChain;
+    public DOMTransactionChain get() {
+        return this.transactionChain;
+    }
+
+    public synchronized void reset() {
+        LOG.trace("Resetting TransactionChain({})", transactionChain);
+        transactionChain.close();
+        transactionChain = dataBroker.createTransactionChain(transactionChainListener);
     }
 
     @Override
-    public DOMTransactionChain get() {
-        return this.transactionChain;
+    public synchronized void close() {
+        transactionChain.close();
     }
 }