NetconfTopologyManager and UT mods/improvements
[netconf.git] / netconf / netconf-topology-singleton / src / main / java / org / opendaylight / netconf / topology / singleton / impl / NetconfTopologyContext.java
index 8b2ccf66afb6719d21c7b0f56b8de1c0d99f13fa..d8df4c36f5f97a4672e9563cce20a011c2710872 100644 (file)
@@ -18,7 +18,9 @@ import akka.util.Timeout;
 import com.google.common.base.Preconditions;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.concurrent.atomic.AtomicBoolean;
 import javax.annotation.Nonnull;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
 import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
@@ -32,34 +34,36 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import scala.concurrent.Future;
 
-class NetconfTopologyContext implements ClusterSingletonService {
+class NetconfTopologyContext implements ClusterSingletonService, AutoCloseable {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfTopologyContext.class);
 
     private final ServiceGroupIdentifier serviceGroupIdent;
     private final Timeout actorResponseWaitTime;
+    private final DOMMountPointService mountService;
+
     private NetconfTopologySetup netconfTopologyDeviceSetup;
     private RemoteDeviceId remoteDeviceId;
     private RemoteDeviceConnector remoteDeviceConnector;
     private NetconfNodeManager netconfNodeManager;
-    private boolean finalClose = false;
-    private boolean closed = false;
-    private boolean isMaster;
-
     private ActorRef masterActorRef;
+    private final AtomicBoolean closed = new AtomicBoolean(false);
+    private final AtomicBoolean stopped = new AtomicBoolean(false);
+    private volatile boolean isMaster;
 
     NetconfTopologyContext(final NetconfTopologySetup netconfTopologyDeviceSetup,
                            final ServiceGroupIdentifier serviceGroupIdent,
-                           final Timeout actorResponseWaitTime) {
+                           final Timeout actorResponseWaitTime, final DOMMountPointService mountService) {
         this.netconfTopologyDeviceSetup = Preconditions.checkNotNull(netconfTopologyDeviceSetup);
         this.serviceGroupIdent = serviceGroupIdent;
         this.actorResponseWaitTime = actorResponseWaitTime;
+        this.mountService = mountService;
 
         remoteDeviceId = NetconfTopologyUtils.createRemoteDeviceId(netconfTopologyDeviceSetup.getNode().getNodeId(),
                 netconfTopologyDeviceSetup.getNode().getAugmentation(NetconfNode.class));
 
         remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId,
-                actorResponseWaitTime);
+                actorResponseWaitTime, mountService);
 
         netconfNodeManager = createNodeDeviceManager();
     }
@@ -76,11 +80,12 @@ class NetconfTopologyContext implements ClusterSingletonService {
             netconfNodeManager = null;
         }
 
-        if (!finalClose) {
-            final String masterAddress = Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString();
+        if (!closed.get()) {
+            final String masterAddress =
+                    Cluster.get(netconfTopologyDeviceSetup.getActorSystem()).selfAddress().toString();
             masterActorRef = netconfTopologyDeviceSetup.getActorSystem().actorOf(NetconfNodeActor.props(
                     netconfTopologyDeviceSetup, remoteDeviceId, DEFAULT_SCHEMA_REPOSITORY, DEFAULT_SCHEMA_REPOSITORY,
-                    actorResponseWaitTime),
+                    actorResponseWaitTime, mountService),
                     NetconfTopologyUtils.createMasterActorName(remoteDeviceId.getName(), masterAddress));
 
             remoteDeviceConnector.startRemoteDeviceConnection(masterActorRef);
@@ -92,13 +97,13 @@ class NetconfTopologyContext implements ClusterSingletonService {
     @Override
     public ListenableFuture<Void> closeServiceInstance() {
 
-        if (!finalClose) {
+        if (!closed.get()) {
             // in case that master changes role to slave, new NodeDeviceManager must be created and listener registered
             netconfNodeManager = createNodeDeviceManager();
         }
         stopDeviceConnectorAndActor();
 
-        return Futures.immediateCheckedFuture(null);
+        return Futures.immediateFuture(null);
     }
 
     @Override
@@ -108,15 +113,18 @@ class NetconfTopologyContext implements ClusterSingletonService {
 
     private NetconfNodeManager createNodeDeviceManager() {
         final NetconfNodeManager ndm =
-                new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime);
+                new NetconfNodeManager(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime, mountService);
         ndm.registerDataTreeChangeListener(netconfTopologyDeviceSetup.getTopologyId(),
                 netconfTopologyDeviceSetup.getNode().getKey());
 
         return ndm;
     }
 
-    void closeFinal() throws Exception {
-        finalClose = true;
+    @Override
+    public void close() throws Exception {
+        if (!closed.compareAndSet(false, true)) {
+            return;
+        }
 
         if (netconfNodeManager != null) {
             netconfNodeManager.close();
@@ -126,7 +134,7 @@ class NetconfTopologyContext implements ClusterSingletonService {
     }
 
     /**
-     * If configuration data was changed
+     * Refresh, if configuration data was changed.
      * @param setup new setup
      */
     void refresh(@Nonnull final NetconfTopologySetup setup) {
@@ -140,7 +148,8 @@ class NetconfTopologyContext implements ClusterSingletonService {
         if (!isMaster) {
             netconfNodeManager.refreshDevice(netconfTopologyDeviceSetup, remoteDeviceId);
         }
-        remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId, actorResponseWaitTime);
+        remoteDeviceConnector = new RemoteDeviceConnectorImpl(netconfTopologyDeviceSetup, remoteDeviceId,
+                actorResponseWaitTime, mountService);
 
         if (isMaster) {
             final Future<Object> future = Patterns.ask(masterActorRef, new RefreshSetupMasterActorData(
@@ -159,8 +168,8 @@ class NetconfTopologyContext implements ClusterSingletonService {
         }
     }
 
-    private synchronized void stopDeviceConnectorAndActor() {
-        if (closed) {
+    private void stopDeviceConnectorAndActor() {
+        if (!stopped.compareAndSet(false, true)) {
             return;
         }
         if (remoteDeviceConnector != null) {
@@ -171,6 +180,5 @@ class NetconfTopologyContext implements ClusterSingletonService {
             netconfTopologyDeviceSetup.getActorSystem().stop(masterActorRef);
             masterActorRef = null;
         }
-        closed = true;
     }
 }