Bug 8032 - Initialization in sal failed, disconnecting from device
[netconf.git] / netconf / netconf-topology-singleton / src / main / java / org / opendaylight / netconf / topology / singleton / impl / actors / NetconfNodeActor.java
index 9828e2476fcf7931295fbad29943b067e623548f..f04430f6660d02ad9898b9097b97856d4862158d 100644 (file)
@@ -17,6 +17,7 @@ import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import java.io.IOException;
 import java.util.List;
+import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.opendaylight.controller.cluster.schema.provider.RemoteYangTextSourceProvider;
@@ -25,6 +26,7 @@ import org.opendaylight.controller.cluster.schema.provider.impl.YangTextSchemaSo
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
+import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
@@ -59,42 +61,52 @@ import org.opendaylight.yangtools.yang.model.repo.api.SchemaSourceFilter;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
 import org.opendaylight.yangtools.yang.model.repo.spi.PotentialSchemaSource;
+import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistration;
 import org.opendaylight.yangtools.yang.model.repo.spi.SchemaSourceRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import scala.concurrent.duration.Duration;
 
 public class NetconfNodeActor extends UntypedActor {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfNodeActor.class);
 
-    private NetconfTopologySetup setup;
-    private RemoteDeviceId id;
     private final SchemaSourceRegistry schemaRegistry;
     private final SchemaRepository schemaRepository;
+    private final Timeout actorResponseWaitTime;
+    private final Duration writeTxIdleTimeout;
+    private final DOMMountPointService mountPointService;
 
+    private RemoteDeviceId id;
+    private NetconfTopologySetup setup;
     private List<SourceIdentifier> sourceIdentifiers;
     private DOMRpcService deviceRpc;
     private SlaveSalFacade slaveSalManager;
-    private final Timeout actorResponseWaitTime;
     private DOMDataBroker deviceDataBroker;
     //readTxActor can be shared
     private ActorRef readTxActor;
+    private List<SchemaSourceRegistration<YangTextSchemaSource>> registeredSchemas;
 
     public static Props props(final NetconfTopologySetup setup,
                               final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
-                              final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime) {
+                              final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime,
+                              final DOMMountPointService mountPointService) {
         return Props.create(NetconfNodeActor.class, () ->
-                new NetconfNodeActor(setup, id, schemaRegistry, schemaRepository, actorResponseWaitTime));
+                new NetconfNodeActor(setup, id, schemaRegistry, schemaRepository, actorResponseWaitTime,
+                        mountPointService));
     }
 
     private NetconfNodeActor(final NetconfTopologySetup setup,
                              final RemoteDeviceId id, final SchemaSourceRegistry schemaRegistry,
-                             final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime) {
+                             final SchemaRepository schemaRepository, final Timeout actorResponseWaitTime,
+                             final DOMMountPointService mountPointService) {
         this.setup = setup;
         this.id = id;
         this.schemaRegistry = schemaRegistry;
         this.schemaRepository = schemaRepository;
         this.actorResponseWaitTime = actorResponseWaitTime;
+        this.writeTxIdleTimeout = setup.getIdleTimeout();
+        this.mountPointService = mountPointService;
     }
 
     @Override
@@ -134,7 +146,7 @@ public class NetconfNodeActor extends UntypedActor {
         } else if (message instanceof NewWriteTransactionRequest) { // master
             try {
                 final DOMDataWriteTransaction tx = deviceDataBroker.newWriteOnlyTransaction();
-                final ActorRef txActor = context().actorOf(WriteTransactionActor.props(tx));
+                final ActorRef txActor = context().actorOf(WriteTransactionActor.props(tx, writeTxIdleTimeout));
                 sender().tell(new NewWriteTransactionReply(txActor), self());
             } catch (final Throwable t) {
                 sender().tell(t, self());
@@ -159,6 +171,11 @@ public class NetconfNodeActor extends UntypedActor {
         }
     }
 
+    @Override
+    public void postStop() throws Exception {
+        super.postStop();
+        closeSchemaSourceRegistrations();
+    }
 
     private void sendYangTextSchemaSourceProxy(final SourceIdentifier sourceIdentifier, final ActorRef sender) {
         final CheckedFuture<YangTextSchemaSource, SchemaSourceException> yangTextSchemaSource =
@@ -213,7 +230,9 @@ public class NetconfNodeActor extends UntypedActor {
         if (this.slaveSalManager != null) {
             slaveSalManager.close();
         }
-        slaveSalManager = new SlaveSalFacade(id, setup.getDomBroker(), setup.getActorSystem(), actorResponseWaitTime);
+        closeSchemaSourceRegistrations();
+        slaveSalManager = new SlaveSalFacade(id, setup.getActorSystem(), actorResponseWaitTime,
+                mountPointService);
 
         final CheckedFuture<SchemaContext, SchemaResolutionException> remoteSchemaContext =
                 getSchemaContext(masterReference);
@@ -244,9 +263,11 @@ public class NetconfNodeActor extends UntypedActor {
         final RemoteSchemaProvider remoteProvider = new RemoteSchemaProvider(remoteYangTextSourceProvider,
                 getContext().dispatcher());
 
-        sourceIdentifiers.forEach(sourceId ->
-                schemaRegistry.registerSchemaSource(remoteProvider, PotentialSchemaSource.create(sourceId,
-                        YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())));
+        registeredSchemas = sourceIdentifiers.stream()
+                .map(sourceId ->
+                        schemaRegistry.registerSchemaSource(remoteProvider, PotentialSchemaSource.create(sourceId,
+                                YangTextSchemaSource.class, PotentialSchemaSource.Costs.REMOTE_IO.getValue())))
+                .collect(Collectors.toList());
 
         final SchemaContextFactory schemaContextFactory
                 = schemaRepository.createSchemaContextFactory(SchemaSourceFilter.ALWAYS_ACCEPT);
@@ -254,4 +275,11 @@ public class NetconfNodeActor extends UntypedActor {
         return schemaContextFactory.createSchemaContext(sourceIdentifiers);
     }
 
+    private void closeSchemaSourceRegistrations() {
+        if (registeredSchemas != null) {
+            registeredSchemas.forEach(SchemaSourceRegistration::close);
+            registeredSchemas = null;
+        }
+    }
+
 }