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;
+ }
+
}