Remove no-schema reconnect 22/103622/22
authorRobert Varga <robert.varga@pantheon.tech>
Tue, 6 Dec 2022 23:19:17 +0000 (00:19 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Fri, 9 Dec 2022 21:06:57 +0000 (22:06 +0100)
AbstractNetconfTopology has all the tools it needs to react to device's
failure to establish context, yet we use bonkers routing to the config
datastore and tickle reconnect there.

Remove this code and issue a warning when an attempt to use is made. At
some point we will reimplement this correctly.

JIRA: NETCONF-925
Change-Id: Iaf52f268d7e12f60fd2300d345fbc8c9d30a4c21
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/AbstractNetconfTopology.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/api/RemoteDeviceHandler.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDevice.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/NetconfDeviceBuilder.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceSalFacade.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/NetconfDeviceTopologyAdapter.java

index 53293c67db6931e5e3075bffd66099b145273e4a..d95a32c9e0ad04f557823d9543ebd7b8194ee428 100644 (file)
@@ -234,24 +234,25 @@ public abstract class AbstractNetconfTopology implements NetconfTopology {
             keepAliveFacade = null;
         }
 
+        // Setup reconnection on empty context, if so configured
+        if (nodeOptional != null && nodeOptional.getIgnoreMissingSchemaSources().getAllowed()) {
+            LOG.warn("Ignoring missing schema sources is not currently implemented for {}", deviceId);
+        }
+
         final RemoteDevice<NetconfDeviceCommunicator> device;
         final List<SchemaSourceRegistration<?>> yanglibRegistrations;
         if (node.requireSchemaless()) {
             device = new SchemalessNetconfDevice(baseSchemas, deviceId, salFacade);
             yanglibRegistrations = List.of();
         } else {
-            final boolean reconnectOnChangedSchema = node.requireReconnectOnChangedSchema();
             final SchemaResourcesDTO resources = schemaManager.getSchemaResources(node.getSchemaCacheDirectory(),
                 nodeId.getValue());
             device = new NetconfDeviceBuilder()
-                .setReconnectOnSchemasChange(reconnectOnChangedSchema)
+                .setReconnectOnSchemasChange(node.requireReconnectOnChangedSchema())
                 .setSchemaResourcesDTO(resources)
                 .setGlobalProcessingExecutor(processingExecutor)
                 .setId(deviceId)
                 .setSalFacade(salFacade)
-                .setNode(node)
-                .setEventExecutor(eventExecutor)
-                .setNodeOptional(nodeOptional)
                 .setDeviceActionFactory(deviceActionFactory)
                 .setBaseSchemas(baseSchemas)
                 .build();
index 650149d7e83bc20302f9b3eaafc19c31655b8f5e..e344d254ea818bcbbb63dfcd4ff8d1dd4f2e3e22 100644 (file)
@@ -11,7 +11,6 @@ import org.opendaylight.mdsal.dom.api.DOMActionService;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.mdsal.dom.api.DOMRpcService;
 import org.opendaylight.netconf.sal.connect.netconf.listener.NetconfSessionPreferences;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yangtools.rfc8528.data.api.MountPointContext;
 
 public interface RemoteDeviceHandler extends AutoCloseable {
@@ -41,10 +40,6 @@ public interface RemoteDeviceHandler extends AutoCloseable {
         // DO NOTHING
     }
 
-    default void onDeviceReconnected(final NetconfSessionPreferences sessionPreferences, final NetconfNode node) {
-        // DO NOTHING
-    }
-
     // FIXME: document this node
     void onDeviceDisconnected();
 
index bbfd411eb4f1e103ec37f6cd9f03e481728e0adc..89ce12533b035867ee049ff00f8ec407577a9ee7 100644 (file)
@@ -20,7 +20,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ListeningExecutorService;
 import com.google.common.util.concurrent.MoreExecutors;
 import com.google.common.util.concurrent.SettableFuture;
-import io.netty.util.concurrent.EventExecutor;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -29,7 +28,6 @@ import java.util.List;
 import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import org.checkerframework.checker.lock.qual.GuardedBy;
 import org.opendaylight.mdsal.dom.api.DOMRpcResult;
@@ -52,8 +50,6 @@ import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.NetconfMessag
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.NetconfNodeAugmentedOptional;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.available.capabilities.AvailableCapabilityBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.unavailable.capabilities.UnavailableCapability;
 import org.opendaylight.yangtools.concepts.Registration;
@@ -103,9 +99,6 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     private final NotificationHandler notificationHandler;
     private final boolean reconnectOnSchemasChange;
     private final BaseNetconfSchemas baseSchemas;
-    private final NetconfNode node;
-    private final EventExecutor eventExecutor;
-    private final NetconfNodeAugmentedOptional nodeOptional;
 
     @GuardedBy("this")
     private boolean connected = false;
@@ -116,22 +109,17 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemas baseSchemas,
             final RemoteDeviceId id, final RemoteDeviceHandler salFacade,
             final ListeningExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange) {
-        this(schemaResourcesDTO, baseSchemas, id, salFacade, globalProcessingExecutor, reconnectOnSchemasChange, null,
-            null, null, null);
+        this(schemaResourcesDTO, baseSchemas, id, salFacade, globalProcessingExecutor, reconnectOnSchemasChange, null);
     }
 
     public NetconfDevice(final SchemaResourcesDTO schemaResourcesDTO, final BaseNetconfSchemas baseSchemas,
             final RemoteDeviceId id, final RemoteDeviceHandler salFacade,
             final ListeningExecutorService globalProcessingExecutor, final boolean reconnectOnSchemasChange,
-            final DeviceActionFactory deviceActionFactory, final NetconfNode node, final EventExecutor eventExecutor,
-            final NetconfNodeAugmentedOptional nodeOptional) {
+            final DeviceActionFactory deviceActionFactory) {
         this.baseSchemas = requireNonNull(baseSchemas);
         this.id = id;
         this.reconnectOnSchemasChange = reconnectOnSchemasChange;
         this.deviceActionFactory = deviceActionFactory;
-        this.node = node;
-        this.eventExecutor = eventExecutor;
-        this.nodeOptional = nodeOptional;
         schemaRegistry = schemaResourcesDTO.getSchemaRegistry();
         schemaRepository = schemaResourcesDTO.getSchemaRepository();
         schemaContextFactory = schemaResourcesDTO.getSchemaContextFactory();
@@ -180,22 +168,8 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
             @Override
             public void onFailure(final Throwable cause) {
                 LOG.warn("{}: Unexpected error resolving device sources", id, cause);
-
-                // No more sources, fail or try to reconnect
-                if (cause instanceof EmptySchemaContextException) {
-                    if (nodeOptional != null && nodeOptional.getIgnoreMissingSchemaSources().getAllowed()) {
-                        eventExecutor.schedule(() -> {
-                            LOG.warn("Reconnection is allowed! This can lead to unexpected errors at runtime.");
-                            LOG.warn("{} : No more sources for schema context.", id);
-                            LOG.info("{} : Try to remount device.", id);
-                            onRemoteSessionDown();
-                            salFacade.onDeviceReconnected(remoteSessionCapabilities, node);
-                        }, nodeOptional.getIgnoreMissingSchemaSources().getReconnectTime().toJava(),
-                            TimeUnit.MILLISECONDS);
-                        return;
-                    }
-                }
-
+                // FIXME: this causes salFacade to see onDeviceDisconnected() and then onDeviceFailed(), which is quite
+                //        weird
                 handleSalInitializationFailure(cause, listener);
                 salFacade.onDeviceFailed(cause);
             }
@@ -395,14 +369,12 @@ public class NetconfDevice implements RemoteDevice<NetconfDeviceCommunicator> {
     }
 
     /**
-     * A dedicated exception to indicate when we fail to setup a SchemaContext.
-     *
-     * @author Robert Varga
+     * A dedicated exception to indicate when we fail to setup an {@link EffectiveModelContext}.
      */
-    private static final class EmptySchemaContextException extends Exception {
+    public static final class EmptySchemaContextException extends Exception {
         private static final long serialVersionUID = 1L;
 
-        EmptySchemaContextException(final String message) {
+        public EmptySchemaContextException(final String message) {
             super(message);
         }
     }
index 2f77159b6bdf6fdcf90578c8d1d416cdcf04556e..90612f86d9e5a3b03ae2e7f9992ea9a23961ccda 100644 (file)
@@ -10,25 +10,19 @@ package org.opendaylight.netconf.sal.connect.netconf;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.util.concurrent.ListeningExecutorService;
-import io.netty.util.concurrent.EventExecutor;
 import org.opendaylight.netconf.sal.connect.api.DeviceActionFactory;
 import org.opendaylight.netconf.sal.connect.api.RemoteDeviceHandler;
+import org.opendaylight.netconf.sal.connect.netconf.NetconfDevice.SchemaResourcesDTO;
 import org.opendaylight.netconf.sal.connect.netconf.schema.mapping.BaseNetconfSchemas;
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev190614.NetconfNodeAugmentedOptional;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
 
 public class NetconfDeviceBuilder {
-
     private boolean reconnectOnSchemasChange;
-    private NetconfDevice.SchemaResourcesDTO schemaResourcesDTO;
+    private SchemaResourcesDTO schemaResourcesDTO;
     private RemoteDeviceId id;
     private RemoteDeviceHandler salFacade;
     private ListeningExecutorService globalProcessingExecutor;
     private DeviceActionFactory deviceActionFactory;
-    private NetconfNode node;
-    private EventExecutor eventExecutor;
-    private NetconfNodeAugmentedOptional nodeOptional;
     private BaseNetconfSchemas baseSchemas;
 
     public NetconfDeviceBuilder() {
@@ -44,7 +38,7 @@ public class NetconfDeviceBuilder {
         return this;
     }
 
-    public NetconfDeviceBuilder setSchemaResourcesDTO(final NetconfDevice.SchemaResourcesDTO schemaResourcesDTO) {
+    public NetconfDeviceBuilder setSchemaResourcesDTO(final SchemaResourcesDTO schemaResourcesDTO) {
         this.schemaResourcesDTO = schemaResourcesDTO;
         return this;
     }
@@ -64,21 +58,6 @@ public class NetconfDeviceBuilder {
         return this;
     }
 
-    public NetconfDeviceBuilder setNode(final NetconfNode node) {
-        this.node = node;
-        return this;
-    }
-
-    public NetconfDeviceBuilder setEventExecutor(final EventExecutor eventExecutor) {
-        this.eventExecutor = eventExecutor;
-        return this;
-    }
-
-    public NetconfDeviceBuilder setNodeOptional(final NetconfNodeAugmentedOptional nodeOptional) {
-        this.nodeOptional = nodeOptional;
-        return this;
-    }
-
     public NetconfDeviceBuilder setBaseSchemas(final BaseNetconfSchemas baseSchemas) {
         this.baseSchemas = requireNonNull(baseSchemas);
         return this;
@@ -87,8 +66,7 @@ public class NetconfDeviceBuilder {
     public NetconfDevice build() {
         validation();
         return new NetconfDevice(schemaResourcesDTO, baseSchemas, id, salFacade,
-            globalProcessingExecutor, reconnectOnSchemasChange, deviceActionFactory, node,
-            eventExecutor, nodeOptional);
+            globalProcessingExecutor, reconnectOnSchemasChange, deviceActionFactory);
     }
 
     private void validation() {
index eb709158f85dda8b43080306d585cac9c8736bd4..a75775e0292a2511110e9414380ed8e8b07e5b82 100644 (file)
@@ -26,8 +26,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.optional.rev19
 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.opendaylight.netconf.node.topology.rev150114.NetconfNode;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus;
 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;
@@ -85,13 +83,6 @@ public final class NetconfDeviceSalFacade implements RemoteDeviceHandler, AutoCl
                 .updateDeviceData(true, netconfSessionPreferences.getNetconfDeviceCapabilities());
     }
 
-    @Override
-    public synchronized void onDeviceReconnected(final NetconfSessionPreferences netconfSessionPreferences,
-            final NetconfNode node) {
-        salProvider.getTopologyDatastoreAdapter().updateDeviceData(ConnectionStatus.Connecting,
-                netconfSessionPreferences.getNetconfDeviceCapabilities(), LogicalDatastoreType.CONFIGURATION, node);
-    }
-
     @Override
     public synchronized void onDeviceDisconnected() {
         salProvider.getTopologyDatastoreAdapter().updateDeviceData(false, new NetconfDeviceCapabilities());
index 0b6ec1ebe0017d19db835579c2e873ef3502a4fd..31c4dd58c743162654cbe1f6da3145196f6ec884 100644 (file)
@@ -69,30 +69,21 @@ public final class NetconfDeviceTopologyAdapter implements TransactionChainListe
         commitTransaction(writeTx, "init");
     }
 
-    public void updateDeviceData(final ConnectionStatus connectionStatus,
-            final NetconfDeviceCapabilities capabilities, final LogicalDatastoreType dsType, final NetconfNode node) {
-        NetconfNode data;
-        if (node != null && dsType == LogicalDatastoreType.CONFIGURATION) {
-            data = node;
-        } else {
-            data = newNetconfNodeBuilder(connectionStatus, capabilities).build();
-        }
-
+    public void updateDeviceData(final boolean up, final NetconfDeviceCapabilities capabilities) {
         final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
         LOG.trace("{}: Update device state transaction {} merging operational data started.",
                 id, writeTx.getIdentifier());
-        writeTx.mergeParentStructurePut(dsType, id.getTopologyBindingPath().augmentation(NetconfNode.class), data);
+
+        // FIXME: this needs to be tied together with node's operational existence
+        writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL,
+            id.getTopologyBindingPath().augmentation(NetconfNode.class),
+            newNetconfNodeBuilder(up, capabilities).build());
         LOG.trace("{}: Update device state transaction {} merging operational data ended.",
                 id, writeTx.getIdentifier());
 
         commitTransaction(writeTx, "update");
     }
 
-    public void updateDeviceData(final boolean up, final NetconfDeviceCapabilities capabilities) {
-        updateDeviceData(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting, capabilities,
-                LogicalDatastoreType.OPERATIONAL, null);
-    }
-
     public void updateClusteredDeviceData(final boolean up, final String masterAddress,
                                           final NetconfDeviceCapabilities capabilities) {
         final WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
@@ -100,7 +91,7 @@ public final class NetconfDeviceTopologyAdapter implements TransactionChainListe
                 id, writeTx.getIdentifier());
         writeTx.mergeParentStructurePut(LogicalDatastoreType.OPERATIONAL,
             id.getTopologyBindingPath().augmentation(NetconfNode.class),
-            newNetconfNodeBuilder(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting, capabilities)
+            newNetconfNodeBuilder(up, capabilities)
                 .setClusteredConnectionStatus(new ClusteredConnectionStatusBuilder()
                     .setNetconfMasterNode(masterAddress)
                     .build())
@@ -149,12 +140,11 @@ public final class NetconfDeviceTopologyAdapter implements TransactionChainListe
         commitTransaction(writeTx, "update-failed-device");
     }
 
-    private NetconfNodeBuilder newNetconfNodeBuilder(final ConnectionStatus connectionStatus,
-            final NetconfDeviceCapabilities capabilities) {
+    private NetconfNodeBuilder newNetconfNodeBuilder(final boolean up, final NetconfDeviceCapabilities capabilities) {
         return new NetconfNodeBuilder()
             .setHost(id.getHost())
             .setPort(new PortNumber(Uint16.valueOf(id.getAddress().getPort())))
-            .setConnectionStatus(connectionStatus)
+            .setConnectionStatus(up ? ConnectionStatus.Connected : ConnectionStatus.Connecting)
             .setAvailableCapabilities(new AvailableCapabilitiesBuilder()
                 .setAvailableCapability(ImmutableList.<AvailableCapability>builder()
                     .addAll(capabilities.getNonModuleBasedCapabilities())