Add AbstractClientChannelInitializer 36/101436/5
authorRobert Varga <robert.varga@pantheon.tech>
Thu, 2 Jun 2022 09:47:20 +0000 (11:47 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 2 Jun 2022 11:50:21 +0000 (13:50 +0200)
We have three distinct classes doing essentially the same thing,
add an intermediate abstract class to handle common functionality.

Change-Id: I107e91cbd1c333279a5c9e2f282b8ef1403a7c48
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/AbstractClientChannelInitializer.java [new file with mode: 0644]
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/SshClientChannelInitializer.java
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/TcpClientChannelInitializer.java
netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/TlsClientChannelInitializer.java
netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/TcpClientChannelInitializerTest.java
netconf/netconf-client/src/test/java/org/opendaylight/netconf/client/TlsClientChannelInitializerTest.java

diff --git a/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/AbstractClientChannelInitializer.java b/netconf/netconf-client/src/main/java/org/opendaylight/netconf/client/AbstractClientChannelInitializer.java
new file mode 100644 (file)
index 0000000..f368a18
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.client;
+
+import static java.util.Objects.requireNonNull;
+
+import io.netty.channel.Channel;
+import io.netty.util.concurrent.Promise;
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
+
+/**
+ * Abstract base class for {@link NetconfClientSession} initializers.
+ */
+abstract class AbstractClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+    private final @NonNull NetconfClientSessionNegotiatorFactory negotiatorFactory;
+    private final @NonNull NetconfClientSessionListener sessionListener;
+
+    AbstractClientChannelInitializer(final NetconfClientSessionNegotiatorFactory negotiatorFactory,
+            final NetconfClientSessionListener sessionListener) {
+        this.negotiatorFactory = requireNonNull(negotiatorFactory);
+        this.sessionListener = requireNonNull(sessionListener);
+    }
+
+    @Override
+    protected final void initializeSessionNegotiator(final Channel ch, final Promise<NetconfClientSession> promise) {
+        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, NETCONF_SESSION_NEGOTIATOR,
+                negotiatorFactory.getSessionNegotiator(() -> sessionListener, ch, promise));
+        ch.config().setConnectTimeoutMillis((int) negotiatorFactory.getConnectionTimeoutMillis());
+    }
+}
index 53d9a27c962987a80d0ebc844aa213fbe3ccaf5d..81f2d00b9724222973af2bea2ce6f39f788cdcc5 100644 (file)
@@ -10,23 +10,19 @@ package org.opendaylight.netconf.client;
 import io.netty.channel.Channel;
 import io.netty.util.concurrent.Promise;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
 import org.opendaylight.netconf.nettyutil.handler.ssh.client.NetconfSshClient;
 
-final class SshClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+final class SshClientChannelInitializer extends AbstractClientChannelInitializer {
     private final AuthenticationHandler authenticationHandler;
-    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-    private final NetconfClientSessionListener sessionListener;
     private final NetconfSshClient sshClient;
 
     SshClientChannelInitializer(final AuthenticationHandler authHandler,
             final NetconfClientSessionNegotiatorFactory negotiatorFactory,
             final NetconfClientSessionListener sessionListener, @Nullable final NetconfSshClient sshClient) {
-        this.authenticationHandler = authHandler;
-        this.negotiatorFactory = negotiatorFactory;
-        this.sessionListener = sessionListener;
+        super(negotiatorFactory, sessionListener);
+        authenticationHandler = authHandler;
         this.sshClient = sshClient;
     }
 
@@ -42,12 +38,4 @@ final class SshClientChannelInitializer extends AbstractChannelInitializer<Netco
         ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(authenticationHandler, promise, sshClient));
         super.initialize(ch, promise);
     }
-
-    @Override
-    protected void initializeSessionNegotiator(final Channel ch,
-                                               final Promise<NetconfClientSession> promise) {
-        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
-                negotiatorFactory.getSessionNegotiator(() -> sessionListener, ch, promise));
-        ch.config().setConnectTimeoutMillis((int)negotiatorFactory.getConnectionTimeoutMillis());
-    }
 }
index c241e17656736052b4cbe3bf48012c8891e02ea4..85c3e0fa6460bc8d4c6973acb2b9b5a9825f7944 100644 (file)
@@ -16,17 +16,11 @@ import io.netty.util.concurrent.Future;
 import io.netty.util.concurrent.GenericFutureListener;
 import io.netty.util.concurrent.Promise;
 import java.net.SocketAddress;
-import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
-
-class TcpClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
-
-    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-    private final NetconfClientSessionListener sessionListener;
 
+final class TcpClientChannelInitializer extends AbstractClientChannelInitializer {
     TcpClientChannelInitializer(final NetconfClientSessionNegotiatorFactory negotiatorFactory,
-                                final NetconfClientSessionListener sessionListener) {
-        this.negotiatorFactory = negotiatorFactory;
-        this.sessionListener = sessionListener;
+            final NetconfClientSessionListener sessionListener) {
+        super(negotiatorFactory, sessionListener);
     }
 
     @Override
@@ -93,10 +87,4 @@ class TcpClientChannelInitializer extends AbstractChannelInitializer<NetconfClie
 
         super.initialize(ch, promise);
     }
-
-    @Override
-    protected void initializeSessionNegotiator(final Channel ch, final Promise<NetconfClientSession> promise) {
-        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
-                negotiatorFactory.getSessionNegotiator(() -> sessionListener, ch, promise));
-    }
 }
index 64d567f5aaac8893edee78673a98f5cfa7335180..dc6598dd2a3deb159f963e51b1f26eeaad1bb984 100644 (file)
@@ -11,25 +11,21 @@ import io.netty.channel.Channel;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelInboundHandlerAdapter;
 import io.netty.util.concurrent.Promise;
-import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
 
-public final class TlsClientChannelInitializer extends AbstractChannelInitializer<NetconfClientSession> {
+public final class TlsClientChannelInitializer extends AbstractClientChannelInitializer {
     public static final String CHANNEL_ACTIVE_SENTRY = "channelActiveSentry";
 
     private final SslHandlerFactory sslHandlerFactory;
-    private final NetconfClientSessionNegotiatorFactory negotiatorFactory;
-    private final NetconfClientSessionListener sessionListener;
 
     public TlsClientChannelInitializer(final SslHandlerFactory sslHandlerFactory,
                                        final NetconfClientSessionNegotiatorFactory negotiatorFactory,
                                        final NetconfClientSessionListener sessionListener) {
+        super(negotiatorFactory, sessionListener);
         this.sslHandlerFactory = sslHandlerFactory;
-        this.negotiatorFactory = negotiatorFactory;
-        this.sessionListener = sessionListener;
     }
 
     @Override
-    public void initialize(Channel ch, Promise<NetconfClientSession> promise) {
+    public void initialize(final Channel ch, final Promise<NetconfClientSession> promise) {
         // When ssl handshake fails due to the certificate mismatch, the connection will try again,
         // then we have a chance to create a new SslHandler using the latest certificates with the
         // help of the sentry. We will replace the sentry with the new SslHandler once the channel
@@ -38,12 +34,6 @@ public final class TlsClientChannelInitializer extends AbstractChannelInitialize
         super.initialize(ch, promise);
     }
 
-    @Override
-    protected void initializeSessionNegotiator(Channel ch, Promise<NetconfClientSession> promise) {
-        ch.pipeline().addAfter(NETCONF_MESSAGE_DECODER, AbstractChannelInitializer.NETCONF_SESSION_NEGOTIATOR,
-                negotiatorFactory.getSessionNegotiator(() -> sessionListener, ch, promise));
-    }
-
     private static final class ChannelActiveSentry extends ChannelInboundHandlerAdapter {
         private final SslHandlerFactory sslHandlerFactory;
 
@@ -52,9 +42,9 @@ public final class TlsClientChannelInitializer extends AbstractChannelInitialize
         }
 
         @Override
-        public void channelActive(ChannelHandlerContext ctx) {
-            ctx.pipeline().replace(this, "sslHandler", sslHandlerFactory.createSslHandler())
-                          .fireChannelActive();
+        public void channelActive(final ChannelHandlerContext ctx) {
+            final var sslHandler = sslHandlerFactory.createSslHandler();
+            ctx.pipeline().replace(this, "sslHandler", sslHandler).fireChannelActive();
         }
     }
 }
index 000cfbef3d039a643125ca032f93178c027576b2..b9b3b961ad113a262d9a2f62d3e9d95f1cc42937 100644 (file)
@@ -15,6 +15,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import io.netty.channel.Channel;
+import io.netty.channel.ChannelConfig;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
 import io.netty.util.concurrent.Promise;
@@ -37,6 +38,11 @@ public class TcpClientChannelInitializerTest {
         doReturn(pipeline).when(channel).pipeline();
         doReturn("").when(channel).toString();
 
+        ChannelConfig channelConfig = mock(ChannelConfig.class);
+        doReturn(channelConfig).when(channel).config();
+        doReturn(1L).when(factory).getConnectionTimeoutMillis();
+        doReturn(channelConfig).when(channelConfig).setConnectTimeoutMillis(1);
+
         Promise<NetconfClientSession> promise = mock(Promise.class);
         doReturn("").when(promise).toString();
 
index e6a518e4cbcf29977ab69aab052ae9b2477924a0..b9f853aa5d1cfd54409cc21273f39168dd6ecfa1 100644 (file)
@@ -15,6 +15,7 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
 import io.netty.channel.Channel;
+import io.netty.channel.ChannelConfig;
 import io.netty.channel.ChannelHandler;
 import io.netty.channel.ChannelPipeline;
 import io.netty.util.concurrent.Promise;
@@ -47,6 +48,11 @@ public class TlsClientChannelInitializerTest {
         doReturn(pipeline).when(pipeline).addFirst(anyString(), any(ChannelHandler.class));
         doReturn(pipeline).when(pipeline).addLast(anyString(), any(ChannelHandler.class));
 
+        ChannelConfig channelConfig = mock(ChannelConfig.class);
+        doReturn(channelConfig).when(channel).config();
+        doReturn(1L).when(negotiatorFactory).getConnectionTimeoutMillis();
+        doReturn(channelConfig).when(channelConfig).setConnectTimeoutMillis(1);
+
         Promise<NetconfClientSession> promise = mock(Promise.class);
 
         TlsClientChannelInitializer initializer = new TlsClientChannelInitializer(sslHandlerFactory,