X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openflowplugin-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fopenflowplugin%2Fimpl%2Fdevice%2FTransactionChainManager.java;h=4706cc1df8d789a24605306c3a32c3563d5fc6eb;hb=0b4b43cb55409bc1a6f8aa2be4bda5b05bd2a66e;hp=0870fabb038d2d124831be87ee1fad6d5bfa1571;hpb=12acda3d28b5b3056bae5277b392768d4d3bd955;p=openflowplugin.git diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java index 0870fabb03..4706cc1df8 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/device/TransactionChainManager.java @@ -9,9 +9,10 @@ package org.opendaylight.openflowplugin.impl.device; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import java.util.concurrent.ExecutionException; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -20,10 +21,13 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; -import org.opendaylight.openflowplugin.api.openflow.device.DeviceState; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,7 +41,7 @@ import org.slf4j.LoggerFactory; * and submitTransaction method (wrapped {@link WriteTransaction#submit()}) * * @author Vaclav Demcak - *

+ *

* Created: Apr 2, 2015 */ class TransactionChainManager implements TransactionChainListener, AutoCloseable { @@ -46,37 +50,33 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable private final Object txLock = new Object(); - private final DeviceState deviceState; private final DataBroker dataBroker; private WriteTransaction wTx; private BindingTransactionChain txChainFactory; private boolean submitIsEnabled; - TransactionChainManager(@Nonnull final DataBroker dataBroker, @Nonnull final DeviceState deviceState) { + public TransactionChainManagerStatus getTransactionChainManagerStatus() { + return transactionChainManagerStatus; + } + + private TransactionChainManagerStatus transactionChainManagerStatus; + private ReadyForNewTransactionChainHandler readyForNewTransactionChainHandler; + private final KeyedInstanceIdentifier nodeII; + private Registration managerRegistration; + + TransactionChainManager(@Nonnull final DataBroker dataBroker, + @Nonnull final KeyedInstanceIdentifier nodeII, + @Nonnull final Registration managerRegistration) { this.dataBroker = Preconditions.checkNotNull(dataBroker); - this.deviceState = Preconditions.checkNotNull(deviceState); - checkExistingNode(); - txChainFactory = dataBroker.createTransactionChain(TransactionChainManager.this); + this.nodeII = Preconditions.checkNotNull(nodeII); + this.managerRegistration = Preconditions.checkNotNull(managerRegistration); + this.transactionChainManagerStatus = TransactionChainManagerStatus.WORKING; + createTxChain(dataBroker); LOG.debug("created txChainManager"); } - /** - * Creating new TransactionChainManager means we have new Node (HandShake process was successful), but - * the node existence in OPERATIONAL DataStore indicates some not finished NODE disconnection or some - * unexpected problem with DataStore. - * We should not continue with a PostHandShake NODE information collecting in this state. - */ - private void checkExistingNode() { - Optional node = Optional. absent(); - try { - node = dataBroker.newReadOnlyTransaction() - .read(LogicalDatastoreType.OPERATIONAL, deviceState.getNodeInstanceIdentifier()).get(); - } - catch (InterruptedException | ExecutionException e) { - LOG.warn("Not able to read node {} in Operation DataStore", deviceState.getNodeId()); - throw new IllegalStateException(e); - } - Preconditions.checkArgument((!node.isPresent()), "Node {} is exist, can not add same now!", deviceState.getNodeId()); + private void createTxChain(final DataBroker dataBroker) { + txChainFactory = dataBroker.createTransactionChain(TransactionChainManager.this); } void initialSubmitWriteTransaction() { @@ -84,25 +84,45 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable submitWriteTransaction(); } + public synchronized boolean attemptToRegisterHandler(final ReadyForNewTransactionChainHandler readyForNewTransactionChainHandler) { + if (TransactionChainManagerStatus.SHUTTING_DOWN.equals(this.transactionChainManagerStatus) + && null == this.readyForNewTransactionChainHandler) { + this.readyForNewTransactionChainHandler = readyForNewTransactionChainHandler; + if (managerRegistration == null) { + this.readyForNewTransactionChainHandler.onReadyForNewTransactionChain(); + } + return true; + } else { + return false; + } + } + boolean submitWriteTransaction() { if (!submitIsEnabled) { LOG.trace("transaction not committed - submit block issued"); return false; } - if ( ! deviceState.isValid()) { - LOG.info("DeviceState is not valid will not submit transaction"); - return false; - } - if (wTx == null) { - LOG.trace("nothing to commit - submit returns true"); - return true; - } synchronized (txLock) { if (wTx == null) { LOG.trace("nothing to commit - submit returns true"); return true; } - wTx.submit(); + final CheckedFuture submitFuture = wTx.submit(); + Futures.addCallback(submitFuture, new FutureCallback() { + @Override + public void onSuccess(Void result) { + //no action required + } + + @Override + public void onFailure(Throwable t) { + if (t instanceof TransactionCommitFailedException) { + LOG.error("Transaction commit failed. {}", t); + } else { + LOG.error("Exception during transaction submitting. {}", t); + } + } + }); wTx = null; } return true; @@ -134,14 +154,14 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable private void recreateTxChain() { txChainFactory.close(); - txChainFactory = dataBroker.createTransactionChain(TransactionChainManager.this); + createTxChain(dataBroker); synchronized (txLock) { wTx = null; } } private WriteTransaction getTransactionSafely() { - if (wTx == null) { + if (wTx == null && !TransactionChainManagerStatus.SHUTTING_DOWN.equals(transactionChainManagerStatus)) { synchronized (txLock) { if (wTx == null) { wTx = txChainFactory.newWriteOnlyTransaction(); @@ -158,13 +178,50 @@ class TransactionChainManager implements TransactionChainListener, AutoCloseable @Override public void close() { - LOG.debug("Removing node {} from operational DS.", deviceState.getNodeId()); + LOG.debug("Removing node {} from operational DS.", nodeII); synchronized (txLock) { final WriteTransaction writeTx = getTransactionSafely(); - writeTx.delete(LogicalDatastoreType.OPERATIONAL, deviceState.getNodeInstanceIdentifier()); - writeTx.submit(); + this.transactionChainManagerStatus = TransactionChainManagerStatus.SHUTTING_DOWN; + writeTx.delete(LogicalDatastoreType.OPERATIONAL, nodeII); + LOG.debug("Delete node {} from operational DS put to write transaction.", nodeII); + CheckedFuture submitsFuture = writeTx.submit(); + LOG.debug("Delete node {} from operational DS write transaction submitted.", nodeII); + Futures.addCallback(submitsFuture, new FutureCallback() { + @Override + public void onSuccess(final Void aVoid) { + LOG.debug("Removing node {} from operational DS successful .", nodeII); + notifyReadyForNewTransactionChainAndCloseFactory(); + } + + @Override + public void onFailure(final Throwable throwable) { + LOG.info("Attempt to close transaction chain factory failed.", throwable); + notifyReadyForNewTransactionChainAndCloseFactory(); + } + }); wTx = null; - txChainFactory.close(); } } + + private void notifyReadyForNewTransactionChainAndCloseFactory() { + synchronized (this) { + try { + LOG.debug("Closing registration in manager."); + managerRegistration.close(); + } catch (Exception e) { + LOG.warn("Failed to close transaction chain manager's registration.", e); + } + managerRegistration = null; + if (null != readyForNewTransactionChainHandler) { + readyForNewTransactionChainHandler.onReadyForNewTransactionChain(); + } + } + txChainFactory.close(); + LOG.debug("Transaction chain factory closed."); + } + + public enum TransactionChainManagerStatus { + WORKING, SHUTTING_DOWN; + } + }