From: Balaji Varadaraju Date: Thu, 15 Feb 2018 07:53:20 +0000 (-0600) Subject: NECONF-524 : Setting the netconf keepalive logic to be more proactive. X-Git-Tag: release/fluorine~3^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=0c9207b1edb531a643db63efdd5b4e0bf4517a62;p=netconf.git NECONF-524 : Setting the netconf keepalive logic to be more proactive. https://jira.opendaylight.org/browse/NETCONF-524 When a NETCONF device loses connection with the controller in exceptional conditions such as the management interface going down, underlying TCP connection would not be closed as there will be no fin packet exchange or reset. At this point NETCONF state will be set as connected until the underlying OS determines the connection is stale which can happen after considerable amount of time. This fix makes the Keepalive packets more proactive to determine such conditions.This fix also sets the listener properly which is required for this fix as well. Change-Id: I781469ae7865e949e9f2c55e53240341f0b10bdd Signed-off-by: Balaji Varadaraju --- diff --git a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java index 5244692290..68366c115c 100644 --- a/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java +++ b/netconf/netconf-topology-singleton/src/main/java/org/opendaylight/netconf/topology/singleton/impl/RemoteDeviceConnectorImpl.java @@ -215,14 +215,19 @@ public class RemoteDeviceConnectorImpl implements RemoteDeviceConnector { LOG.info("{}: Concurrent rpc limit is smaller than 1, no limit will be enforced.", remoteDeviceId); } - return new NetconfConnectorDTO( - userCapabilities.isPresent() ? new NetconfDeviceCommunicator(remoteDeviceId, device, - new UserPreferences(userCapabilities.get(), - Objects.isNull(node.getYangModuleCapabilities()) - ? false : node.getYangModuleCapabilities().isOverride(), - Objects.isNull(node.getNonModuleCapabilities()) - ? false : node.getNonModuleCapabilities().isOverride()), rpcMessageLimit) - : new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit), salFacade); + NetconfDeviceCommunicator netconfDeviceCommunicator = + userCapabilities.isPresent() ? new NetconfDeviceCommunicator(remoteDeviceId, device, + new UserPreferences(userCapabilities.get(), + Objects.isNull(node.getYangModuleCapabilities()) + ? false : node.getYangModuleCapabilities().isOverride(), + Objects.isNull(node.getNonModuleCapabilities()) + ? false : node.getNonModuleCapabilities().isOverride()), rpcMessageLimit) + : new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit); + + if (salFacade instanceof KeepaliveSalFacade) { + ((KeepaliveSalFacade)salFacade).setListener(netconfDeviceCommunicator); + } + return new NetconfConnectorDTO(netconfDeviceCommunicator, salFacade); } private static Optional getUserCapabilities(final NetconfNode node) { diff --git a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java index c9ec7bf87f..342d3e9cda 100644 --- a/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java +++ b/netconf/netconf-topology/src/main/java/org/opendaylight/netconf/topology/AbstractNetconfTopology.java @@ -373,9 +373,15 @@ public abstract class AbstractNetconfTopology implements NetconfTopology { LOG.info("Concurrent rpc limit is smaller than 1, no limit will be enforced for device {}", remoteDeviceId); } - return new NetconfConnectorDTO(userCapabilities.isPresent() - ? new NetconfDeviceCommunicator(remoteDeviceId, device, userCapabilities.get(), rpcMessageLimit) - : new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit), salFacade); + NetconfDeviceCommunicator netconfDeviceCommunicator = + userCapabilities.isPresent() ? new NetconfDeviceCommunicator(remoteDeviceId, device, + userCapabilities.get(), rpcMessageLimit) + : new NetconfDeviceCommunicator(remoteDeviceId, device, rpcMessageLimit); + + if (salFacade instanceof KeepaliveSalFacade) { + ((KeepaliveSalFacade)salFacade).setListener(netconfDeviceCommunicator); + } + return new NetconfConnectorDTO(netconfDeviceCommunicator, salFacade); } protected NetconfDevice.SchemaResourcesDTO setupSchemaCacheDTO(final NodeId nodeId, final NetconfNode node) { diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java index 0e240dde64..eaece00f28 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/listener/NetconfDeviceCommunicator.java @@ -167,7 +167,7 @@ public class NetconfDeviceCommunicator public void disconnect() { // If session is already in closing, no need to close it again - if (currentSession != null && isSessionClosing.compareAndSet(false, true)) { + if (currentSession != null && isSessionClosing.compareAndSet(false, true) && currentSession.isUp()) { currentSession.close(); } } diff --git a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java index 82cf4b2337..73b1296ef8 100644 --- a/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java +++ b/netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/sal/KeepaliveSalFacade.java @@ -21,6 +21,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.dom.api.DOMNotification; @@ -66,6 +67,7 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler currentKeepalive; private volatile DOMRpcService currentDeviceRpc; + private final AtomicBoolean lastKeepAliveSucceeded = new AtomicBoolean(false); public KeepaliveSalFacade(final RemoteDeviceId id, final RemoteDeviceHandler salFacade, final ScheduledExecutorService executor, final long keepaliveDelaySeconds, @@ -104,7 +106,7 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler { - private final ScheduledFuture previousKeepalive; - - Keepalive(final ScheduledFuture previousKeepalive) { - this.previousKeepalive = previousKeepalive; - } - @Override public void run() { LOG.trace("{}: Invoking keepalive RPC", id); try { - if (previousKeepalive != null && !previousKeepalive.isDone()) { + boolean lastJobSucceeded = lastKeepAliveSucceeded.getAndSet(false); + if (!lastJobSucceeded) { onFailure(new IllegalStateException("Previous keepalive timed out")); } else { Futures.addCallback(currentDeviceRpc.invokeRpc(PATH, KEEPALIVE_PAYLOAD), this, @@ -212,11 +211,10 @@ public final class KeepaliveSalFacade implements RemoteDeviceHandler