Refresh IETF client/server models
[netconf.git] / transport / transport-ssh / src / main / java / org / opendaylight / netconf / transport / ssh / SSHTransportStackFactory.java
index bb31fe03a85aab3392b10d03a3f05deba2344fb8..77cd75e012e279dc90f207ee496f0f31d6bb5b12 100644 (file)
@@ -11,117 +11,140 @@ import static com.google.common.base.Preconditions.checkArgument;
 import static java.util.Objects.requireNonNull;
 
 import com.google.common.util.concurrent.ListenableFuture;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.EventLoopGroup;
 import org.eclipse.jdt.annotation.NonNull;
 import org.opendaylight.netconf.shaded.sshd.netty.NettyIoServiceFactoryFactory;
-import org.opendaylight.netconf.shaded.sshd.server.subsystem.SubsystemFactory;
 import org.opendaylight.netconf.transport.api.TransportChannelListener;
 import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
-import org.opendaylight.netconf.transport.tcp.NettyTransportSupport;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ssh.client.rev230417.SshClientGrouping;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ssh.server.rev230417.SshServerGrouping;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.client.rev230417.TcpClientGrouping;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev230417.TcpServerGrouping;
+import org.opendaylight.netconf.transport.tcp.BootstrapFactory;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ssh.client.rev231228.SshClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ssh.server.rev231228.SshServerGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.client.rev231228.TcpClientGrouping;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev231228.TcpServerGrouping;
 
 /**
- * A factory capable of instantiating {@link SSHClient}s and {@link SSHServer}s.
+ * A {@link BootstrapFactory} additionally capable of instantiating {@link SSHClient}s and {@link SSHServer}s.
  */
-public final class SSHTransportStackFactory implements AutoCloseable {
-    private final EventLoopGroup group;
-    private final EventLoopGroup parentGroup;
-    private final NettyIoServiceFactoryFactory ioServiceFactory;
-
-    private SSHTransportStackFactory(final EventLoopGroup group, final EventLoopGroup parentGroup) {
-        this.group = requireNonNull(group);
-        this.parentGroup = parentGroup;
-        ioServiceFactory = new NettyIoServiceFactoryFactory(group);
-    }
+public final class SSHTransportStackFactory extends BootstrapFactory {
+    private final NettyIoServiceFactoryFactory ioServiceFactory = new NettyIoServiceFactoryFactory(group);
 
     public SSHTransportStackFactory(final @NonNull String groupName, final int groupThreads) {
-        this(NettyTransportSupport.newEventLoopGroup(groupName, groupThreads), null);
+        super(groupName, groupThreads);
     }
 
     public SSHTransportStackFactory(final @NonNull String groupName, final int groupThreads,
             final @NonNull String parentGroupName, final int parentGroupThreads) {
-        this(NettyTransportSupport.newEventLoopGroup(groupName, groupThreads),
-            NettyTransportSupport.newEventLoopGroup(parentGroupName, parentGroupThreads));
+        super(groupName, groupThreads, parentGroupName, parentGroupThreads);
     }
 
     public @NonNull ListenableFuture<SSHClient> connectClient(final String subsystem,
             final TransportChannelListener listener, final TcpClientGrouping connectParams,
             final SshClientGrouping clientParams) throws UnsupportedConfigurationException {
-        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams)
+        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams, null)
+            .connect(newBootstrap(), connectParams);
+    }
+
+    /** Builds the SSH Client and initiates connection.
+     *
+     * @param subsystem bound subsystem name
+     * @param listener client channel listener, required
+     * @param connectParams TCP transport configuration addressing server to connect, required
+     * @param clientParams SSH overlay configuration, required, should contain username
+     * @param configurator client factory manager configurator, optional
+     * @return a future producing {@link SSHClient}
+     * @throws UnsupportedConfigurationException if any of configurations is invalid or incomplete
+     * @throws NullPointerException if any of required parameters is null
+     */
+    public @NonNull ListenableFuture<SSHClient> connectClient(final String subsystem,
+            final TransportChannelListener listener, final TcpClientGrouping connectParams,
+            final SshClientGrouping clientParams, final ClientFactoryManagerConfigurator configurator)
+            throws UnsupportedConfigurationException {
+        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams, configurator)
             .connect(newBootstrap(), connectParams);
     }
 
     public @NonNull ListenableFuture<SSHClient> listenClient(final String subsystem,
             final TransportChannelListener listener, final TcpServerGrouping listenParams,
             final SshClientGrouping clientParams) throws UnsupportedConfigurationException {
-        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams)
+        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams, null)
             .listen(newServerBootstrap(), listenParams);
     }
 
-    public @NonNull ListenableFuture<SSHServer> connectServer(final TransportChannelListener listener,
-            final SubsystemFactory subsystemFactory, final TcpClientGrouping connectParams,
-            final SshServerGrouping serverParams) throws UnsupportedConfigurationException {
-        return SSHServer.of(ioServiceFactory, group, listener, subsystemFactory, requireNonNull(serverParams), null)
-            .connect(newBootstrap(), connectParams);
+    /**
+     * Builds and starts Call-Home SSH Client.
+     *
+     * @param subsystem bound subsystem name
+     * @param listener client channel listener, required
+     * @param listenParams TCP transport configuration addressing inbound connection, required
+     * @param clientParams SSH overlay configuration, required, should contain username
+     * @param configurator client factory manager configurator, optional
+     * @return a future producing {@link SSHClient}
+     * @throws UnsupportedConfigurationException if any of configurations is invalid or incomplete
+     * @throws NullPointerException if any of required parameters is null
+     */
+    public @NonNull ListenableFuture<SSHClient> listenClient(final String subsystem,
+            final TransportChannelListener listener, final TcpServerGrouping listenParams,
+            final SshClientGrouping clientParams, final ClientFactoryManagerConfigurator configurator)
+            throws UnsupportedConfigurationException {
+        return SSHClient.of(ioServiceFactory, group, subsystem, listener, clientParams, configurator)
+            .listen(newServerBootstrap(), listenParams);
     }
 
-    public @NonNull ListenableFuture<SSHServer> listenServer(final TransportChannelListener listener,
-            final SubsystemFactory subsystemFactory, final TcpServerGrouping connectParams,
+    public @NonNull ListenableFuture<SSHServer> connectServer(final String subsystem,
+            final TransportChannelListener listener, final TcpClientGrouping connectParams,
             final SshServerGrouping serverParams) throws UnsupportedConfigurationException {
-        return listenServer(listener, subsystemFactory, connectParams, requireNonNull(serverParams), null);
+        return SSHServer.of(ioServiceFactory, group, subsystem, listener, requireNonNull(serverParams), null)
+            .connect(newBootstrap(), connectParams);
     }
 
     /**
-     * Builds and starts SSH Server.
+     * Builds and starts a Call-Home SSH Server, initiates connection to client.
      *
+     * @param subsystem bound subsystem name
      * @param listener server channel listener, required
-     * @param subsystemFactory A {@link SubsystemFactory} for the hosted subsystem
-     * @param listenParams TCP transport configuration, required
+     * @param connectParams TCP transport configuration addressing client to be connected, required
      * @param serverParams SSH overlay configuration, optional if configurator is defined, required otherwise
      * @param configurator server factory manager configurator, optional if serverParams is defined, required otherwise
-     * @return server instance as listenable future
+     * @return a future producing {@link SSHServer}
      * @throws UnsupportedConfigurationException if any of configurations is invalid or incomplete
      * @throws NullPointerException if any of required parameters is null
      * @throws IllegalArgumentException if both configurator and serverParams are null
      */
-    public @NonNull ListenableFuture<SSHServer> listenServer(final TransportChannelListener listener,
-            final SubsystemFactory subsystemFactory, final TcpServerGrouping listenParams,
+    public @NonNull ListenableFuture<SSHServer> connectServer(final String subsystem,
+            final TransportChannelListener listener, final TcpClientGrouping connectParams,
             final SshServerGrouping serverParams, final ServerFactoryManagerConfigurator configurator)
-                    throws UnsupportedConfigurationException {
+            throws UnsupportedConfigurationException {
         checkArgument(serverParams != null || configurator != null,
             "Neither server parameters nor factory configurator is defined");
-        return SSHServer.of(ioServiceFactory, group, listener, subsystemFactory, serverParams, configurator)
-            .listen(newServerBootstrap(), listenParams);
+        return SSHServer.of(ioServiceFactory, group, subsystem, listener, serverParams, configurator)
+            .connect(newBootstrap(), connectParams);
     }
 
-    /**
-     * Create a new {@link Bootstrap} based on this factory's {@link EventLoopGroup}s.
-     *
-     * @return A new {@link Bootstrap}
-     */
-    public @NonNull Bootstrap newBootstrap() {
-        return NettyTransportSupport.newBootstrap().group(group);
+    public @NonNull ListenableFuture<SSHServer> listenServer(final String subsystem,
+            final TransportChannelListener listener, final TcpServerGrouping connectParams,
+            final SshServerGrouping serverParams) throws UnsupportedConfigurationException {
+        return listenServer(subsystem, listener, connectParams, requireNonNull(serverParams), null);
     }
 
     /**
-     * Create a new {@link ServerBootstrap} based on this factory's {@link EventLoopGroup}s.
+     * Builds and starts SSH Server.
      *
-     * @return A new {@link ServerBootstrap}
+     * @param listener server channel listener, required
+     * @param subsystem bound subsystem name
+     * @param listenParams TCP transport configuration, required
+     * @param serverParams SSH overlay configuration, optional if configurator is defined, required otherwise
+     * @param configurator server factory manager configurator, optional if serverParams is defined, required otherwise
+     * @return a future producing {@link SSHServer}
+     * @throws UnsupportedConfigurationException if any of configurations is invalid or incomplete
+     * @throws NullPointerException if any of required parameters is null
+     * @throws IllegalArgumentException if both configurator and serverParams are null
      */
-    public @NonNull ServerBootstrap newServerBootstrap() {
-        return NettyTransportSupport.newServerBootstrap().group(parentGroup != null ? parentGroup : group, group);
-    }
-
-    @Override
-    public void close() {
-        if (parentGroup != null) {
-            parentGroup.shutdownGracefully();
-        }
-        group.shutdownGracefully();
+    public @NonNull ListenableFuture<SSHServer> listenServer(final String subsystem,
+            final TransportChannelListener listener, final TcpServerGrouping listenParams,
+            final SshServerGrouping serverParams, final ServerFactoryManagerConfigurator configurator)
+                throws UnsupportedConfigurationException {
+        checkArgument(serverParams != null || configurator != null,
+            "Neither server parameters nor factory configurator is defined");
+        return SSHServer.of(ioServiceFactory, group, subsystem, listener, serverParams, configurator)
+            .listen(newServerBootstrap(), listenParams);
     }
 }