<groupId>org.opendaylight.netconf</groupId>
<artifactId>shaded-sshd</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.guicedee.services</groupId>
+ <artifactId>javax.inject</artifactId>
+ <optional>true</optional>
+ </dependency>
+ <dependency>
+ <groupId>jakarta.annotation</groupId>
+ <artifactId>jakarta.annotation-api</artifactId>
+ <scope>provided</scope>
+ <optional>true</optional>
+ </dependency>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.framework</artifactId>
+++ /dev/null
-/*
- * Copyright (c) 2023 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.northbound;
-
-import static java.util.Objects.requireNonNull;
-
-import io.netty.channel.EventLoopGroup;
-import java.util.Map;
-import org.opendaylight.netconf.server.NetconfServerDispatcherImpl;
-import org.opendaylight.netconf.server.ServerChannelInitializer;
-import org.opendaylight.netconf.server.api.NetconfServerDispatcher;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-
-@Component(factory = DefaultNetconfServerDispatcher.FACTORY_NAME, service = NetconfServerDispatcher.class)
-public final class DefaultNetconfServerDispatcher extends NetconfServerDispatcherImpl {
- static final String FACTORY_NAME = "org.opendaylight.netconf.impl.mdsal.DefaultNetconfServerDispatcher";
-
- private static final String BOSS_PROP = ".bossGroup";
- private static final String WORKER_PROP = ".workerGroup";
- private static final String INITIALIZER_PROP = ".initializer";
-
- @Activate
- public DefaultNetconfServerDispatcher(final Map<String, ?> properties) {
- super(OSGiNetconfServer.extractProp(properties, INITIALIZER_PROP, ServerChannelInitializer.class),
- OSGiNetconfServer.extractProp(properties, BOSS_PROP, EventLoopGroup.class),
- OSGiNetconfServer.extractProp(properties, WORKER_PROP, EventLoopGroup.class));
- }
-
- static Map<String, ?> props(final EventLoopGroup bossGroup, final EventLoopGroup workerGroup,
- final ServerChannelInitializer initializer) {
- return Map.of(
- "type", "netconf-server-dispatcher",
- BOSS_PROP, requireNonNull(bossGroup),
- WORKER_PROP, requireNonNull(workerGroup),
- INITIALIZER_PROP, requireNonNull(initializer));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Inocybe Technologies 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.northbound;
-
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.local.LocalAddress;
-import io.netty.util.concurrent.EventExecutor;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.util.concurrent.Executors;
-import org.opendaylight.netconf.auth.AuthProvider;
-import org.opendaylight.netconf.northbound.ssh.SshProxyServer;
-import org.opendaylight.netconf.northbound.ssh.SshProxyServerConfigurationBuilder;
-import org.opendaylight.netconf.server.api.NetconfServerDispatcher;
-import org.opendaylight.netconf.shaded.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * NETCONF server for MD-SAL (listening by default on port 2830).
- */
-@Component(service = { }, configurationPid = "org.opendaylight.netconf.ssh")
-@Designate(ocd = NetconfNorthboundSshServer.Configuration.class)
-public final class NetconfNorthboundSshServer implements AutoCloseable {
- @ObjectClassDefinition
- public @interface Configuration {
- @AttributeDefinition
- String bindingAddress() default "0.0.0.0";
- @AttributeDefinition(min = "1", max = "65535")
- int portNumber() default 2830;
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundSshServer.class);
-
- private final ChannelFuture localServer;
- private final SshProxyServer sshProxyServer;
-
- @Activate
- public NetconfNorthboundSshServer(
- @Reference final NetconfServerDispatcher netconfServerDispatcher,
- @Reference(target = "(type=global-worker-group)") final EventLoopGroup workerGroup,
- @Reference(target = "(type=global-event-executor)") final EventExecutor eventExecutor,
- @Reference(target = "(type=netconf-auth-provider)") final AuthProvider authProvider,
- final Configuration configuration) {
- this(netconfServerDispatcher, workerGroup, eventExecutor, authProvider, configuration.bindingAddress(),
- configuration.portNumber());
- }
-
- public NetconfNorthboundSshServer(final NetconfServerDispatcher netconfServerDispatcher,
- final EventLoopGroup workerGroup, final EventExecutor eventExecutor, final AuthProvider authProvider,
- final String bindingAddress, final int portNumber) {
- final LocalAddress localAddress = new LocalAddress(String.valueOf(portNumber));
- final var sshProxyServerConfiguration = new SshProxyServerConfigurationBuilder()
- .setBindingAddress(getInetAddress(bindingAddress, portNumber))
- .setLocalAddress(localAddress)
- .setAuthenticator(authProvider)
- .setIdleTimeout(Integer.MAX_VALUE)
- .setKeyPairProvider(new SimpleGeneratorHostKeyProvider())
- .createSshProxyServerConfiguration();
-
- localServer = netconfServerDispatcher.createLocalServer(localAddress);
- sshProxyServer = new SshProxyServer(Executors.newScheduledThreadPool(1), workerGroup, eventExecutor);
-
- localServer.addListener(future -> {
- if (future.isDone() && !future.isCancelled()) {
- try {
- sshProxyServer.bind(sshProxyServerConfiguration);
- } catch (final IOException e) {
- throw new IllegalStateException("Unable to start SSH netconf server", e);
- }
- LOG.info("Netconf SSH endpoint started successfully at {}", bindingAddress);
- } else {
- LOG.warn("Unable to start SSH netconf server at {}", bindingAddress, future.cause());
- throw new IllegalStateException("Unable to start SSH netconf server", future.cause());
- }
- });
- }
-
- @Deactivate
- @Override
- public void close() throws IOException {
- sshProxyServer.close();
-
- if (localServer.isDone()) {
- localServer.channel().close();
- } else {
- localServer.cancel(true);
- }
- }
-
- private static InetSocketAddress getInetAddress(final String bindingAddress, final int portNumber) {
- final var ipAddress = IetfInetUtil.ipAddressFor(bindingAddress);
- return new InetSocketAddress(IetfInetUtil.inetAddressFor(ipAddress), portNumber);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 Inocybe Technologies 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.northbound;
-
-import io.netty.channel.ChannelFuture;
-import java.net.InetSocketAddress;
-import org.opendaylight.netconf.server.api.NetconfServerDispatcher;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.Designate;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Create an MD-SAL NETCONF server using TCP.
- */
-@Component(service = { }, configurationPid = "org.opendaylight.netconf.tcp", enabled = false)
-@Designate(ocd = NetconfNorthboundTcpServer.Configuration.class)
-public final class NetconfNorthboundTcpServer implements AutoCloseable {
- @ObjectClassDefinition
- public @interface Configuration {
- @AttributeDefinition
- String bindingAddress() default "0.0.0.0";
- @AttributeDefinition(min = "1", max = "65535")
- int portNumber() default 2831;
- }
-
- private static final Logger LOG = LoggerFactory.getLogger(NetconfNorthboundTcpServer.class);
-
- private final ChannelFuture tcpServer;
-
- @Activate
- public NetconfNorthboundTcpServer(
- @Reference(target = "(type=netconf-server-dispatcher)") final NetconfServerDispatcher serverDispatcher,
- final Configuration configuration) {
- this(serverDispatcher, configuration.bindingAddress(), configuration.portNumber());
- }
-
- public NetconfNorthboundTcpServer(final NetconfServerDispatcher serverDispatcher, final String address,
- final int port) {
- final InetSocketAddress inetAddress = getInetAddress(address, port);
- tcpServer = serverDispatcher.createServer(inetAddress);
- tcpServer.addListener(future -> {
- if (future.isDone() && future.isSuccess()) {
- LOG.info("Netconf TCP endpoint started successfully at {}", inetAddress);
- } else {
- LOG.warn("Unable to start TCP netconf server at {}", inetAddress, future.cause());
- throw new IllegalStateException("Unable to start TCP netconf server", future.cause());
- }
- });
- }
-
- @Override
- public void close() {
- if (tcpServer.isDone()) {
- tcpServer.channel().close();
- } else {
- tcpServer.cancel(true);
- }
- }
-
- private static InetSocketAddress getInetAddress(final String bindingAddress, final int portNumber) {
- final var inetAd = IetfInetUtil.inetAddressFor(IetfInetUtil.ipAddressFor(bindingAddress));
- return new InetSocketAddress(inetAd, portNumber);
- }
-}
import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
-import io.netty.channel.EventLoopGroup;
import io.netty.util.Timer;
import java.util.Map;
import org.opendaylight.controller.config.threadpool.ScheduledThreadPool;
import org.osgi.service.metatype.annotations.Designate;
import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-@Component(service = { }, configurationPid = "org.opendaylight.netconf.impl")
+@Component(service = { OSGiNetconfServer.class }, configurationPid = "org.opendaylight.netconf.impl")
@Designate(ocd = OSGiNetconfServer.Configuration.class)
public final class OSGiNetconfServer {
@ObjectClassDefinition
private final AggregatedNetconfOperationServiceFactory mappers = new AggregatedNetconfOperationServiceFactory();
private final ComponentInstance<DefaultNetconfMonitoringService> monitoring;
- private final ComponentInstance<DefaultNetconfServerDispatcher> dispatcher;
+ private final ServerChannelInitializer serverChannelInitializer;
@Activate
public OSGiNetconfServer(
@Reference(target = "(component.factory=" + DefaultNetconfMonitoringService.FACTORY_NAME + ")")
final ComponentFactory<DefaultNetconfMonitoringService> monitoringFactory,
- @Reference(target = "(component.factory=" + DefaultNetconfServerDispatcher.FACTORY_NAME + ")")
- final ComponentFactory<DefaultNetconfServerDispatcher> dispatcherFactory,
@Reference(target = "(type=mapper-aggregator-registry)")
final NetconfOperationServiceFactory mapperAggregatorRegistry,
@Reference(target = "(type=global-netconf-ssh-scheduled-executor)")
final ScheduledThreadPool sshScheduledExecutor,
- @Reference(target = "(type=global-boss-group)") final EventLoopGroup bossGroup,
- @Reference(target = "(type=global-boss-group)") final EventLoopGroup workerGroup,
@Reference(target = "(type=global-timer)") final Timer timer,
@Reference final SessionIdProvider sessionIdProvider,
final Configuration configuration) {
mappers.onAddNetconfOperationServiceFactory(mapperAggregatorRegistry);
monitoring = monitoringFactory.newInstance(FrameworkUtil.asDictionary(DefaultNetconfMonitoringService.props(
mapperAggregatorRegistry, sshScheduledExecutor, configuration.monitoring$_$update$_$interval())));
- dispatcher = dispatcherFactory.newInstance(FrameworkUtil.asDictionary(DefaultNetconfServerDispatcher.props(
- bossGroup, workerGroup, new ServerChannelInitializer(new NetconfServerSessionNegotiatorFactory(timer,
- mappers, sessionIdProvider, configuration.connection$_$timeout$_$millis(),
- monitoring.getInstance())))));
+ serverChannelInitializer = new ServerChannelInitializer(new NetconfServerSessionNegotiatorFactory(timer,
+ mappers, sessionIdProvider, configuration.connection$_$timeout$_$millis(), monitoring.getInstance()));
}
@Deactivate
public void deactivate() {
- dispatcher.dispose();
monitoring.dispose();
mappers.close();
}
+ ServerChannelInitializer serverChannelInitializer() {
+ return serverChannelInitializer;
+ }
+
static <T> T extractProp(final Map<String, ?> properties, final String key, final Class<T> valueType) {
return valueType.cast(verifyNotNull(properties.get(requireNonNull(key))));
}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.northbound;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.netconf.auth.AuthProvider;
+import org.opendaylight.netconf.server.BaseTransportChannelListener;
+import org.opendaylight.netconf.server.NetconfSubsystemFactory;
+import org.opendaylight.netconf.server.ServerChannelInitializer;
+import org.opendaylight.netconf.shaded.sshd.server.auth.password.UserAuthPasswordFactory;
+import org.opendaylight.netconf.shaded.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.netconf.transport.ssh.SSHServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.server.rev230417.netconf.server.listen.stack.grouping.transport.ssh.ssh.TcpServerParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev230417.TcpServerGrouping;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * NETCONF server for MD-SAL (listening by default on port 2830).
+ */
+@Component(service = { }, configurationPid = "org.opendaylight.netconf.ssh")
+@Designate(ocd = SshServerTransport.Configuration.class)
+public final class SshServerTransport extends BaseTransportChannelListener implements AutoCloseable {
+ @ObjectClassDefinition
+ public @interface Configuration {
+ @AttributeDefinition
+ String bindingAddress() default "0.0.0.0";
+ @AttributeDefinition(min = "1", max = "65535")
+ int portNumber() default 2830;
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(SshServerTransport.class);
+
+ private final SSHServer sshServer;
+
+ @Activate
+ public SshServerTransport(@Reference final TransportFactoryHolder factoryHolder,
+ @Reference final OSGiNetconfServer backend,
+ @Reference(target = "(type=netconf-auth-provider)") final AuthProvider authProvider,
+ final Configuration configuration) {
+ this(factoryHolder, backend.serverChannelInitializer(), authProvider, new TcpServerParametersBuilder()
+ .setLocalAddress(IetfInetUtil.ipAddressFor(configuration.bindingAddress()))
+ .setLocalPort(new PortNumber(Uint16.valueOf(configuration.portNumber())))
+ .build());
+ }
+
+ public SshServerTransport(final TransportFactoryHolder factoryHolder, final ServerChannelInitializer initializer,
+ final AuthProvider authProvider, final TcpServerGrouping listenParams) {
+ final var localAddr = listenParams.requireLocalAddress().stringValue();
+ final var localPort = listenParams.requireLocalPort().getValue();
+
+ try {
+ sshServer = factoryHolder.factory().listenServer(this, new NetconfSubsystemFactory(initializer),
+ listenParams, null, factoryMgr -> {
+ factoryMgr.setUserAuthFactories(List.of(UserAuthPasswordFactory.INSTANCE));
+ factoryMgr.setPasswordAuthenticator(
+ (username, password, session) -> authProvider.authenticated(username, password));
+ factoryMgr.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
+ })
+ .get();
+ } catch (UnsupportedConfigurationException | ExecutionException | InterruptedException e) {
+ LOG.warn("Could not start SSH NETCONF server at {}:{}", localAddr, localPort, e);
+ throw new IllegalStateException("Unable to start SSH netconf server", e);
+ }
+
+ LOG.info("SSH NETCONF server at {}:{} started", localAddr, localPort);
+ }
+
+ @Deactivate
+ @Override
+ public void close() throws IOException {
+ try {
+ sshServer.shutdown().get();
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.warn("Could not stop SSH NETCONF server {}", sshServer, e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Inocybe Technologies 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.northbound;
+
+import java.util.concurrent.ExecutionException;
+import org.opendaylight.netconf.server.BaseServerTransport;
+import org.opendaylight.netconf.server.ServerChannelInitializer;
+import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException;
+import org.opendaylight.netconf.transport.tcp.TCPServer;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.server.rev230417.netconf.server.listen.stack.grouping.transport.tls.tls.TcpServerParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.tcp.server.rev230417.TcpServerGrouping;
+import org.opendaylight.yangtools.yang.common.Uint16;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Create an MD-SAL NETCONF server using TCP.
+ */
+@Component(service = {}, configurationPid = "org.opendaylight.netconf.tcp", enabled = false)
+@Designate(ocd = TcpServerTransport.Configuration.class)
+public final class TcpServerTransport extends BaseServerTransport implements AutoCloseable {
+ @ObjectClassDefinition
+ public @interface Configuration {
+ @AttributeDefinition
+ String bindingAddress() default "0.0.0.0";
+
+ @AttributeDefinition(min = "1", max = "65535")
+ int portNumber() default 2831;
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(TcpServerTransport.class);
+
+ private final TCPServer tcpServer;
+
+ @Activate
+ public TcpServerTransport(@Reference final TransportFactoryHolder factoryHolder,
+ @Reference final OSGiNetconfServer backend, final Configuration configuration) {
+ // FIXME: create an instantiation and do not use TLS
+ this(factoryHolder, backend.serverChannelInitializer(), new TcpServerParametersBuilder()
+ .setLocalAddress(IetfInetUtil.ipAddressFor(configuration.bindingAddress()))
+ .setLocalPort(new PortNumber(Uint16.valueOf(configuration.portNumber())))
+ .build());
+ }
+
+ public TcpServerTransport(final TransportFactoryHolder factoryHolder, final ServerChannelInitializer initializer,
+ final TcpServerGrouping listenParams) {
+ super(initializer);
+
+ final var localAddr = listenParams.requireLocalAddress().stringValue();
+ final var localPort = listenParams.requireLocalPort().getValue();
+
+ try {
+ tcpServer = TCPServer.listen(this, factoryHolder.factory().newServerBootstrap(), listenParams).get();
+ } catch (UnsupportedConfigurationException | ExecutionException | InterruptedException e) {
+ LOG.warn("Could not start TCP NETCONF server at {}:{}", localAddr, localPort, e);
+ throw new IllegalStateException("Could not start TCP NETCONF server", e);
+ }
+
+ LOG.info("TCP NETCONF server at {}:{} started", localAddr, localPort);
+ }
+
+ @Deactivate
+ @Override
+ public void close() {
+ try {
+ tcpServer.shutdown().get();
+ } catch (ExecutionException | InterruptedException e) {
+ LOG.warn("Could not stop TCP NETCONF server {}", tcpServer, e);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.northbound;
+
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import org.opendaylight.netconf.transport.ssh.SSHTransportStackFactory;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.Designate;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A simple holder of {@link SSHTransportStackFactory}, bridging to configuration. The factory encapsulates Netty
+ * event loop groups, which is suitable for use with TLS/TCP transports as well.
+ */
+@Singleton
+@Component(service = TransportFactoryHolder.class, configurationPid = "org.opendaylight.netconf.northbound.netty")
+@Designate(ocd = TransportFactoryHolder.Configuration.class)
+public final class TransportFactoryHolder implements AutoCloseable {
+ /**
+ * Configuration of the NETCONF northbound.
+ */
+ @ObjectClassDefinition()
+ public @interface Configuration {
+ @AttributeDefinition(name = "Number of Netty boss threads", min = "0")
+ int boss$_$threads() default 0;
+
+ @AttributeDefinition(name = "Number of Netty worker threads", min = "0")
+ int worker$_$threads() default 0;
+ }
+
+ private static final Logger LOG = LoggerFactory.getLogger(TransportFactoryHolder.class);
+
+ private final SSHTransportStackFactory factory;
+
+ @Inject
+ public TransportFactoryHolder() {
+ this(0, 0);
+ }
+
+ @Activate
+ public TransportFactoryHolder(final Configuration configuration) {
+ this(configuration.boss$_$threads(), configuration.worker$_$threads());
+ }
+
+ public TransportFactoryHolder(final int bossThreads, final int workerThreads) {
+ factory = new SSHTransportStackFactory("odl-netconf-nb-worker", workerThreads,
+ "odl-netconf-nb-boss", bossThreads);
+ LOG.info("NETCONF Northbound Netty context initialized");
+ }
+
+ @PreDestroy
+ @Deactivate
+ @Override
+ public void close() {
+ LOG.info("NETCONF Northbound Netty context shutting down");
+ factory.close();
+ LOG.info("NETCONF Northbound Netty context shut down");
+ }
+
+ SSHTransportStackFactory factory() {
+ return factory;
+ }
+}
* Facade for guarding against {@link #shutdown()} invocations. This is necessary as SSHD wants to shutdown the executor
* when the server shuts down.
*/
+@Deprecated(since = "7.0.0", forRemoval = true)
final class ExecutorServiceFacade extends ForwardingExecutorService {
private final ExecutorService delegate;
* <p>
* Command is Apache Mina SSH terminology for objects handling ssh data.
*/
+@Deprecated(since = "7.0.0", forRemoval = true)
final class RemoteNetconfCommand implements AsyncCommand {
private static final Logger LOG = LoggerFactory.getLogger(RemoteNetconfCommand.class);
* Netty handler that reads SSH from remote client and writes to delegate server
* and reads from delegate server and writes to remote client.
*/
+@Deprecated(since = "7.0.0", forRemoval = true)
final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {
private static final Logger LOG = LoggerFactory.getLogger(SshProxyClientHandler.class);
* Proxy SSH server that just delegates decrypted content to a delegate server within same VM.
* Implemented using Apache Mina SSH lib.
*/
+@Deprecated(since = "7.0.0", forRemoval = true)
public class SshProxyServer implements AutoCloseable {
private final SshServer sshServer;
private final ScheduledExecutorService minaTimerExecutor;
import org.opendaylight.netconf.shaded.sshd.common.keyprovider.KeyPairProvider;
import org.opendaylight.netconf.shaded.sshd.server.auth.pubkey.PublickeyAuthenticator;
+@Deprecated(since = "7.0.0", forRemoval = true)
public final class SshProxyServerConfiguration {
private final InetSocketAddress bindingAddress;
private final LocalAddress localAddress;
import org.opendaylight.netconf.shaded.sshd.common.keyprovider.KeyPairProvider;
import org.opendaylight.netconf.shaded.sshd.server.auth.pubkey.PublickeyAuthenticator;
+@Deprecated(since = "7.0.0", forRemoval = true)
public final class SshProxyServerConfigurationBuilder {
private InetSocketAddress bindingAddress;
private LocalAddress localAddress;