Repository: mina-sshd Updated Branches: refs/heads/master 4b02183ef -> f56963c44
[SSHD-694] Expose channel request handler management methods Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/439b71f5 Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/439b71f5 Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/439b71f5 Branch: refs/heads/master Commit: 439b71f58747306b0e081a25cedac26463611e77 Parents: 4b02183 Author: Lyor Goldstein <[email protected]> Authored: Sun Oct 2 16:05:08 2016 +0300 Committer: Lyor Goldstein <[email protected]> Committed: Sun Oct 2 16:05:08 2016 +0300 ---------------------------------------------------------------------- README.md | 6 +++--- .../sshd/common/channel/AbstractChannel.java | 19 ++++++++++++++----- .../org/apache/sshd/common/channel/Channel.java | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/439b71f5/README.md ---------------------------------------------------------------------- diff --git a/README.md b/README.md index 290fc68..29b6938 100644 --- a/README.md +++ b/README.md @@ -892,7 +892,8 @@ rather than being accumulated. However, one can use the `EventListenerUtils` and The code supports both [global](https://tools.ietf.org/html/rfc4254#section-4) and [channel-specific](https://tools.ietf.org/html/rfc4254#section-5.4) requests via the registration of `RequestHandler`(s). The global handlers are derived from `ConnectionServiceRequestHandler`(s) whereas the channel-specific ones are derived from `ChannelRequestHandler`(s). In order to add a handler one need only register the correct -implementation and handle the request when it is detected: +implementation and handle the request when it is detected. For global request handlers this is done by registering +them on the server: ```java @@ -907,10 +908,9 @@ implementation and handle the request when it is detected: newGlobals.add(new MyGlobalRequestHandler()); server.setGlobalRequestHandlers(newGlobals); - // Similar code can be done with the server's channelRequestHandlers(); ``` -The way request handlers are invoked when a global/channel-specific request is received is as follows: +For channel-specific requests, one uses the channel's `add/removeRequestHandler` method to manage its handlers. The way request handlers are invoked when a global/channel-specific request is received is as follows: * All currently registered handlers' `process` method is invoked with the request type string parameter (among others). The implementation should examine the request parameters and decide whether it is able to process it. http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/439b71f5/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java index 89f84af..23c7f5a 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java @@ -20,13 +20,14 @@ package org.apache.sshd.common.channel; import java.io.EOFException; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; @@ -80,7 +81,6 @@ public abstract class AbstractChannel protected final AtomicBoolean eofSent = new AtomicBoolean(false); protected AtomicReference<GracefulState> gracefulState = new AtomicReference<>(GracefulState.Opened); protected final DefaultCloseFuture gracefulFuture = new DefaultCloseFuture(lock); - protected final List<RequestHandler<Channel>> handlers = new ArrayList<>(); /** * Channel events listener */ @@ -93,6 +93,7 @@ public abstract class AbstractChannel private Session sessionInstance; private ExecutorService executor; private boolean shutdownExecutor; + private final List<RequestHandler<Channel>> requestHandlers = new CopyOnWriteArrayList<>(); private final Window localWindow; private final Window remoteWindow; @@ -124,12 +125,19 @@ public abstract class AbstractChannel addRequestHandlers(handlers); } - public void addRequestHandlers(Collection<? extends RequestHandler<Channel>> handlers) { - GenericUtils.forEach(handlers, this::addRequestHandler); + @Override + public List<RequestHandler<Channel>> getRequestHandlers() { + return requestHandlers; } + @Override public void addRequestHandler(RequestHandler<Channel> handler) { - handlers.add(ValidateUtils.checkNotNull(handler, "No handler instance")); + requestHandlers.add(Objects.requireNonNull(handler, "No handler instance")); + } + + @Override + public void removeRequestHandler(RequestHandler<Channel> handler) { + requestHandlers.remove(Objects.requireNonNull(handler, "No handler instance")); } @Override @@ -240,6 +248,7 @@ public abstract class AbstractChannel log.debug("handleChannelRequest({}) SSH_MSG_CHANNEL_REQUEST {} wantReply={}", this, req, wantReply); } + Collection<? extends RequestHandler<Channel>> handlers = getRequestHandlers(); for (RequestHandler<Channel> handler : handlers) { RequestHandler.Result result; try { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/439b71f5/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java index dae79a0..fa5e226 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java @@ -19,6 +19,8 @@ package org.apache.sshd.common.channel; import java.io.IOException; +import java.util.Collection; +import java.util.List; import org.apache.sshd.client.future.OpenFuture; import org.apache.sshd.common.AttributeStore; @@ -26,6 +28,7 @@ import org.apache.sshd.common.Closeable; import org.apache.sshd.common.PropertyResolver; import org.apache.sshd.common.session.ConnectionService; import org.apache.sshd.common.session.Session; +import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.buffer.Buffer; /** @@ -63,6 +66,18 @@ public interface Channel Window getRemoteWindow(); + List<RequestHandler<Channel>> getRequestHandlers(); + + void addRequestHandler(RequestHandler<Channel> handler); + default void addRequestHandlers(Collection<? extends RequestHandler<Channel>> handlers) { + GenericUtils.forEach(handlers, this::addRequestHandler); + } + + void removeRequestHandler(RequestHandler<Channel> handler); + default void removeRequestHandlers(Collection<? extends RequestHandler<Channel>> handlers) { + GenericUtils.forEach(handlers, this::removeRequestHandler); + } + /** * Invoked when <code>SSH_MSG_CHANNEL_CLOSE</code> received *
