This is an automated email from the ASF dual-hosted git repository. lgoldstein pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
The following commit(s) were added to refs/heads/master by this push: new 53bcfd8 Added more overloads that use Duration(s) as timeout values 53bcfd8 is described below commit 53bcfd855db96b2f2f6fd6a37fba372b632509c0 Author: Lyor Goldstein <lgoldst...@apache.org> AuthorDate: Sun Mar 1 21:42:30 2020 +0200 Added more overloads that use Duration(s) as timeout values --- CHANGES.md | 2 + .../common/session/SessionHeartbeatController.java | 12 ++++ .../util/threads/CloseableExecutorService.java | 8 ++- .../channel/throttle/ThrottlingPacketWriter.java | 3 +- .../org/apache/sshd/common/session/Session.java | 73 +++++++++++++++++++++- .../common/session/helpers/AbstractSession.java | 15 ++--- 6 files changed, 101 insertions(+), 12 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 56f0b06..f978527 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,8 @@ been received - see [SSHD-968](https://issues.apache.org/jira/browse/SSHD-968). * Handling of debug/ignore/unimplemented messages has been split into `handleXXX` and `doInvokeXXXMsgHandler` methods where the former validate the messages and deal with the idle timeout, and the latter execute the actual invcation. +* Added overloaded methods that accept a `java.time.Duration` specifier for timeout value. + ## Behavioral changes and enhancements * [SSHD-964](https://issues.apache.org/jira/browse/SSHD-964) - Send SSH_MSG_CHANNEL_EOF when tunnel channel being closed. diff --git a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionHeartbeatController.java b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionHeartbeatController.java index be1f75d..7858d61 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionHeartbeatController.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionHeartbeatController.java @@ -19,6 +19,7 @@ package org.apache.sshd.common.session; +import java.time.Duration; import java.util.EnumSet; import java.util.Objects; import java.util.Set; @@ -88,4 +89,15 @@ public interface SessionHeartbeatController extends PropertyResolver { PropertyResolverUtils.updateProperty(this, SESSION_HEARTBEAT_TYPE, type); PropertyResolverUtils.updateProperty(this, SESSION_HEARTBEAT_INTERVAL, TimeUnit.MILLISECONDS.convert(count, unit)); } + + /** + * Set the session heartbeat + * + * @param type The type of {@link HeartbeatType heartbeat} to use + * @param interval The (never {@code null}) heartbeat interval - its milliseconds value is used + */ + default void setSessionHeartbeat(HeartbeatType type, Duration interval) { + Objects.requireNonNull(interval, "No interval specified"); + setSessionHeartbeat(type, TimeUnit.MILLISECONDS, interval.toMillis()); + } } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java index 3b9beeb..0dd51f3 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/util/threads/CloseableExecutorService.java @@ -19,10 +19,16 @@ package org.apache.sshd.common.util.threads; +import java.time.Duration; +import java.util.Objects; import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; import org.apache.sshd.common.Closeable; public interface CloseableExecutorService extends ExecutorService, Closeable { - // Nothing extra + default boolean awaitTermination(Duration timeout) throws InterruptedException { + Objects.requireNonNull(timeout, "No timeout specified"); + return awaitTermination(timeout.toMillis(), TimeUnit.MILLISECONDS); + } } diff --git a/sshd-contrib/src/main/java/org/apache/sshd/common/channel/throttle/ThrottlingPacketWriter.java b/sshd-contrib/src/main/java/org/apache/sshd/common/channel/throttle/ThrottlingPacketWriter.java index 00be698..543d171 100644 --- a/sshd-contrib/src/main/java/org/apache/sshd/common/channel/throttle/ThrottlingPacketWriter.java +++ b/sshd-contrib/src/main/java/org/apache/sshd/common/channel/throttle/ThrottlingPacketWriter.java @@ -78,7 +78,8 @@ public class ThrottlingPacketWriter extends AbstractLoggingBean implements Packe TimeUnit.SECONDS, PropertyResolverUtils.getLongProperty(resolver, WAIT_TIME_PROP, DEFAULT_MAX_WAIT_TIME)); } - public ThrottlingPacketWriter(PacketWriter delegate, int maxPendingPackets, TimeUnit waitUnit, long waitCount) { + public ThrottlingPacketWriter( + PacketWriter delegate, int maxPendingPackets, TimeUnit waitUnit, long waitCount) { this(delegate, maxPendingPackets, waitUnit.toMillis(waitCount)); } diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java index a9d59d4..70c5c80 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java @@ -20,6 +20,7 @@ package org.apache.sshd.common.session; import java.io.IOException; import java.net.SocketAddress; +import java.time.Duration; import java.util.Objects; import java.util.concurrent.TimeUnit; @@ -39,6 +40,7 @@ import org.apache.sshd.common.io.PacketWriter; import org.apache.sshd.common.kex.KexFactoryManager; import org.apache.sshd.common.kex.KeyExchange; import org.apache.sshd.common.session.helpers.TimeoutIndicator; +import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.common.util.buffer.Buffer; /** @@ -124,6 +126,39 @@ public interface Session * {@link java.util.concurrent.TimeoutException} exception to indicate a timeout. * * @param buffer the buffer to encode and spend + * @param timeout the (never {@code null}) timeout value - its + * {@link Duration#toMillis() milliseconds} value will be used + * @return a future that can be used to check when the packet has actually been sent + * @throws IOException if an error occurred when encoding sending the packet + * @see #writePacket(Buffer, long) + */ + default IoWriteFuture writePacket(Buffer buffer, Duration timeout) throws IOException { + Objects.requireNonNull(timeout, "No timeout was specified"); + return writePacket(buffer, timeout.toMillis()); + } + + /** + * Encode and send the given buffer with the specified timeout. + * If the buffer could not be written before the timeout elapses, the returned + * {@link org.apache.sshd.common.io.IoWriteFuture} will be set with a + * {@link java.util.concurrent.TimeoutException} exception to indicate a timeout. + * + * @param buffer the buffer to encode and spend + * @param maxWaitMillis the timeout in milliseconds + * @return a future that can be used to check when the packet has actually been sent + * @throws IOException if an error occurred when encoding sending the packet + */ + default IoWriteFuture writePacket(Buffer buffer, long maxWaitMillis) throws IOException { + return writePacket(buffer, maxWaitMillis, TimeUnit.MILLISECONDS); + } + + /** + * Encode and send the given buffer with the specified timeout. + * If the buffer could not be written before the timeout elapses, the returned + * {@link org.apache.sshd.common.io.IoWriteFuture} will be set with a + * {@link java.util.concurrent.TimeoutException} exception to indicate a timeout. + * + * @param buffer the buffer to encode and spend * @param timeout the timeout * @param unit the time unit of the timeout parameter * @return a future that can be used to check when the packet has actually been sent @@ -141,8 +176,44 @@ public interface Session * @param unit The {@link TimeUnit} to wait for the response * @return the return buffer if the request was successful, {@code null} otherwise. * @throws IOException if an error occurred when encoding sending the packet + * @throws java.net.SocketTimeoutException If no response received within specified timeout + */ + default Buffer request( + String request, Buffer buffer, long timeout, TimeUnit unit) + throws IOException { + ValidateUtils.checkTrue(timeout > 0L, "Non-positive timeout requested: %d", timeout); + return request(request, buffer, TimeUnit.MILLISECONDS.convert(timeout, unit)); + } + + /** + * + * Send a global request and wait for the response. This must only be used when sending + * a {@code SSH_MSG_GLOBAL_REQUEST} with a result expected, else it will time out + * + * @param request the request name - used mainly for logging and debugging + * @param buffer the buffer containing the global request + * @param timeout The (never {@code null}) timeout to wait - its milliseconds value is used + * @return the return buffer if the request was successful, {@code null} otherwise. + * @throws IOException if an error occurred when encoding sending the packet + * @throws java.net.SocketTimeoutException If no response received within specified timeout + */ + default Buffer request(String request, Buffer buffer, Duration timeout) throws IOException { + Objects.requireNonNull(timeout, "No timeout specified"); + return request(request, buffer, timeout.toMillis()); + } + + /** + * Send a global request and wait for the response. This must only be used when sending + * a {@code SSH_MSG_GLOBAL_REQUEST} with a result expected, else it will time out + * + * @param request the request name - used mainly for logging and debugging + * @param buffer the buffer containing the global request + * @param maxWaitMillis Max. time to wait for response (millis) - must be <U>positive</U> + * @return the return buffer if the request was successful, {@code null} otherwise. + * @throws IOException if an error occurred when encoding sending the packet + * @throws java.net.SocketTimeoutException If no response received within specified timeout */ - Buffer request(String request, Buffer buffer, long timeout, TimeUnit unit) throws IOException; + Buffer request(String request, Buffer buffer, long maxWaitMillis) throws IOException; /** * Handle any exceptions that occurred on this session. diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java index 5c43b8b..d654844 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java @@ -956,18 +956,15 @@ public abstract class AbstractSession extends SessionHelper { } @Override - public Buffer request(String request, Buffer buffer, long timeout, TimeUnit unit) throws IOException { - ValidateUtils.checkTrue(timeout > 0L, "Non-positive timeout requested: %d", timeout); - - long maxWaitMillis = TimeUnit.MILLISECONDS.convert(timeout, unit); + public Buffer request(String request, Buffer buffer, long maxWaitMillis) throws IOException { if (maxWaitMillis <= 0L) { throw new IllegalArgumentException( - "Requested timeout for " + request + " below 1 msec: " + timeout + " " + unit); + "Requested timeout for " + request + " below 1 msec: " + maxWaitMillis); } boolean debugEnabled = log.isDebugEnabled(); if (debugEnabled) { - log.debug("request({}) request={}, timeout={} {}", this, request, timeout, unit); + log.debug("request({}) request={}, timeout={}ms", this, request, maxWaitMillis); } Object result; @@ -1018,13 +1015,13 @@ public abstract class AbstractSession extends SessionHelper { } if (debugEnabled) { - log.debug("request({}) request={}, timeout={} {}, requestSeqNo={}, result received={}", - this, request, timeout, unit, prevGlobalReqSeqNo, result != null); + log.debug("request({}) request={}, timeout={}ms, requestSeqNo={}, result received={}", + this, request, maxWaitMillis, prevGlobalReqSeqNo, result != null); } if (result == null) { throw new SocketTimeoutException( - "No response received after " + timeout + " " + unit + " for request=" + request); + "No response received after " + maxWaitMillis + "ms for request=" + request); } if (result instanceof Buffer) {