From 65cf3424af5febb8f9f7995c4562cbff9e3551c0 Mon Sep 17 00:00:00 2001 From: Jakub Toth Date: Fri, 14 Jun 2019 11:32:00 -0400 Subject: [PATCH] Netconf stack by default locks the data store before issuing edit-config, and then unlocks it. This poses some scalabilty issues when multiple requests for the same device arrives. Also some devices automatically queues the requests at the device itself. The patch provides an option to allow lock/unlock operations for edit-config. Default value is true which defaults to today's behavior. JIRA: NETCONF-629 Change-Id: I0531b27c0807dfb586f9e80c9b9fc9b189e3cadf Signed-off-by: Jakub Toth --- .../callhome/mount/CallHomeTopology.java | 2 +- .../topology/impl/NetconfTopologyImpl.java | 2 +- .../netconf/sal/LockChangeListener.java | 52 +++++++++++++++++ .../netconf/sal/NetconfDeviceDataBroker.java | 15 +++-- .../netconf/sal/NetconfDeviceSalFacade.java | 56 ++++++++++++++++--- .../netconf/sal/tx/AbstractWriteTx.java | 7 ++- .../sal/tx/WriteCandidateRunningTx.java | 19 ++++++- .../netconf/sal/tx/WriteCandidateTx.java | 19 ++++++- .../netconf/sal/tx/WriteRunningTx.java | 19 ++++++- .../src/main/yang/netconf-node-optional.yang | 44 +++++++++++++++ .../sal/NetconfDeviceSalFacadeTest.java | 6 +- 11 files changed, 214 insertions(+), 27 deletions(-) create mode 100644 netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/LockChangeListener.java create mode 100644 netconf/sal-netconf-connector/src/main/yang/netconf-node-optional.yang diff --git a/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java b/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java index 84c743ea66..e032637cd8 100644 --- a/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java +++ b/netconf/callhome-provider/src/main/java/org/opendaylight/netconf/callhome/mount/CallHomeTopology.java @@ -48,6 +48,6 @@ public class CallHomeTopology extends BaseCallHomeTopology { @Override protected RemoteDeviceHandler createSalFacade(final RemoteDeviceId id) { - return new NetconfDeviceSalFacade(id, mountPointService, dataBroker); + return new NetconfDeviceSalFacade(id, mountPointService, dataBroker, topologyId); } } diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java index 995ca6583e..c4c2196f93 100644 --- a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java +++ b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/impl/NetconfTopologyImpl.java @@ -87,7 +87,7 @@ public class NetconfTopologyImpl extends AbstractNetconfTopology @Override protected RemoteDeviceHandler createSalFacade(final RemoteDeviceId id) { - return new NetconfDeviceSalFacade(id, mountPointService, dataBroker); + return new NetconfDeviceSalFacade(id, mountPointService, dataBroker, topologyId); } /** diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/LockChangeListener.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/LockChangeListener.java new file mode 100644 index 0000000000..2092057d48 --- /dev/null +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/LockChangeListener.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 Lumina Networks, Inc. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.sal.connect.netconf.sal; + +import java.util.Collection; +import org.opendaylight.mdsal.binding.api.DataObjectModification; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.dom.api.DOMDataBroker; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.topology.node.DatastoreLock; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class LockChangeListener implements DataTreeChangeListener { + + private static final Logger LOG = LoggerFactory.getLogger(LockChangeListener.class); + + private final NetconfDeviceDataBroker netconfDeviceDataBroker; + + LockChangeListener(final DOMDataBroker netconfDeviceDataBrokder) { + this.netconfDeviceDataBroker = (NetconfDeviceDataBroker)netconfDeviceDataBrokder; + } + + @Override + public void onDataTreeChanged(final Collection> changes) { + for (final DataTreeModification change : changes) { + final DataObjectModification rootNode = change.getRootNode(); + switch (rootNode.getModificationType()) { + case SUBTREE_MODIFIED: + case WRITE: + if (!rootNode.getDataAfter().isDatastoreLockAllowed()) { + LOG.warn("With blocking the lock/unlock operations, the user is coming to" + + "operate in a manner which is not supported. It must not exist" + + "any concurrent access to the data store - it may interfere with" + + "data consistency."); + } + netconfDeviceDataBroker.setLockAllowed(rootNode.getDataAfter().isDatastoreLockAllowed()); + break; + case DELETE: + netconfDeviceDataBroker.setLockAllowed(true); + break; + default: + LOG.debug("Unsupported modification type: {}.", rootNode.getModificationType()); + } + } + } +} diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java index 694e120ae2..57c27280bd 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceDataBroker.java @@ -30,13 +30,15 @@ import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; import org.opendaylight.yangtools.yang.model.api.SchemaContext; public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBroker { + private final RemoteDeviceId id; private final NetconfBaseOps netconfOps; - private final boolean rollbackSupport; private final boolean candidateSupported; private final boolean runningWritable; + private boolean isLockAllowed = true; + public NetconfDeviceDataBroker(final RemoteDeviceId id, final SchemaContext schemaContext, final DOMRpcService rpc, final NetconfSessionPreferences netconfSessionPreferences) { this.id = id; @@ -65,12 +67,12 @@ public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBrok public DOMDataTreeWriteTransaction newWriteOnlyTransaction() { if (candidateSupported) { if (runningWritable) { - return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport); + return new WriteCandidateRunningTx(id, netconfOps, rollbackSupport, isLockAllowed); } else { - return new WriteCandidateTx(id, netconfOps, rollbackSupport); + return new WriteCandidateTx(id, netconfOps, rollbackSupport, isLockAllowed); } } else { - return new WriteRunningTx(id, netconfOps, rollbackSupport); + return new WriteRunningTx(id, netconfOps, rollbackSupport, isLockAllowed); } } @@ -83,4 +85,9 @@ public final class NetconfDeviceDataBroker implements PingPongMergingDOMDataBrok public ClassToInstanceMap getExtensions() { return ImmutableClassToInstanceMap.of(); } + + void setLockAllowed(boolean isLockAllowedOrig) { + this.isLockAllowed = isLockAllowedOrig; + } + } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java index 74378ce938..7f9c5cd65a 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java @@ -12,8 +12,9 @@ import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.List; import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; import org.opendaylight.mdsal.dom.api.DOMActionService; -import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMMountPointService; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; @@ -21,6 +22,16 @@ import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfDeviceCapabilities; import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences; import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.NetconfNodeFieldsOptional; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.Topology; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.TopologyKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.topology.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.topology.NodeKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.netconf.node.fields.optional.topology.node.DatastoreLock; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; +import org.opendaylight.yangtools.concepts.ListenerRegistration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,17 +43,23 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice private final RemoteDeviceId id; private final NetconfDeviceSalProvider salProvider; private final List salRegistrations = new ArrayList<>(); + private final DataBroker dataBroker; + private final String topologyId; + + private ListenerRegistration listenerRegistration = null; public NetconfDeviceSalFacade(final RemoteDeviceId id, final DOMMountPointService mountPointService, - final DataBroker dataBroker) { - this.id = id; - this.salProvider = new NetconfDeviceSalProvider(id, mountPointService, dataBroker); + final DataBroker dataBroker, final String topologyId) { + this(id, new NetconfDeviceSalProvider(id, mountPointService, dataBroker), dataBroker, topologyId); } @VisibleForTesting - NetconfDeviceSalFacade(final RemoteDeviceId id, final NetconfDeviceSalProvider salProvider) { + NetconfDeviceSalFacade(final RemoteDeviceId id, final NetconfDeviceSalProvider salProvider, + final DataBroker dataBroker, final String topologyId) { this.id = id; this.salProvider = salProvider; + this.dataBroker = dataBroker; + this.topologyId = topologyId; } @Override @@ -55,13 +72,14 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice final NetconfSessionPreferences netconfSessionPreferences, final DOMRpcService deviceRpc, final DOMActionService deviceAction) { - final DOMDataBroker domBroker = + final NetconfDeviceDataBroker netconfDeviceDataBroker = new NetconfDeviceDataBroker(id, schemaContext, deviceRpc, netconfSessionPreferences); - + registerLockListener(netconfDeviceDataBroker); final NetconfDeviceNotificationService notificationService = new NetconfDeviceNotificationService(); salProvider.getMountInstance() - .onTopologyDeviceConnected(schemaContext, domBroker, deviceRpc, notificationService, deviceAction); + .onTopologyDeviceConnected(schemaContext, netconfDeviceDataBroker, deviceRpc, notificationService, + deviceAction); salProvider.getTopologyDatastoreAdapter() .updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities()); } @@ -70,12 +88,14 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice public synchronized void onDeviceDisconnected() { salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, new NetconfDeviceCapabilities()); salProvider.getMountInstance().onTopologyDeviceDisconnected(); + closeLockChangeListener(); } @Override public synchronized void onDeviceFailed(final Throwable throwable) { salProvider.getTopologyDatastoreAdapter().setDeviceAsFailed(throwable); salProvider.getMountInstance().onTopologyDeviceDisconnected(); + closeLockChangeListener(); } @Override @@ -84,6 +104,7 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice closeGracefully(reg); } closeGracefully(salProvider); + closeLockChangeListener(); } @SuppressWarnings("checkstyle:IllegalCatch") @@ -97,4 +118,23 @@ public final class NetconfDeviceSalFacade implements AutoCloseable, RemoteDevice } } + private void closeLockChangeListener() { + if (listenerRegistration != null) { + listenerRegistration.close(); + } + } + + private void registerLockListener(final NetconfDeviceDataBroker netconfDeviceDataBroker) { + listenerRegistration = dataBroker.registerDataTreeChangeListener( + DataTreeIdentifier.create(LogicalDatastoreType.CONFIGURATION, createTopologyListPath()), + new LockChangeListener(netconfDeviceDataBroker)); + } + + private InstanceIdentifier createTopologyListPath() { + return InstanceIdentifier.create(NetconfNodeFieldsOptional.class) + .child(Topology.class, new TopologyKey(new TopologyId(topologyId))) + .child(Node.class, new NodeKey(new NodeId(id.getName()))) + .child(DatastoreLock.class); + + } } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/AbstractWriteTx.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/AbstractWriteTx.java index c1d3efc89a..06ffd70e92 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/AbstractWriteTx.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/AbstractWriteTx.java @@ -52,11 +52,14 @@ public abstract class AbstractWriteTx implements DOMDataTreeWriteTransaction { private final List listeners = new CopyOnWriteArrayList<>(); // Allow commit to be called only once protected volatile boolean finished = false; + protected final boolean isLockAllowed; - public AbstractWriteTx(final NetconfBaseOps netOps, final RemoteDeviceId id, final boolean rollbackSupport) { - this.netOps = netOps; + public AbstractWriteTx(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport, + final boolean isLockAllowed) { + this.netOps = netconfOps; this.id = id; this.rollbackSupport = rollbackSupport; + this.isLockAllowed = isLockAllowed; init(); } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java index b5198ec836..fefddc5720 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateRunningTx.java @@ -27,7 +27,12 @@ public class WriteCandidateRunningTx extends WriteCandidateTx { public WriteCandidateRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport) { - super(id, netOps, rollbackSupport); + this(id, netOps, rollbackSupport, true); + } + + public WriteCandidateRunningTx(RemoteDeviceId id, NetconfBaseOps netconfOps, boolean rollbackSupport, + boolean isLockAllowed) { + super(id, netconfOps, rollbackSupport, isLockAllowed); } @Override @@ -43,7 +48,11 @@ public class WriteCandidateRunningTx extends WriteCandidateTx { } private void lockRunning() { - resultsFutures.add(netOps.lockRunning(new NetconfRpcFutureCallback("Lock running", id))); + if (isLockAllowed) { + resultsFutures.add(netOps.lockRunning(new NetconfRpcFutureCallback("Lock running", id))); + } else { + LOG.trace("Lock is not allowed: {}", id); + } } /** @@ -51,6 +60,10 @@ public class WriteCandidateRunningTx extends WriteCandidateTx { * and its netty threadpool that is really sensitive to blocking calls. */ private void unlockRunning() { - netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id)); + if (isLockAllowed) { + netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id)); + } else { + LOG.trace("Unlock is not allowed: {}", id); + } } } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java index 8657c11998..9bdf7e9974 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteCandidateTx.java @@ -49,8 +49,13 @@ public class WriteCandidateTx extends AbstractWriteTx { private static final Logger LOG = LoggerFactory.getLogger(WriteCandidateTx.class); - public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps rpc, final boolean rollbackSupport) { - super(rpc, id, rollbackSupport); + public WriteCandidateTx(final RemoteDeviceId id, final NetconfBaseOps netconfOps, final boolean rollbackSupport) { + this(id, netconfOps, rollbackSupport, true); + } + + public WriteCandidateTx(RemoteDeviceId id, NetconfBaseOps netconfOps, boolean rollbackSupport, + boolean isLockAllowed) { + super(id, netconfOps, rollbackSupport, isLockAllowed); } @Override @@ -60,6 +65,10 @@ public class WriteCandidateTx extends AbstractWriteTx { } private void lock() { + if (!isLockAllowed) { + LOG.trace("Lock is not allowed."); + return; + } final FutureCallback lockCandidateCallback = new FutureCallback() { @Override public void onSuccess(final DOMRpcResult result) { @@ -143,7 +152,11 @@ public class WriteCandidateTx extends AbstractWriteTx { * and its netty threadpool that is really sensitive to blocking calls. */ private void unlock() { - netOps.unlockCandidate(new NetconfRpcFutureCallback("Unlock candidate", id)); + if (isLockAllowed) { + netOps.unlockCandidate(new NetconfRpcFutureCallback("Unlock candidate", id)); + } else { + LOG.trace("Unlock is not allowed: {}", id); + } } } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTx.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTx.java index 0386a1a546..d88acbfcd2 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTx.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/tx/WriteRunningTx.java @@ -47,7 +47,12 @@ public class WriteRunningTx extends AbstractWriteTx { public WriteRunningTx(final RemoteDeviceId id, final NetconfBaseOps netOps, final boolean rollbackSupport) { - super(netOps, id, rollbackSupport); + this(id, netOps, rollbackSupport, true); + } + + public WriteRunningTx(RemoteDeviceId id, NetconfBaseOps netconfOps, boolean rollbackSupport, + boolean isLockAllowed) { + super(id, netconfOps, rollbackSupport, isLockAllowed); } @Override @@ -56,7 +61,11 @@ public class WriteRunningTx extends AbstractWriteTx { } private void lock() { - resultsFutures.add(netOps.lockRunning(new NetconfRpcFutureCallback("Lock running", id))); + if (isLockAllowed) { + resultsFutures.add(netOps.lockRunning(new NetconfRpcFutureCallback("Lock running", id))); + } else { + LOG.trace("Lock is not allowed: {}", id); + } } @Override @@ -83,7 +92,11 @@ public class WriteRunningTx extends AbstractWriteTx { } private void unlock() { - netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id)); + if (isLockAllowed) { + netOps.unlockRunning(new NetconfRpcFutureCallback("Unlock running", id)); + } else { + LOG.trace("Unlock is not allowed: {}", id); + } } private static final class Change { diff --git a/netconf/sal-netconf-connector/src/main/yang/netconf-node-optional.yang b/netconf/sal-netconf-connector/src/main/yang/netconf-node-optional.yang new file mode 100644 index 0000000000..0bcf0374ca --- /dev/null +++ b/netconf/sal-netconf-connector/src/main/yang/netconf-node-optional.yang @@ -0,0 +1,44 @@ +module netconf-node-optional { + namespace "urn:opendaylight:netconf-node-optional"; + prefix "netnopt"; + + import network-topology { prefix nt; revision-date 2013-10-21; } + + revision "2019-06-14" { + description "Initial revision of Node Locking model"; + } + + container netconf-node-fields-optional { + description "Allows to create node's optional value with the path mapping according to + the network-topology -> topology -> node"; + list topology { + key topology-id; + leaf topology-id { + type nt:topology-id; + description "The name of node's topology"; + } + list node { + key node-id; + leaf node-id { + type nt:node-id; + description "The identifier of a node in the topology"; + } + // Containers allow to create specific data-change-listener directly on a node's optional value. + // In the future, it'll be easy to extend the node by optional node fields in this way. Do not create + // direct leafs here, please. + container datastore-lock { + description "Allows to ignore lock/unlock node's datastare."; + leaf datastore-lock-allowed { + type boolean; + default true; + description "The operation allows the client to lock the entire configuration datastore + system of a device. + WARNING - With blocking the lock/unlock operations, the user is coming to operate + in a manner which is not supported. It must not exist any concurrent access to + the data store - it may interfere with data consistency."; + } + } + } + } + } +} diff --git a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java index 7ff31fbd9e..69f491dfe6 100644 --- a/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java +++ b/netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacadeTest.java @@ -24,6 +24,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; +import org.opendaylight.mdsal.binding.api.DataBroker; import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMNotification; import org.opendaylight.mdsal.dom.api.DOMRpcService; @@ -41,9 +42,10 @@ public class NetconfDeviceSalFacadeTest { private NetconfDeviceTopologyAdapter netconfDeviceTopologyAdapter; @Mock private NetconfDeviceSalProvider.MountInstance mountInstance; - @Mock private NetconfDeviceSalProvider salProvider; + @Mock + private DataBroker dataBroker; @Before public void setUp() throws Exception { @@ -51,7 +53,7 @@ public class NetconfDeviceSalFacadeTest { final InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8000); final RemoteDeviceId remoteDeviceId = new RemoteDeviceId("test", address); - deviceFacade = new NetconfDeviceSalFacade(remoteDeviceId, salProvider); + deviceFacade = new NetconfDeviceSalFacade(remoteDeviceId, salProvider, dataBroker, "mockTopo"); doReturn(netconfDeviceTopologyAdapter).when(salProvider).getTopologyDatastoreAdapter(); doNothing().when(netconfDeviceTopologyAdapter) -- 2.36.6