From: jiang.wei <351183359@qq.com> Date: Wed, 21 Mar 2018 07:17:36 +0000 (+0800) Subject: fix failure during connecting device when channelActive happens later than handleMessage X-Git-Tag: release/fluorine~96^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=d67b5d05f228009204ea6e190a4011aad9f8aa94;p=netconf.git fix failure during connecting device when channelActive happens later than handleMessage fix bug NETCONF-533 --https://jira.opendaylight.org/browse/NETCONF-533 Change-Id: I46e4a85fc7be1bc221cfbb43386eae95768ac5ac Signed-off-by: jiang.wei <351183359@qq.com> --- diff --git a/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiator.java b/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiator.java index 608450225f..0b456f447f 100644 --- a/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiator.java +++ b/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiator.java @@ -63,8 +63,19 @@ public class NetconfClientSessionNegotiator extends super(sessionPreferences, promise, channel, timer, sessionListener, connectionTimeoutMillis); } + @SuppressWarnings("checkstyle:IllegalCatch") @Override protected void handleMessage(final NetconfHelloMessage netconfMessage) throws NetconfDocumentedException { + if (!ifNegotiatedAlready()) { + LOG.debug("Server hello message received, starting negotiation on channel {}", channel); + try { + startNegotiation(); + } catch (final Exception e) { + LOG.warn("Unexpected negotiation failure", e); + negotiationFailed(e); + return; + } + } final NetconfClientSession session = getSessionForHelloMessage(netconfMessage); replaceHelloMessageInboundHandler(session); diff --git a/netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiatorTest.java b/netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiatorTest.java index 79b13a233c..12d4322ea0 100644 --- a/netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiatorTest.java +++ b/netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientSessionNegotiatorTest.java @@ -168,6 +168,22 @@ public class NetconfClientSessionNegotiatorTest { verify(promise).setSuccess(anyObject()); } + @Test + public void testNegotiatorWhenChannelActiveHappenAfterHandleMessage() throws Exception { + Promise promise = mock(Promise.class); + doReturn(false).when(promise).isDone(); + doReturn(promise).when(promise).setSuccess(anyObject()); + NetconfClientSessionNegotiator negotiator = createNetconfClientSessionNegotiator(promise, null); + Set caps = Sets.newSet("a", "b"); + NetconfHelloMessage helloServerMessage = NetconfHelloMessage.createServerHello(caps, 10); + + negotiator.handleMessage(helloServerMessage); + negotiator.channelActive(null); + + verify(promise).setSuccess(anyObject()); + } + + @Test public void testNetconfClientSessionNegotiatorWithEXI() throws Exception { Promise promise = mock(Promise.class); diff --git a/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java b/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java index a9adf2a668..f8f486b2a0 100644 --- a/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java +++ b/netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/AbstractNetconfSessionNegotiator.java @@ -79,22 +79,31 @@ public abstract class AbstractNetconfSessionNegotiator

sslHandler = getSslHandler(channel); - if (sslHandler.isPresent()) { - Future future = sslHandler.get().handshakeFuture(); - future.addListener(new GenericFutureListener>() { - @Override - public void operationComplete(final Future future) { - Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful"); - LOG.debug("Ssl handshake complete"); - start(); - } - }); + if (ifNegotiatedAlready()) { + LOG.debug("Negotiation on channel {} already started", channel); } else { - start(); + final Optional sslHandler = getSslHandler(channel); + if (sslHandler.isPresent()) { + Future future = sslHandler.get().handshakeFuture(); + future.addListener(new GenericFutureListener>() { + @Override + public void operationComplete(final Future future) { + Preconditions.checkState(future.isSuccess(), "Ssl handshake was not successful"); + LOG.debug("Ssl handshake complete"); + start(); + } + }); + } else { + start(); + } } } + protected final boolean ifNegotiatedAlready() { + // Indicates whether negotiation already started + return this.state != State.IDLE; + } + private static Optional getSslHandler(final Channel channel) { final SslHandler sslHandler = channel.pipeline().get(SslHandler.class); return sslHandler == null ? Optional.absent() : Optional.of(sslHandler);