You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2019/02/19 14:45:59 UTC

[mina-sshd] 01/02: [SSHD-897] Provide channel instance in SignalListener#signal invocation

This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch SSHD-897
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 995970a964b60446c999d7f33c8a93bc1813200f
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Tue Feb 19 13:58:50 2019 +0200

    [SSHD-897] Provide channel instance in SignalListener#signal invocation
---
 CHANGES.md                                         |  2 ++
 .../org/apache/sshd/common/channel/PtyMode.java    |  0
 .../org/apache/sshd/common/util/GenericUtils.java  | 16 +++++++++++
 .../java/org/apache/sshd/server/ExitCallback.java  |  0
 .../main/java/org/apache/sshd/server/Signal.java   |  0
 .../apache/sshd/common/channel/PtyModeTest.java    |  4 +--
 .../java/org/apache/sshd/server/Environment.java   | 19 ++++++++-----
 .../org/apache/sshd/server/SignalListener.java     |  5 ++--
 .../apache/sshd/server/StandardEnvironment.java    | 33 +++++++++-------------
 .../apache/sshd/server/channel/ChannelSession.java |  8 ++++--
 .../sshd/server/StandardEnvironmentTest.java       |  2 +-
 11 files changed, 54 insertions(+), 35 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 07b4430..aba6cfa 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -18,6 +18,8 @@ current sesssion - client/server proposals and what has been negotiated.
 
 * The `Session` object provides a `KexExtensionHandler` for usage with [KEX extension negotiation](https://tools.wordtothewise.com/rfc/rfc8308)
 
+* The `SignalListener` accepts a `Channel` argument indicating the channel instance through which the signal was received
+
 ## Behavioral changes and enhancements
 
 * [SSHD-882](https://issues.apache.org/jira/browse/SSHD-882) - Provide hooks to allow users to register a consumer
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java b/sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java
similarity index 100%
rename from sshd-core/src/main/java/org/apache/sshd/common/channel/PtyMode.java
rename to sshd-common/src/main/java/org/apache/sshd/common/channel/PtyMode.java
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java
index 294148d..ea75c08 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/GenericUtils.java
@@ -595,6 +595,22 @@ public final class GenericUtils {
         return set;
     }
 
+    @SafeVarargs
+    public static <E extends Enum<E>> Set<E> asEnumSet(E... values) {
+        if (isEmpty(values)) {
+            return Collections.emptySet();
+        }
+
+        Set<E> s = EnumSet.of(values[0]);
+        for (int index = 1 /* we used [0] to populate the initial set */; index < values.length; index++) {
+            if (!s.add(values[index])) {
+                continue;   // debug breakpoint
+            }
+        }
+
+        return s;
+    }
+
     /**
      * @param <V> Type of mapped value
      * @return A {@link Supplier} that returns a <U>new</U> {@link NavigableMap}
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java b/sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java
similarity index 100%
rename from sshd-core/src/main/java/org/apache/sshd/server/ExitCallback.java
rename to sshd-common/src/main/java/org/apache/sshd/server/ExitCallback.java
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Signal.java b/sshd-common/src/main/java/org/apache/sshd/server/Signal.java
similarity index 100%
rename from sshd-core/src/main/java/org/apache/sshd/server/Signal.java
rename to sshd-common/src/main/java/org/apache/sshd/server/Signal.java
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
similarity index 95%
rename from sshd-core/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
rename to sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
index 819bc3a..3234948 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
+++ b/sshd-common/src/test/java/org/apache/sshd/common/channel/PtyModeTest.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import java.util.Set;
 
 import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.util.test.BaseTestSupport;
+import org.apache.sshd.util.test.JUnitTestSupport;
 import org.apache.sshd.util.test.NoIoTestCase;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -36,7 +36,7 @@ import org.junit.runners.MethodSorters;
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @Category({ NoIoTestCase.class })
-public class PtyModeTest extends BaseTestSupport {
+public class PtyModeTest extends JUnitTestSupport {
     public PtyModeTest() {
         super();
     }
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
index 192cb86..ea3d769 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.sshd.common.channel.PtyMode;
+import org.apache.sshd.common.util.GenericUtils;
 
 /**
  * Interface providing access to the environment map and allowing the registration
@@ -73,24 +74,28 @@ public interface Environment {
      * Add a qualified listener for the specific signals
      *
      * @param listener the {@link SignalListener} to register
-     * @param signal   the {@link Signal}s  the listener is interested in
+     * @param signals The (never {@code null}/empty) {@link Signal}s the listener is interested in
      */
-    void addSignalListener(SignalListener listener, Signal... signal);
+    default void addSignalListener(SignalListener listener, Signal... signals) {
+        addSignalListener(listener, GenericUtils.asEnumSet(signals));
+    }
 
     /**
-     * Add a qualified listener for the specific signals
+     * Add a global listener for all signals
      *
      * @param listener the {@link SignalListener} to register
-     * @param signals  the {@link Signal}s the listener is interested in
      */
-    void addSignalListener(SignalListener listener, Collection<Signal> signals);
+    default void addSignalListener(SignalListener listener) {
+        addSignalListener(listener, Signal.SIGNALS);
+    }
 
     /**
-     * Add a global listener for all signals
+     * Add a qualified listener for the specific signals
      *
      * @param listener the {@link SignalListener} to register
+     * @param signals  the {@link Signal}s the listener is interested in
      */
-    void addSignalListener(SignalListener listener);
+    void addSignalListener(SignalListener listener, Collection<Signal> signals);
 
     /**
      * Remove a previously registered listener for all the signals it was registered
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java b/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
index 2675e5c..ef1b7b7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SignalListener.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sshd.server;
 
+import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.util.SshdEventListener;
 
 /**
@@ -27,11 +28,11 @@ import org.apache.sshd.common.util.SshdEventListener;
  */
 @FunctionalInterface
 public interface SignalListener extends SshdEventListener {
-
     /**
+     * @param channel The {@link Channel} through which the signal was received
      * @param signal The received {@link Signal}
      */
-    void signal(Signal signal);
+    void signal(Channel channel, Signal signal);
 
     static <L extends SignalListener> L validateListener(L listener) {
         return SshdEventListener.validateListener(listener, SignalListener.class.getSimpleName());
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java b/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
index 8c67a43..1e16a3a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/StandardEnvironment.java
@@ -18,12 +18,12 @@
  */
 package org.apache.sshd.server;
 
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 
+import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.PtyMode;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
@@ -43,16 +43,6 @@ public class StandardEnvironment extends AbstractLoggingBean implements Environm
         ptyModes = new ConcurrentHashMap<>();
     }
 
-    @Override
-    public void addSignalListener(SignalListener listener, Signal... signals) {
-        addSignalListener(listener, Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(signals, "No signals")));
-    }
-
-    @Override
-    public void addSignalListener(SignalListener listener) {
-        addSignalListener(listener, Signal.SIGNALS);
-    }
-
     /*
      * NOTE: we don't care if the collection is a Set or not - after all,
      * we hold the listeners inside a Set, so even if we add several times
@@ -64,7 +54,8 @@ public class StandardEnvironment extends AbstractLoggingBean implements Environm
         ValidateUtils.checkNotNullAndNotEmpty(signals, "No signals");
 
         for (Signal s : signals) {
-            getSignalListeners(s, true).add(listener);
+            Collection<SignalListener> list = getSignalListeners(s, true);
+            list.add(listener);
         }
     }
 
@@ -93,26 +84,27 @@ public class StandardEnvironment extends AbstractLoggingBean implements Environm
         }
     }
 
-    public void signal(Signal signal) {
+    public void signal(Channel channel, Signal signal) {
         Collection<SignalListener> ls = getSignalListeners(signal, false);
         if (log.isDebugEnabled()) {
-            log.debug("signal({}) - listeners={}", signal, ls);
+            log.debug("signal({})[{}] - listeners={}", channel, signal, ls);
         }
 
         if (GenericUtils.isEmpty(ls)) {
             return;
         }
 
+        boolean traceEnabled = log.isTraceEnabled();
         for (SignalListener l : ls) {
             try {
-                l.signal(signal);
+                l.signal(channel, signal);
 
-                if (log.isTraceEnabled()) {
-                    log.trace("Signal {} to {}", signal, l);
+                if (traceEnabled) {
+                    log.trace("signal({}) Signal {} to {}", channel, signal, l);
                 }
             } catch (RuntimeException e) {
-                log.warn("Failed ({}) to signal {} to listener={}: {}",
-                         e.getClass().getSimpleName(), signal, l, e.getMessage());
+                log.warn("signal({}) Failed ({}) to signal {} to listener={}: {}",
+                     channel, e.getClass().getSimpleName(), signal, l, e.getMessage());
             }
         }
     }
@@ -126,7 +118,8 @@ public class StandardEnvironment extends AbstractLoggingBean implements Environm
      */
     public void set(String key, String value) {
         // TODO: listening for property changes would be nice too.
-        getEnv().put(ValidateUtils.checkNotNullAndNotEmpty(key, "Empty environment variable name"), value);
+        Map<String, String> environ = getEnv();
+        environ.put(ValidateUtils.checkNotNullAndNotEmpty(key, "Empty environment variable name"), value);
     }
 
     /**
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index ab57cb1..2c2f6bd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -471,7 +471,7 @@ public class ChannelSession extends AbstractServerChannel {
         StandardEnvironment e = getEnvironment();
         e.set(Environment.ENV_COLUMNS, Integer.toString(tColumns));
         e.set(Environment.ENV_LINES, Integer.toString(tRows));
-        e.signal(Signal.WINCH);
+        e.signal(this, Signal.WINCH);
         return RequestHandler.Result.ReplySuccess;
     }
 
@@ -484,7 +484,8 @@ public class ChannelSession extends AbstractServerChannel {
 
         Signal signal = Signal.get(name);
         if (signal != null) {
-            getEnvironment().signal(signal);
+            StandardEnvironment environ = getEnvironment();
+            environ.signal(this, signal);
         } else {
             log.warn("handleSignal({}) unknown signal received: {}", this, name);
         }
@@ -498,7 +499,8 @@ public class ChannelSession extends AbstractServerChannel {
             log.debug("handleBreak({}) length={}", this, breakLength);
         }
 
-        getEnvironment().signal(Signal.INT);
+        StandardEnvironment environ = getEnvironment();
+        environ.signal(this, Signal.INT);
         return RequestHandler.Result.ReplySuccess;
     }
 
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/StandardEnvironmentTest.java b/sshd-core/src/test/java/org/apache/sshd/server/StandardEnvironmentTest.java
index 2e36d57..7b18a77 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/StandardEnvironmentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/StandardEnvironmentTest.java
@@ -42,7 +42,7 @@ public class StandardEnvironmentTest extends BaseTestSupport {
     @Test
     public void testAddSignalListenerOnDuplicateSignals() {
         StandardEnvironment environ = new StandardEnvironment();
-        SignalListener listener = signal -> {
+        SignalListener listener = (channel, signal) -> {
             // ignored
         };