import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+
import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-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.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
private static final Logger logger = LoggerFactory.getLogger(NetconfDeviceDatastoreAdapter.class);
private final RemoteDeviceId id;
- private final BindingTransactionChain txChain;
+ private BindingTransactionChain txChain;
- NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final DataBroker dataService) {
+ NetconfDeviceDatastoreAdapter(final RemoteDeviceId deviceId, final BindingTransactionChain txChain) {
this.id = Preconditions.checkNotNull(deviceId);
- this.txChain = Preconditions.checkNotNull(dataService).createTransactionChain(new TransactionChainListener() {
- @Override
- public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
- logger.error("{}: TransactionChain({}) {} FAILED!", id, chain, transaction.getIdentifier(), cause);
- throw new IllegalStateException(id + " TransactionChain(" + chain + ") not committed correctly", cause);
- }
-
- @Override
- public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
- logger.trace("{}: TransactionChain({}) {} SUCCESSFUL", id, chain);
- }
- });
+ this.txChain = Preconditions.checkNotNull(txChain);
initDeviceData();
}
transaction.delete(LogicalDatastoreType.OPERATIONAL, id.getBindingPath());
logger.trace("{}: Close device state transaction {} removing all data ended.", id, transaction.getIdentifier());
- commitTransaction(transaction, "close");
+ try {
+ transaction.submit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ logger.error("{}: Transaction(close) {} FAILED!", id, transaction.getIdentifier(), e);
+ throw new IllegalStateException(id + " Transaction(close) not committed correctly", e);
+ }
}
private void initDeviceData() {
@Override
public void close() throws Exception {
removeDeviceConfigAndState();
- txChain.close();
}
public static org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node buildDataForDeviceState(
nodeBuilder.setId(id.getBindingKey().getId());
return nodeBuilder;
}
+
+ public void setTxChain(BindingTransactionChain txChain) {
+ this.txChain = Preconditions.checkNotNull(txChain);
+ }
}
package org.opendaylight.netconf.sal.connect.netconf.sal;
import com.google.common.base.Preconditions;
+
import java.util.Collection;
import java.util.Collections;
+
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+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.DOMMountPoint;
import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
private volatile NetconfDeviceTopologyAdapter topologyDatastoreAdapter;
+ private DataBroker dataBroker;
+ private BindingTransactionChain txChain;
+
+ private final TransactionChainListener transactionChainListener = new TransactionChainListener() {
+ @Override
+ public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
+ logger.error("{}: TransactionChain({}) {} FAILED!", id, chain, transaction.getIdentifier(), cause);
+ chain.close();
+ resetTransactionChainForAdapaters();
+ throw new IllegalStateException(id + " TransactionChain(" + chain + ") not committed correctly", cause);
+ }
+
+ @Override
+ public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
+ logger.trace("{}: TransactionChain({}) {} SUCCESSFUL", id, chain);
+ }
+ };
+
public NetconfDeviceSalProvider(final RemoteDeviceId deviceId) {
this.id = deviceId;
}
public void onSessionInitiated(final BindingAwareBroker.ProviderContext session) {
logger.debug("{}: Session with sal established {}", id, session);
- final DataBroker dataBroker = session.getSALService(DataBroker.class);
- datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, dataBroker);
+ this.dataBroker = session.getSALService(DataBroker.class);
+ txChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(transactionChainListener);
+
+ datastoreAdapter = new NetconfDeviceDatastoreAdapter(id, txChain);
+ topologyDatastoreAdapter = new NetconfDeviceTopologyAdapter(id, txChain);
+ }
+
+ private void resetTransactionChainForAdapaters() {
+ txChain = Preconditions.checkNotNull(dataBroker).createTransactionChain(transactionChainListener);
+
+ datastoreAdapter.setTxChain(txChain);
+ topologyDatastoreAdapter.setTxChain(txChain);
+
+ logger.trace("{}: Resetting TransactionChain {}", id, txChain);
- topologyDatastoreAdapter = new NetconfDeviceTopologyAdapter(id, dataBroker);
}
public void close() throws Exception {
datastoreAdapter = null;
topologyDatastoreAdapter.close();
topologyDatastoreAdapter = null;
+ txChain.close();
}
public static final class MountInstance implements AutoCloseable {
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
+import java.util.concurrent.ExecutionException;
+
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-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.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities;
import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
};
private final RemoteDeviceId id;
- private final BindingTransactionChain txChain;
+ private BindingTransactionChain txChain;
private final InstanceIdentifier<NetworkTopology> networkTopologyPath;
private final KeyedInstanceIdentifier<Topology, TopologyKey> topologyListPath;
private static final String UNKNOWN_REASON = "Unknown reason";
- NetconfDeviceTopologyAdapter(final RemoteDeviceId id, final DataBroker dataService) {
+ NetconfDeviceTopologyAdapter(final RemoteDeviceId id, final BindingTransactionChain txChain) {
this.id = id;
- this.txChain = Preconditions.checkNotNull(dataService).createTransactionChain(new TransactionChainListener() {
- @Override
- public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction, Throwable cause) {
- LOG.error("{}: TransactionChain({}) {} FAILED!", id, chain,
- transaction.getIdentifier(), cause);
- throw new IllegalStateException(id + " TransactionChain(" + chain + ") not committed correctly", cause);
- }
-
- @Override
- public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
- LOG.trace("{}: TransactionChain({}) SUCCESSFUL", id, chain);
- }
- });
+ this.txChain = Preconditions.checkNotNull(txChain);
this.networkTopologyPath = InstanceIdentifier.builder(NetworkTopology.class).build();
this.topologyListPath = networkTopologyPath.child(Topology.class, new TopologyKey(new TopologyId(TopologyNetconf.QNAME.getLocalName())));
"{}: Close device state transaction {} removing all data ended.",
id, writeTx.getIdentifier());
- commitTransaction(writeTx, "close");
+ try {
+ writeTx.submit().get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("{}: Transaction(close) {} FAILED!", id, writeTx.getIdentifier(), e);
+ throw new IllegalStateException(id + " Transaction(close) not committed correctly", e);
+ }
}
private void createNetworkTopologyIfNotPresent(final WriteTransaction writeTx) {
@Override
public void close() throws Exception {
removeDeviceConfiguration();
- txChain.close();
+ }
+
+ public void setTxChain(BindingTransactionChain txChain) {
+ this.txChain = Preconditions.checkNotNull(txChain);
}
}
public void testFailedDevice() throws Exception {
doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
- NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
+ NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
adapter.setDeviceAsFailed(null);
verify(txChain, times(2)).newWriteOnlyTransaction();
public void testDeviceUpdate() throws Exception {
doReturn(Futures.immediateCheckedFuture(null)).when(writeTx).submit();
- NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, broker);
+ NetconfDeviceTopologyAdapter adapter = new NetconfDeviceTopologyAdapter(id, txChain);
adapter.updateDeviceData(true, new NetconfDeviceCapabilities());
verify(txChain, times(2)).newWriteOnlyTransaction();