Allow SshClient to be customized via NetconfClientConfiguration
[netconf.git] / netconf / netconf-client / src / main / java / org / opendaylight / netconf / client / NetconfClientDispatcherImpl.java
index 6abce42b43239d0c0d645964d11450c8abcb2c7a..747a5f75fd72750dbb36353511d7deab60dd6d90 100644 (file)
@@ -5,21 +5,24 @@
  * 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 io.netty.channel.EventLoopGroup;
 import io.netty.util.Timer;
 import io.netty.util.concurrent.Future;
-import java.io.Closeable;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
 import org.opendaylight.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.netconf.client.conf.NetconfReconnectingClientConfiguration;
-import org.opendaylight.protocol.framework.AbstractDispatcher;
+import org.opendaylight.netconf.nettyutil.AbstractNetconfDispatcher;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClientSession, NetconfClientSessionListener>
-        implements NetconfClientDispatcher, Closeable {
+public class NetconfClientDispatcherImpl
+        extends AbstractNetconfDispatcher<NetconfClientSession, NetconfClientSessionListener>
+        implements NetconfClientDispatcher {
 
     private static final Logger LOG = LoggerFactory.getLogger(NetconfClientDispatcherImpl.class);
 
@@ -42,6 +45,8 @@ public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClien
                 return createTcpClient(clientConfiguration);
             case SSH:
                 return createSshClient(clientConfiguration);
+            case TLS:
+                return createTlsClient(clientConfiguration);
             default:
                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
         }
@@ -54,6 +59,8 @@ public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClien
                 return createReconnectingTcpClient(clientConfiguration);
             case SSH:
                 return createReconnectingSshClient(clientConfiguration);
+            case TLS:
+                return createReconnectingTlsClient(clientConfiguration);
             default:
                 throw new IllegalArgumentException("Unknown client protocol " + clientConfiguration.getProtocol());
         }
@@ -63,8 +70,7 @@ public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClien
         LOG.debug("Creating TCP client with configuration: {}", currentConfiguration);
         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
             (ch, promise) -> new TcpClientChannelInitializer(getNegotiatorFactory(currentConfiguration),
-                        currentConfiguration
-                        .getSessionListener()).initialize(ch, promise));
+                        currentConfiguration.getSessionListener()).initialize(ch, promise));
     }
 
     private Future<Void> createReconnectingTcpClient(
@@ -83,15 +89,36 @@ public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClien
         LOG.debug("Creating SSH client with configuration: {}", currentConfiguration);
         return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
             (ch, sessionPromise) -> new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
-                        getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
-                        .initialize(ch, sessionPromise));
+                        getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
+                        currentConfiguration.getSshClient()).initialize(ch, sessionPromise));
     }
 
     private Future<Void> createReconnectingSshClient(
             final NetconfReconnectingClientConfiguration currentConfiguration) {
         LOG.debug("Creating reconnecting SSH client with configuration: {}", currentConfiguration);
         final SshClientChannelInitializer init = new SshClientChannelInitializer(currentConfiguration.getAuthHandler(),
-                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener());
+                getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener(),
+                currentConfiguration.getSshClient());
+
+        return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration
+                .getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
+                init::initialize);
+    }
+
+    private Future<NetconfClientSession> createTlsClient(final NetconfClientConfiguration currentConfiguration) {
+        LOG.debug("Creating TLS client with configuration: {}", currentConfiguration);
+        return super.createClient(currentConfiguration.getAddress(), currentConfiguration.getReconnectStrategy(),
+            (ch, sessionPromise) -> new TlsClientChannelInitializer(currentConfiguration.getSslHandlerFactory(),
+                    getNegotiatorFactory(currentConfiguration), currentConfiguration.getSessionListener())
+                    .initialize(ch, sessionPromise));
+    }
+
+    private Future<Void> createReconnectingTlsClient(
+            final NetconfReconnectingClientConfiguration currentConfiguration) {
+        LOG.debug("Creating reconnecting TLS client with configuration: {}", currentConfiguration);
+        final TlsClientChannelInitializer init = new TlsClientChannelInitializer(
+                currentConfiguration.getSslHandlerFactory(), getNegotiatorFactory(currentConfiguration),
+                currentConfiguration.getSessionListener());
 
         return super.createReconnectingClient(currentConfiguration.getAddress(), currentConfiguration
                 .getConnectStrategyFactory(), currentConfiguration.getReconnectStrategy(),
@@ -99,7 +126,19 @@ public class NetconfClientDispatcherImpl extends AbstractDispatcher<NetconfClien
     }
 
     protected NetconfClientSessionNegotiatorFactory getNegotiatorFactory(final NetconfClientConfiguration cfg) {
-        return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
-                cfg.getConnectionTimeoutMillis());
+        final List<Uri> odlHelloCapabilities = cfg.getOdlHelloCapabilities();
+        if (odlHelloCapabilities == null || odlHelloCapabilities.isEmpty()) {
+            return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
+                    cfg.getConnectionTimeoutMillis());
+        } else {
+            // LinkedHashSet since perhaps the device cares about order of hello message capabilities.
+            // This allows user control of the order while complying with the existing interface.
+            final Set<String> stringCapabilities = new LinkedHashSet<>();
+            for (final Uri uri : odlHelloCapabilities) {
+                stringCapabilities.add(uri.getValue());
+            }
+            return new NetconfClientSessionNegotiatorFactory(timer, cfg.getAdditionalHeader(),
+                    cfg.getConnectionTimeoutMillis(), stringCapabilities);
+        }
     }
 }