[SSHD-838] Implement initial IoServiceEventListener in Nio2ServiceFactory
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/909e7ac0 Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/909e7ac0 Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/909e7ac0 Branch: refs/heads/master Commit: 909e7ac08ed5c0aa0db7ad00c753aec8d3aeb887 Parents: 881e9db Author: Goldstein Lyor <[email protected]> Authored: Sun Aug 5 15:08:15 2018 +0300 Committer: Lyor Goldstein <[email protected]> Committed: Sun Aug 5 19:35:53 2018 +0300 ---------------------------------------------------------------------- README.md | 6 + .../java/org/apache/sshd/cli/CliSupport.java | 73 ++++++++++- .../sshd/cli/client/SshClientCliSupport.java | 6 +- .../apache/sshd/cli/server/SshServerMain.java | 2 +- .../apache/sshd/cli/server/SshFsMounter.java | 4 +- .../org/apache/sshd/common/FactoryManager.java | 2 + .../common/helpers/AbstractFactoryManager.java | 12 ++ .../common/io/AbstractIoServiceFactory.java | 25 +++- .../org/apache/sshd/common/io/IoService.java | 2 +- .../sshd/common/io/IoServiceEventListener.java | 88 ++++++++++++++ .../io/IoServiceEventListenerManager.java | 28 +++++ .../apache/sshd/common/io/IoServiceFactory.java | 2 +- .../sshd/common/io/nio2/Nio2Acceptor.java | 34 +++++- .../sshd/common/io/nio2/Nio2Connector.java | 120 ++++++++++++------- .../apache/sshd/common/io/nio2/Nio2Service.java | 12 ++ .../sshd/common/io/nio2/Nio2ServiceFactory.java | 4 +- .../io/nio2/Nio2ServiceFactoryFactory.java | 9 +- .../apache/sshd/common/io/mina/MinaService.java | 13 ++ .../sshd/common/io/mina/MinaServiceFactory.java | 4 +- .../io/mina/MinaServiceFactoryFactory.java | 7 +- .../org/apache/sshd/netty/NettyIoAcceptor.java | 5 +- .../org/apache/sshd/netty/NettyIoConnector.java | 4 +- .../org/apache/sshd/netty/NettyIoService.java | 26 +++- .../sshd/netty/NettyIoServiceFactory.java | 13 ++ .../netty/NettyIoServiceFactoryFactory.java | 7 +- 25 files changed, 427 insertions(+), 81 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index a44b48d..251370a 100644 --- a/README.md +++ b/README.md @@ -1134,6 +1134,12 @@ In general, event listeners are **cumulative** - e.g., any channel event listene ``` +### `IoServiceEventListener` + +This listener provides low-level events regarding connection establishment (by the client) or acceptance (by the server). The listener is registered +on the `IoServiceFactory` via the `FactoryManager`-s (i.e., `SshClient/Server#setIoServiceEventListener`). Unlike other listeners defined in this +section, it is **not cumulative** - i.e., one can `setIoServiceEventListener` but not `addIoServiceEventListener` - thus **replacing** any previously +registered listener. ### `SessionListener` http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java ---------------------------------------------------------------------- diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java index 942fcf3..27c6d96 100644 --- a/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java @@ -18,10 +18,19 @@ */ package org.apache.sshd.cli; +import java.io.IOException; import java.io.PrintStream; +import java.net.SocketAddress; +import java.util.Map; +import java.util.Objects; +import org.apache.sshd.common.config.LogLevelValue; +import org.apache.sshd.common.config.SshConfigFileReader; import org.apache.sshd.common.helpers.AbstractFactoryManager; import org.apache.sshd.common.io.BuiltinIoServiceFactoryFactories; +import org.apache.sshd.common.io.IoAcceptor; +import org.apache.sshd.common.io.IoConnector; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoServiceFactoryFactory; import org.apache.sshd.common.util.GenericUtils; @@ -87,13 +96,75 @@ public abstract class CliSupport { return factory; } - public static <M extends AbstractFactoryManager> M setupIoServiceFactory(M manager, PrintStream stderr, String... args) { + public static <M extends AbstractFactoryManager> M setupIoServiceFactory( + M manager, Map<String, ?> options, PrintStream stdout, PrintStream stderr, String... args) { BuiltinIoServiceFactoryFactories factory = resolveIoServiceFactory(stderr, args); if (factory == null) { return null; } manager.setIoServiceFactoryFactory(factory.create()); + + String levelValue = (options == null) ? null : Objects.toString(options.get(SshConfigFileReader.LOG_LEVEL_CONFIG_PROP), null); + if (GenericUtils.isEmpty(levelValue)) { + return manager; + } + + LogLevelValue level = LogLevelValue.fromName(levelValue); + if (level == null) { + throw new IllegalArgumentException("Unknown " + SshConfigFileReader.LOG_LEVEL_CONFIG_PROP + " option value: " + levelValue); + } + + if ((level != LogLevelValue.FATAL) && (level != LogLevelValue.ERROR) && (level != LogLevelValue.INFO)) { + return manager; + } + + manager.setIoServiceEventListener(new IoServiceEventListener() { + private final PrintStream out = (level == LogLevelValue.INFO) ? stdout : stderr; + + @Override + public void connectionEstablished( + IoConnector connector, SocketAddress local, SocketAddress remote) + throws IOException { + out.append("Connection established via ").append(Objects.toString(connector)) + .append("- local=").append(Objects.toString(local)) + .append(", remote=").append(Objects.toString(remote)) + .println(); + } + + @Override + public void abortEstablishedConnection( + IoConnector connector, SocketAddress local, SocketAddress remote, Throwable reason) + throws IOException { + out.append("Abort established connection ").append(Objects.toString(connector)) + .append(" - local=").append(Objects.toString(local)) + .append(", remote=").append(Objects.toString(remote)) + .append(": (").append(reason.getClass().getSimpleName()).append(')') + .append(" ").println(reason.getMessage()); + reason.printStackTrace(out); + } + + @Override + public void connectionAccepted(IoAcceptor acceptor, SocketAddress local, SocketAddress remote) + throws IOException { + out.append("Connection accepted via ").append(Objects.toString(acceptor)) + .append(" - local=").append(Objects.toString(local)) + .append(", remote=").append(Objects.toString(remote)) + .println(); + } + + @Override + public void abortAcceptedConnection( + IoAcceptor acceptor, SocketAddress local, SocketAddress remote, Throwable reason) + throws IOException { + out.append("Abort accepted connection ").append(Objects.toString(acceptor)) + .append(" - local=").append(Objects.toString(local)) + .append(", remote=").append(Objects.toString(remote)) + .append(": (").append(reason.getClass().getSimpleName()).append(')') + .append(" ").println(reason.getMessage()); + reason.printStackTrace(out); + } + }); return manager; } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java ---------------------------------------------------------------------- diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java index 35d8717..0d7d2f5 100644 --- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java @@ -268,8 +268,8 @@ public abstract class SshClientCliSupport extends CliSupport { } } - public static SshClient setupDefaultClient(PrintStream stderr, String... args) { - return setupIoServiceFactory(SshClient.setUpDefaultClient(), System.err, args); + public static SshClient setupDefaultClient(Map<String, ?> options, PrintStream stdout, PrintStream stderr, String... args) { + return setupIoServiceFactory(SshClient.setUpDefaultClient(), options, stdout, stderr, args); } // returns null if error encountered @@ -305,7 +305,7 @@ public abstract class SshClientCliSupport extends CliSupport { } } - SshClient client = setupDefaultClient(stderr, args); + SshClient client = setupDefaultClient(options, stdout, stderr, args); if (client == null) { return null; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java ---------------------------------------------------------------------- diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java index b9f6d1e..0740d65 100644 --- a/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java +++ b/sshd-cli/src/main/java/org/apache/sshd/cli/server/SshServerMain.java @@ -146,7 +146,7 @@ public class SshServerMain extends SshServerCliSupport { } } - SshServer sshd = error ? null : setupIoServiceFactory(SshServer.setUpDefaultServer(), System.err, args); + SshServer sshd = error ? null : setupIoServiceFactory(SshServer.setUpDefaultServer(), options, System.out, System.err, args); if (sshd == null) { error = true; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java ---------------------------------------------------------------------- diff --git a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java index 4fe1d99..51596b1 100644 --- a/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java +++ b/sshd-cli/src/test/java/org/apache/sshd/cli/server/SshFsMounter.java @@ -283,6 +283,7 @@ public final class SshFsMounter extends SshServerCliSupport { error = true; break; } + String opt = args[++i]; int idx = opt.indexOf('='); if (idx <= 0) { @@ -294,7 +295,8 @@ public final class SshFsMounter extends SshServerCliSupport { } } - SshServer sshd = error ? null : setupIoServiceFactory(Utils.setupTestServer(SshFsMounter.class), System.err, args); + SshServer sshd = error ? null : setupIoServiceFactory( + Utils.setupTestServer(SshFsMounter.class), options, System.out, System.err, args); if (sshd == null) { error = true; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java index 50f4a54..31f0de6 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java @@ -30,6 +30,7 @@ import org.apache.sshd.common.channel.throttle.ChannelStreamPacketWriterResolver import org.apache.sshd.common.file.FileSystemFactory; import org.apache.sshd.common.forward.ForwardingFilterFactory; import org.apache.sshd.common.forward.PortForwardingEventListenerManager; +import org.apache.sshd.common.io.IoServiceEventListenerManager; import org.apache.sshd.common.io.IoServiceFactory; import org.apache.sshd.common.kex.KexFactoryManager; import org.apache.sshd.common.random.Random; @@ -56,6 +57,7 @@ public interface FactoryManager ChannelStreamPacketWriterResolverManager, UnknownChannelReferenceHandlerManager, PortForwardingEventListenerManager, + IoServiceEventListenerManager, AttributeStore, PropertyResolver { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/helpers/AbstractFactoryManager.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/helpers/AbstractFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/helpers/AbstractFactoryManager.java index a05fe65..7dd7f86 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/helpers/AbstractFactoryManager.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/helpers/AbstractFactoryManager.java @@ -46,6 +46,7 @@ import org.apache.sshd.common.file.FileSystemFactory; import org.apache.sshd.common.forward.ForwardingFilterFactory; import org.apache.sshd.common.forward.PortForwardingEventListener; import org.apache.sshd.common.io.DefaultIoServiceFactoryFactory; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoServiceFactory; import org.apache.sshd.common.io.IoServiceFactoryFactory; import org.apache.sshd.common.kex.AbstractKexFactoryManager; @@ -92,6 +93,7 @@ public abstract class AbstractFactoryManager extends AbstractKexFactoryManager i private ReservedSessionMessagesHandler reservedSessionMessagesHandler; private ChannelStreamPacketWriterResolver channelStreamPacketWriterResolver; private UnknownChannelReferenceHandler unknownChannelReferenceHandler; + private IoServiceEventListener eventListener; protected AbstractFactoryManager() { ClassLoader loader = getClass().getClassLoader(); @@ -119,6 +121,16 @@ public abstract class AbstractFactoryManager extends AbstractKexFactoryManager i } @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; + } + + @Override public Factory<Random> getRandomFactory() { return randomFactory; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java index b15262f..97e2bf0 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java @@ -35,12 +35,14 @@ public abstract class AbstractIoServiceFactory extends AbstractCloseable implements IoServiceFactory, FactoryManagerHolder, ExecutorServiceCarrier { + private IoServiceEventListener eventListener; private final FactoryManager manager; private final CloseableExecutorService executor; protected AbstractIoServiceFactory(FactoryManager factoryManager, CloseableExecutorService executorService) { - manager = Objects.requireNonNull(factoryManager); - executor = Objects.requireNonNull(executorService); + manager = Objects.requireNonNull(factoryManager, "No factory manager provided"); + executor = Objects.requireNonNull(executorService, "No executor service provided"); + eventListener = factoryManager.getIoServiceEventListener(); } @Override @@ -54,6 +56,16 @@ public abstract class AbstractIoServiceFactory } @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; + } + + @Override protected void doCloseImmediately() { try { CloseableExecutorService service = getExecutorService(); @@ -73,6 +85,15 @@ public abstract class AbstractIoServiceFactory } } + protected <S extends IoService> S autowireCreatedService(S service) { + if (service == null) { + return service; + } + + service.setIoServiceEventListener(getIoServiceEventListener()); + return service; + } + public static int getNioWorkers(FactoryManager manager) { int nb = manager.getIntProperty(FactoryManager.NIO_WORKERS, FactoryManager.DEFAULT_NIO_WORKERS); if (nb > 0) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java index 69dcdee..d6fcef3 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoService.java @@ -25,7 +25,7 @@ import org.apache.sshd.common.Closeable; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public interface IoService extends Closeable { +public interface IoService extends Closeable, IoServiceEventListenerManager { /** * Socket reuse address. * See {@link java.net.StandardSocketOptions#SO_REUSEADDR} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java new file mode 100644 index 0000000..7018825 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListener.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.sshd.common.io; + +import java.io.IOException; +import java.net.SocketAddress; + +import org.apache.sshd.common.util.SshdEventListener; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public interface IoServiceEventListener extends SshdEventListener { + /** + * Called when a new connection has been created to a remote peer - <u>before</u> it was + * converted into a session + * + * @param connector The {@link IoConnector} through which the connection was established + * @param local The local connection endpoint + * @param remote The remote connection endpoint + * @throws IOException If failed to handle the event - in which case connection will be aborted + */ + default void connectionEstablished(IoConnector connector, SocketAddress local, SocketAddress remote) throws IOException { + // Do nothing + } + + /** + * Called when a previously established connection has been abnormally terminated before it could be + * turned into a session + * + * @param acceptor The {@link IoConnector} through which the connection was established + * @param local The local connection endpoint + * @param remote The remote connection endpoint + * @param reason The reason for aborting - may be an exception thrown by + * {@link #connectionEstablished(IoConnector, SocketAddress, SocketAddress) connectionEstablished} + * @throws IOException If failed to handle the event - the exception is logged but does not + * prevent further connections from being accepted + */ + default void abortEstablishedConnection(IoConnector connector, SocketAddress local, SocketAddress remote, Throwable reason) throws IOException { + // Do nothing + } + + /** + * Called when a new connection has been accepted from a remote peer - <u>before</u> it was + * converted into a session + * + * @param acceptor The {@link IoAcceptor} through which the connection was accepted + * @param local The local connection endpoint + * @param remote The remote connection endpoint + * @throws IOException If failed to handle the event - in which case connection will be aborted + */ + default void connectionAccepted(IoAcceptor acceptor, SocketAddress local, SocketAddress remote) throws IOException { + // Do nothing + } + + /** + * Called when a previously accepted connection has been abnormally terminated before it could be + * turned into a session + * + * @param acceptor The {@link IoAcceptor} through which the connection was accepted + * @param local The local connection endpoint + * @param remote The remote connection endpoint + * @param reason The reason for aborting - may be an exception thrown by + * {@link #connectionAccepted(IoAcceptor, SocketAddress, SocketAddress) connectionAccepted} + * @throws IOException If failed to handle the event - the exception is logged but does not + * prevent further connections from being accepted + */ + default void abortAcceptedConnection(IoAcceptor acceptor, SocketAddress local, SocketAddress remote, Throwable reason) throws IOException { + // Do nothing + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListenerManager.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListenerManager.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListenerManager.java new file mode 100644 index 0000000..4dcf55e --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceEventListenerManager.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.common.io; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public interface IoServiceEventListenerManager { + IoServiceEventListener getIoServiceEventListener(); + + void setIoServiceEventListener(IoServiceEventListener listener); +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java index 6d8c261..d6c110b 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoServiceFactory.java @@ -23,7 +23,7 @@ import org.apache.sshd.common.Closeable; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public interface IoServiceFactory extends Closeable { +public interface IoServiceFactory extends Closeable, IoServiceEventListenerManager { IoConnector createConnector(IoHandler handler); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java index 1c63b54..0c90ce3 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java @@ -36,6 +36,7 @@ import org.apache.sshd.common.Closeable; import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.io.IoAcceptor; import org.apache.sshd.common.io.IoHandler; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.util.ValidateUtils; /** @@ -196,7 +197,14 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor { Nio2Session session = null; Long sessionId = null; boolean keepAccepting; + IoServiceEventListener listener = getIoServiceEventListener(); try { + if (listener != null) { + SocketAddress localAddress = result.getLocalAddress(); + SocketAddress remoteAddress = result.getRemoteAddress(); + listener.connectionAccepted(Nio2Acceptor.this, localAddress, remoteAddress); + } + // Create a session IoHandler handler = getIoHandler(); setSocketOptions(result); @@ -216,6 +224,17 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor { keepAccepting = true; } catch (Throwable exc) { + if (listener != null) { + try { + SocketAddress localAddress = result.getLocalAddress(); + SocketAddress remoteAddress = result.getRemoteAddress(); + listener.abortAcceptedConnection(Nio2Acceptor.this, localAddress, remoteAddress, exc); + } catch (Exception e) { + if (log.isDebugEnabled()) { + log.debug("onCompleted(" + address + ") listener=" + listener + " ignoring abort event exception", e); + } + } + } keepAccepting = okToReaccept(exc, address); // fail fast the accepted connection @@ -269,8 +288,9 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor { protected boolean okToReaccept(Throwable exc, SocketAddress address) { AsynchronousServerSocketChannel channel = channels.get(address); + boolean debugEnabled = log.isDebugEnabled(); if (channel == null) { - if (log.isDebugEnabled()) { + if (debugEnabled) { log.debug("Caught {} for untracked channel of {}: {}", exc.getClass().getSimpleName(), address, exc.getMessage()); } @@ -278,17 +298,19 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor { } if (disposing.get()) { - if (log.isDebugEnabled()) { + if (debugEnabled) { log.debug("Caught {} for tracked channel of {} while disposing: {}", exc.getClass().getSimpleName(), address, exc.getMessage()); } return false; } - log.warn("Caught {} while accepting incoming connection from {}: {}", - exc.getClass().getSimpleName(), address, exc.getMessage()); - if (log.isDebugEnabled()) { - log.debug("Incoming connection from " + address + " failure details", exc); + if (debugEnabled) { + log.debug("Caught {} while accepting incoming connection from {}: {}", + exc.getClass().getSimpleName(), address, exc.getMessage()); + } + if (log.isTraceEnabled()) { + log.trace("Incoming connection from " + address + " failure details", exc); } return true; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java index 2924caf..061795d 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Connector.java @@ -28,6 +28,7 @@ import org.apache.sshd.common.future.DefaultSshFuture; import org.apache.sshd.common.io.IoConnectFuture; import org.apache.sshd.common.io.IoConnector; import org.apache.sshd.common.io.IoHandler; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; @@ -60,9 +61,9 @@ public class Nio2Connector extends Nio2Service implements IoConnector { socket.bind(localAddress); } Nio2CompletionHandler<Void, Object> completionHandler = - ValidateUtils.checkNotNull(createConnectionCompletionHandler(future, socket, getFactoryManager(), getIoHandler()), - "No connection completion handler created for %s", - address); + ValidateUtils.checkNotNull(createConnectionCompletionHandler(future, socket, getFactoryManager(), getIoHandler()), + "No connection completion handler created for %s", + address); socket.connect(address, null, completionHandler); } catch (Throwable exc) { Throwable t = GenericUtils.peelException(exc); @@ -110,55 +111,88 @@ public class Nio2Connector extends Nio2Service implements IoConnector { protected Nio2CompletionHandler<Void, Object> createConnectionCompletionHandler( IoConnectFuture future, AsynchronousSocketChannel socket, FactoryManager manager, IoHandler handler) { - return new Nio2CompletionHandler<Void, Object>() { - @Override - @SuppressWarnings("synthetic-access") - protected void onCompleted(Void result, Object attachment) { - Long sessionId = null; - try { - Nio2Session session = createSession(manager, handler, socket); - handler.sessionCreated(session); - sessionId = session.getId(); - sessions.put(sessionId, session); - future.setSession(session); - if (session.isClosing()) { - try { - handler.sessionClosed(session); - } finally { - unmapSession(sessionId); - } - } else { - session.startReading(); - } - } catch (Throwable exc) { - Throwable t = GenericUtils.peelException(exc); - boolean debugEnabled = log.isDebugEnabled(); - if (debugEnabled) { - log.debug("onCompleted - failed {} to start session: {}", - t.getClass().getSimpleName(), t.getMessage()); - } - if (log.isTraceEnabled()) { - log.trace("onCompleted - session creation failure details", t); - } + return new ConnectionCompletionHandler(future, socket, manager, handler); + } + protected class ConnectionCompletionHandler extends Nio2CompletionHandler<Void, Object> { + protected final IoConnectFuture future; + protected final AsynchronousSocketChannel socket; + protected final FactoryManager manager; + protected final IoHandler handler; + + protected ConnectionCompletionHandler( + IoConnectFuture future, AsynchronousSocketChannel socket, FactoryManager manager, IoHandler handler) { + this.future = future; + this.socket = socket; + this.manager = manager; + this.handler = handler; + } + + @Override + @SuppressWarnings("synthetic-access") + protected void onCompleted(Void result, Object attachment) { + Long sessionId = null; + IoServiceEventListener listener = getIoServiceEventListener(); + try { + if (listener != null) { + SocketAddress local = socket.getLocalAddress(); + SocketAddress remote = socket.getRemoteAddress(); + listener.connectionEstablished(Nio2Connector.this, local, remote); + } + + Nio2Session session = createSession(manager, handler, socket); + handler.sessionCreated(session); + sessionId = session.getId(); + sessions.put(sessionId, session); + future.setSession(session); + if (session.isClosing()) { + try { + handler.sessionClosed(session); + } finally { + unmapSession(sessionId); + } + } else { + session.startReading(); + } + } catch (Throwable exc) { + Throwable t = GenericUtils.peelException(exc); + boolean debugEnabled = log.isDebugEnabled(); + if (listener != null) { try { - socket.close(); - } catch (IOException err) { + SocketAddress localAddress = socket.getLocalAddress(); + SocketAddress remoteAddress = socket.getRemoteAddress(); + listener.abortEstablishedConnection(Nio2Connector.this, localAddress, remoteAddress, t); + } catch (Exception e) { if (debugEnabled) { - log.debug("onCompleted - failed {} to close socket: {}", err.getClass().getSimpleName(), err.getMessage()); + log.debug("onCompleted() listener=" + listener + " ignoring abort event exception", e); } } + } - future.setException(t); - unmapSession(sessionId); + if (debugEnabled) { + log.debug("onCompleted - failed {} to start session: {}", t.getClass().getSimpleName(), t.getMessage()); + } + if (log.isTraceEnabled()) { + log.trace("onCompleted - session creation failure details", t); } - } - @Override - protected void onFailed(Throwable exc, Object attachment) { - future.setException(exc); + try { + socket.close(); + } catch (IOException err) { + if (debugEnabled) { + log.debug("onCompleted - failed {} to close socket: {}", err.getClass().getSimpleName(), err.getMessage()); + } + } + + future.setException(t); + unmapSession(sessionId); } - }; + } + + @Override + protected void onFailed(Throwable exc, Object attachment) { + future.setException(exc); + } } protected Nio2Session createSession(FactoryManager manager, IoHandler handler, AsynchronousSocketChannel socket) throws Throwable { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java index d0983ff..b340ec8 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java @@ -39,6 +39,7 @@ import org.apache.sshd.common.FactoryManagerHolder; import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoService; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.closeable.AbstractInnerCloseable; @@ -66,6 +67,7 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe private final FactoryManager manager; private final IoHandler handler; private final AsynchronousChannelGroup group; + private IoServiceEventListener eventListener; protected Nio2Service(FactoryManager manager, IoHandler handler, AsynchronousChannelGroup group) { if (log.isTraceEnabled()) { @@ -77,6 +79,16 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe this.sessions = new ConcurrentHashMap<>(); } + @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; + } + protected AsynchronousChannelGroup getChannelGroup() { return group; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java index 80c047f..493f2c5 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java @@ -54,12 +54,12 @@ public class Nio2ServiceFactory extends AbstractIoServiceFactory { @Override public IoConnector createConnector(IoHandler handler) { - return new Nio2Connector(getFactoryManager(), handler, group); + return autowireCreatedService(new Nio2Connector(getFactoryManager(), handler, group)); } @Override public IoAcceptor createAcceptor(IoHandler handler) { - return new Nio2Acceptor(getFactoryManager(), handler, group); + return autowireCreatedService(new Nio2Acceptor(getFactoryManager(), handler, group)); } @Override http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactoryFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactoryFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactoryFactory.java index 478f152..935fd92 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactoryFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactoryFactory.java @@ -28,18 +28,17 @@ import org.apache.sshd.common.io.IoServiceFactory; import org.apache.sshd.common.util.threads.CloseableExecutorService; /** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class Nio2ServiceFactoryFactory extends AbstractIoServiceFactoryFactory { - public Nio2ServiceFactoryFactory() { this(null); } /** - * @param executors The {@link CloseableExecutorService} to use for spawning threads. - * If {@code null} then an internal service is allocated - in which case it - * is automatically shutdown regardless of the value of the <tt>shutdownOnExit</tt> - * parameter value + * @param executors The {@link CloseableExecutorService} to use for spawning threads. + * If {@code null} then an internal service is allocated - in which case it + * is automatically shutdown */ public Nio2ServiceFactoryFactory(Factory<CloseableExecutorService> executors) { super(executors); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaService.java ---------------------------------------------------------------------- diff --git a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaService.java b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaService.java index 2a0c2ec..c183795 100644 --- a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaService.java +++ b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaService.java @@ -35,6 +35,7 @@ import org.apache.mina.transport.socket.SocketSessionConfig; import org.apache.mina.transport.socket.nio.NioSession; import org.apache.sshd.common.Closeable; import org.apache.sshd.common.FactoryManager; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.Readable; import org.apache.sshd.common.util.closeable.AbstractCloseable; @@ -48,12 +49,24 @@ public abstract class MinaService extends AbstractCloseable implements org.apach protected final IoProcessor<NioSession> ioProcessor; protected IoSessionConfig sessionConfig; + private IoServiceEventListener eventListener; + public MinaService(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) { this.manager = Objects.requireNonNull(manager, "No factory manager provided"); this.handler = Objects.requireNonNull(handler, "No IoHandler provided"); this.ioProcessor = Objects.requireNonNull(ioProcessor, "No IoProcessor provided"); } + @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; + } + protected abstract IoService getIoService(); public void dispose() { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactory.java ---------------------------------------------------------------------- diff --git a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactory.java b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactory.java index 2a4299a..6585fcb 100644 --- a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactory.java +++ b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactory.java @@ -46,11 +46,11 @@ public class MinaServiceFactory extends AbstractIoServiceFactory { @Override public IoConnector createConnector(IoHandler handler) { - return new MinaConnector(getFactoryManager(), handler, ioProcessor); + return autowireCreatedService(new MinaConnector(getFactoryManager(), handler, ioProcessor)); } @Override public IoAcceptor createAcceptor(IoHandler handler) { - return new MinaAcceptor(getFactoryManager(), handler, ioProcessor); + return autowireCreatedService(new MinaAcceptor(getFactoryManager(), handler, ioProcessor)); } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactoryFactory.java ---------------------------------------------------------------------- diff --git a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactoryFactory.java b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactoryFactory.java index 901bf3e..fdd190f 100644 --- a/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactoryFactory.java +++ b/sshd-mina/src/main/java/org/apache/sshd/common/io/mina/MinaServiceFactoryFactory.java @@ -25,6 +25,9 @@ import org.apache.sshd.common.io.IoServiceFactory; import org.apache.sshd.common.util.threads.CloseableExecutorService; /** + * TODO Add javadoc + * + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class MinaServiceFactoryFactory extends AbstractIoServiceFactoryFactory { public MinaServiceFactoryFactory() { @@ -32,8 +35,8 @@ public class MinaServiceFactoryFactory extends AbstractIoServiceFactoryFactory { } /** - * @param factory The {@link CloseableExecutorService} factory to use for spawning threads. - * If {@code null} then an internal service is allocated. + * @param factory The {@link CloseableExecutorService} factory to use for spawning threads. + * If {@code null} then an internal service is allocated. */ public MinaServiceFactoryFactory(Factory<CloseableExecutorService> factory) { super(factory); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoAcceptor.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoAcceptor.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoAcceptor.java index 7f710e1..05e6dcc 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoAcceptor.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoAcceptor.java @@ -58,11 +58,10 @@ public class NettyIoAcceptor extends NettyIoService implements IoAcceptor { protected final ServerBootstrap bootstrap = new ServerBootstrap(); protected final DefaultCloseFuture closeFuture = new DefaultCloseFuture(toString(), lock); protected final Map<SocketAddress, Channel> boundAddresses = new ConcurrentHashMap<>(); - protected final IoHandler handler; public NettyIoAcceptor(NettyIoServiceFactory factory, IoHandler handler) { - this.factory = factory; - this.handler = handler; + super(factory, handler); + channelGroup = new DefaultChannelGroup("sshd-acceptor-channels", GlobalEventExecutor.INSTANCE); bootstrap.group(factory.eventLoopGroup) .channel(NioServerSocketChannel.class) http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java index 9dde3d9..e6f0065 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoConnector.java @@ -48,11 +48,9 @@ import io.netty.util.concurrent.GlobalEventExecutor; public class NettyIoConnector extends NettyIoService implements IoConnector { protected final Bootstrap bootstrap = new Bootstrap(); - protected final IoHandler handler; public NettyIoConnector(NettyIoServiceFactory factory, IoHandler handler) { - this.factory = factory; - this.handler = handler; + super(factory, handler); channelGroup = new DefaultChannelGroup("sshd-connector-channels", GlobalEventExecutor.INSTANCE); bootstrap.group(factory.eventLoopGroup) .channel(NioSocketChannel.class) http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java index 9bd3ca3..a62326f 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoService.java @@ -20,11 +20,14 @@ package org.apache.sshd.netty; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import org.apache.sshd.common.io.IoConnectFuture; +import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoService; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.util.closeable.AbstractCloseable; @@ -35,17 +38,32 @@ import io.netty.util.AttributeKey; * @author <a href="mailto:[email protected]">Julien Viet</a> * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public class NettyIoService extends AbstractCloseable implements IoService { +public abstract class NettyIoService extends AbstractCloseable implements IoService { public static final AttributeKey<IoConnectFuture> CONNECT_FUTURE_KEY = AttributeKey.valueOf(IoConnectFuture.class.getName()); protected final AtomicLong sessionSeq = new AtomicLong(); protected final Map<Long, IoSession> sessions = new ConcurrentHashMap<>(); - protected NettyIoServiceFactory factory; protected ChannelGroup channelGroup; + protected final NettyIoServiceFactory factory; + protected final IoHandler handler; - public NettyIoService() { - super(); + private IoServiceEventListener eventListener; + + protected NettyIoService(NettyIoServiceFactory factory, IoHandler handler) { + this.factory = Objects.requireNonNull(factory, "No factory instance provided"); + this.handler = Objects.requireNonNull(handler, "No I/O handler provied"); + this.eventListener = factory.getIoServiceEventListener(); + } + + @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; } @Override http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactory.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactory.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactory.java index f65989b..aeeb07c 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactory.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactory.java @@ -23,6 +23,7 @@ import org.apache.sshd.common.future.CloseFuture; import org.apache.sshd.common.io.IoAcceptor; import org.apache.sshd.common.io.IoConnector; import org.apache.sshd.common.io.IoHandler; +import org.apache.sshd.common.io.IoServiceEventListener; import org.apache.sshd.common.io.IoServiceFactory; import org.apache.sshd.common.util.closeable.AbstractCloseable; @@ -39,6 +40,8 @@ public class NettyIoServiceFactory extends AbstractCloseable implements IoServic protected final EventLoopGroup eventLoopGroup; protected final boolean closeEventLoopGroup; + private IoServiceEventListener eventListener; + public NettyIoServiceFactory() { this(null); } @@ -49,6 +52,16 @@ public class NettyIoServiceFactory extends AbstractCloseable implements IoServic } @Override + public IoServiceEventListener getIoServiceEventListener() { + return eventListener; + } + + @Override + public void setIoServiceEventListener(IoServiceEventListener listener) { + eventListener = listener; + } + + @Override public IoConnector createConnector(IoHandler handler) { return new NettyIoConnector(this, handler); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/909e7ac0/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactoryFactory.java ---------------------------------------------------------------------- diff --git a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactoryFactory.java b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactoryFactory.java index 8cafba2..54a0fa0 100644 --- a/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactoryFactory.java +++ b/sshd-netty/src/main/java/org/apache/sshd/netty/NettyIoServiceFactoryFactory.java @@ -19,6 +19,8 @@ package org.apache.sshd.netty; +import java.util.Objects; + import org.apache.sshd.common.FactoryManager; import org.apache.sshd.common.io.AbstractIoServiceFactoryFactory; import org.apache.sshd.common.io.IoServiceFactory; @@ -44,6 +46,9 @@ public class NettyIoServiceFactoryFactory extends AbstractIoServiceFactoryFactor @Override public IoServiceFactory create(FactoryManager manager) { - return new NettyIoServiceFactory(eventLoopGroup); + Objects.requireNonNull(manager, "No factory manager provided"); + IoServiceFactory factory = new NettyIoServiceFactory(eventLoopGroup); + factory.setIoServiceEventListener(manager.getIoServiceEventListener()); + return factory; } }
