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
      *

Reply via email to