public abstract class AbstractChannel extends AbstractInnerCloseable implements Channel, ExecutorServiceCarrier
Modifier and Type | Class and Description |
---|---|
class |
AbstractChannel.GracefulChannelCloseable |
protected static class |
AbstractChannel.GracefulState |
AbstractCloseable.State
AttributeRepository.AttributeKey<T>
Modifier and Type | Field and Description |
---|---|
private java.util.Map<AttributeRepository.AttributeKey<?>,java.lang.Object> |
attributes |
protected ChannelListener |
channelListenerProxy |
protected java.util.Collection<ChannelListener> |
channelListeners
Channel events listener
|
private ChannelStreamWriterResolver |
channelStreamPacketWriterResolver |
protected java.util.concurrent.atomic.AtomicBoolean |
eofReceived |
protected java.util.concurrent.atomic.AtomicBoolean |
eofSent |
private CloseableExecutorService |
executor |
protected DefaultCloseFuture |
gracefulFuture |
protected java.util.concurrent.atomic.AtomicReference<AbstractChannel.GracefulState> |
gracefulState |
private int |
id |
protected java.util.concurrent.atomic.AtomicBoolean |
initialized |
private Window |
localWindow |
private java.util.Map<java.lang.String,java.util.Date> |
pendingRequests
A
Map of sent requests - key = request name, value = timestamp when request was sent. |
private java.util.Map<java.lang.String,java.lang.Object> |
properties |
private int |
recipient |
private Window |
remoteWindow |
private java.util.List<RequestHandler<Channel>> |
requestHandlers |
static java.util.function.IntUnaryOperator |
RESPONSE_BUFFER_GROWTH_FACTOR
Default growth factor function used to resize response buffers
|
protected ConnectionService |
service |
private Session |
sessionInstance |
closeFuture, futureLock, state
log
CHANNEL_EXEC, CHANNEL_SHELL, CHANNEL_SUBSYSTEM
EMPTY
NONE
Modifier | Constructor and Description |
---|---|
protected |
AbstractChannel(boolean client) |
protected |
AbstractChannel(boolean client,
java.util.Collection<? extends RequestHandler<Channel>> handlers) |
protected |
AbstractChannel(java.lang.String discriminator,
boolean client) |
protected |
AbstractChannel(java.lang.String discriminator,
boolean client,
java.util.Collection<? extends RequestHandler<Channel>> handlers,
CloseableExecutorService executorService) |
Modifier and Type | Method and Description |
---|---|
void |
addChannelListener(ChannelListener listener)
Add a channel listener
|
protected java.util.Date |
addPendingRequest(java.lang.String request,
boolean wantReply)
Add a channel request to the tracked pending ones if reply is expected
|
void |
addRequestHandler(RequestHandler<Channel> handler) |
java.util.Collection<AttributeRepository.AttributeKey<?>> |
attributeKeys() |
void |
clearAttributes()
Removes all currently stored user-defined attributes
|
<T> T |
computeAttributeIfAbsent(AttributeRepository.AttributeKey<T> key,
java.util.function.Function<? super AttributeRepository.AttributeKey<T>,? extends T> resolver)
If the specified key is not already associated with a value (or is mapped to
null ), attempts to compute
its value using the given mapping function and enters it into this map unless null . |
protected void |
configureWindow() |
protected abstract void |
doWriteData(byte[] data,
int off,
long len) |
protected abstract void |
doWriteExtendedData(byte[] data,
int off,
long len) |
<T> T |
getAttribute(AttributeRepository.AttributeKey<T> key)
Returns the value of the user-defined attribute.
|
int |
getAttributesCount() |
ChannelListener |
getChannelListenerProxy() |
ChannelStreamWriterResolver |
getChannelStreamWriterResolver() |
CloseableExecutorService |
getExecutorService() |
int |
getId() |
protected Closeable |
getInnerCloseable() |
Window |
getLocalWindow() |
PropertyResolver |
getParentPropertyResolver() |
java.util.Map<java.lang.String,java.lang.Object> |
getProperties()
A map of properties that can be used to configure the SSH server or client.
|
int |
getRecipient() |
Window |
getRemoteWindow() |
java.util.List<RequestHandler<Channel>> |
getRequestHandlers() |
Session |
getSession() |
protected void |
handleChannelRequest(java.lang.String req,
boolean wantReply,
Buffer buffer) |
void |
handleClose()
Invoked when
SSH_MSG_CHANNEL_CLOSE received |
void |
handleData(Buffer buffer)
Invoked when
SSH_MSG_CHANNEL_DATA received |
void |
handleEof()
Invoked when
SSH_MSG_CHANNEL_EOF received |
void |
handleExtendedData(Buffer buffer)
Invoked when
SSH_MSG_CHANNEL_EXTENDED_DATA received |
void |
handleFailure()
Invoked when
SSH_MSG_CHANNEL_FAILURE received |
protected RequestHandler.Result |
handleInternalRequest(java.lang.String req,
boolean wantReply,
Buffer buffer)
Called by
handleUnknownChannelRequest(String, boolean, Buffer) in order to allow channel request
handling if none of the registered handlers processed the request - last chance. |
void |
handleRequest(Buffer buffer)
Invoked when
SSH_MSG_CHANNEL_REQUEST received |
void |
handleSuccess()
Invoked when
SSH_MSG_CHANNEL_SUCCESS received |
protected void |
handleUnknownChannelRequest(java.lang.String req,
boolean wantReply,
Buffer buffer)
Called when none of the register request handlers reported handling the request
|
void |
handleWindowAdjust(Buffer buffer)
Invoked when
SSH_MSG_CHANNEL_WINDOW_ADJUST received |
void |
init(ConnectionService service,
Session session,
int id)
Invoked when the local channel is initial created
|
protected void |
invokeChannelSignaller(Invoker<ChannelListener,java.lang.Void> invoker) |
boolean |
isEofSent() |
boolean |
isEofSignalled() |
boolean |
isInitialized() |
protected void |
notifyStateChanged(ChannelListener listener,
java.lang.String hint) |
protected void |
notifyStateChanged(java.lang.String hint) |
protected void |
preClose()
preClose is guaranteed to be called before doCloseGracefully or doCloseImmediately.
|
<T> T |
removeAttribute(AttributeRepository.AttributeKey<T> key)
Removes the user-defined attribute
|
void |
removeChannelListener(ChannelListener listener)
Remove a channel listener
|
protected java.util.Date |
removePendingRequest(java.lang.String request)
Removes a channel request from the tracked ones
|
void |
removeRequestHandler(RequestHandler<Channel> handler) |
ChannelStreamWriterResolver |
resolveChannelStreamWriterResolver() |
protected IoWriteFuture |
sendEof()
Sends
SSH_MSG_CHANNEL_EOF provided not already sent and current channel state allows it. |
protected IoWriteFuture |
sendResponse(Buffer buffer,
java.lang.String req,
RequestHandler.Result result,
boolean wantReply) |
protected void |
sendWindowAdjust(long len) |
<T> T |
setAttribute(AttributeRepository.AttributeKey<T> key,
T value)
Sets a user-defined attribute.
|
void |
setChannelStreamWriterResolver(ChannelStreamWriterResolver resolver) |
protected void |
setRecipient(int recipient) |
protected void |
signalChannelClosed(ChannelListener listener,
java.lang.Throwable reason) |
void |
signalChannelClosed(java.lang.Throwable reason) |
protected void |
signalChannelInitialized() |
protected void |
signalChannelInitialized(ChannelListener listener) |
protected void |
signalChannelOpenFailure(ChannelListener listener,
java.lang.Throwable reason) |
protected void |
signalChannelOpenFailure(java.lang.Throwable reason) |
protected void |
signalChannelOpenSuccess() |
protected void |
signalChannelOpenSuccess(ChannelListener listener) |
java.lang.String |
toString() |
protected long |
validateIncomingDataSize(int cmd,
long len) |
IoWriteFuture |
writePacket(Buffer buffer)
Encode and send the given buffer.
|
doCloseGracefully, doCloseImmediately
addCloseFutureListener, builder, close, getFutureLock, isClosed, isClosing, removeCloseFutureListener
debug, debug, debug, debug, debug, error, error, error, error, error, getSimplifiedLogger, info, info, warn, warn, warn, warn, warn, warn, warn, warn
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
addRequestHandlers, handleOpenFailure, handleOpenSuccess, open, removeRequestHandlers, resolveAttribute, resolveAttribute
getSessionContext
getBoolean, getBooleanProperty, getCharset, getInteger, getIntProperty, getLong, getLongProperty, getObject, getString, getStringProperty
ofAttributesMap, ofKeyValuePair
resolveChannelStreamWriter
addCloseFutureListener, close, close, close, getMaxCloseWaitTime, isClosed, isClosing, isOpen, removeCloseFutureListener
public static final java.util.function.IntUnaryOperator RESPONSE_BUFFER_GROWTH_FACTOR
protected ConnectionService service
protected final java.util.concurrent.atomic.AtomicBoolean initialized
protected final java.util.concurrent.atomic.AtomicBoolean eofReceived
protected final java.util.concurrent.atomic.AtomicBoolean eofSent
protected java.util.concurrent.atomic.AtomicReference<AbstractChannel.GracefulState> gracefulState
protected final DefaultCloseFuture gracefulFuture
protected final java.util.Collection<ChannelListener> channelListeners
protected final ChannelListener channelListenerProxy
private int id
private int recipient
private Session sessionInstance
private CloseableExecutorService executor
private final java.util.List<RequestHandler<Channel>> requestHandlers
private final Window localWindow
private final Window remoteWindow
private ChannelStreamWriterResolver channelStreamPacketWriterResolver
private final java.util.Map<java.lang.String,java.util.Date> pendingRequests
Map
of sent requests - key = request name, value = timestamp when request was sent.private final java.util.Map<java.lang.String,java.lang.Object> properties
private final java.util.Map<AttributeRepository.AttributeKey<?>,java.lang.Object> attributes
protected AbstractChannel(boolean client)
protected AbstractChannel(boolean client, java.util.Collection<? extends RequestHandler<Channel>> handlers)
protected AbstractChannel(java.lang.String discriminator, boolean client)
protected AbstractChannel(java.lang.String discriminator, boolean client, java.util.Collection<? extends RequestHandler<Channel>> handlers, CloseableExecutorService executorService)
public java.util.List<RequestHandler<Channel>> getRequestHandlers()
public void addRequestHandler(RequestHandler<Channel> handler)
public void removeRequestHandler(RequestHandler<Channel> handler)
public int getId()
public int getRecipient()
protected void setRecipient(int recipient)
public Window getLocalWindow()
public Window getRemoteWindow()
public Session getSession()
getSession
in interface SessionHolder<Session>
public PropertyResolver getParentPropertyResolver()
getParentPropertyResolver
in interface PropertyResolver
null
if no parentpublic CloseableExecutorService getExecutorService()
getExecutorService
in interface ExecutorServiceCarrier
CloseableExecutorService
to usepublic ChannelStreamWriterResolver getChannelStreamWriterResolver()
getChannelStreamWriterResolver
in interface ChannelStreamWriterResolverManager
public void setChannelStreamWriterResolver(ChannelStreamWriterResolver resolver)
setChannelStreamWriterResolver
in interface ChannelStreamWriterResolverManager
public ChannelStreamWriterResolver resolveChannelStreamWriterResolver()
resolveChannelStreamWriterResolver
in interface ChannelStreamWriterResolverManager
protected java.util.Date addPendingRequest(java.lang.String request, boolean wantReply)
request
- The request typewantReply
- true
if reply is expectedDate
timestamp - null
if no reply is expected (in
which case the request is not tracked)java.lang.IllegalArgumentException
- If the request is already being trackedremovePendingRequest(String)
protected java.util.Date removePendingRequest(java.lang.String request)
request
- The request typeDate
timestamp - null
if the specified request type is not being
tracked or has not been added to the tracked ones to begin withaddPendingRequest(String, boolean)
public void handleRequest(Buffer buffer) throws java.io.IOException
Channel
SSH_MSG_CHANNEL_REQUEST
receivedbuffer
- The rest of the message data Buffer
after decoding the channel identifiersjava.io.IOException
- If failed to handle the messageprotected void handleChannelRequest(java.lang.String req, boolean wantReply, Buffer buffer) throws java.io.IOException
java.io.IOException
protected void handleUnknownChannelRequest(java.lang.String req, boolean wantReply, Buffer buffer) throws java.io.IOException
req
- The request typewantReply
- Whether reply is requestedbuffer
- The Buffer
containing extra request-specific datajava.io.IOException
- If failed to send the response (if needed)handleInternalRequest(String, boolean, Buffer)
protected RequestHandler.Result handleInternalRequest(java.lang.String req, boolean wantReply, Buffer buffer) throws java.io.IOException
handleUnknownChannelRequest(String, boolean, Buffer)
in order to allow channel request
handling if none of the registered handlers processed the request - last chance.req
- The request typewantReply
- Whether reply is requestedbuffer
- The Buffer
containing extra request-specific datanull
or Unsupported
and reply is required then a
failure message will be sentjava.io.IOException
- If failed to process the request internallyprotected IoWriteFuture sendResponse(Buffer buffer, java.lang.String req, RequestHandler.Result result, boolean wantReply) throws java.io.IOException
java.io.IOException
public void init(ConnectionService service, Session session, int id) throws java.io.IOException
Channel
service
- The ConnectionService
through which the channel is initializedsession
- The Session
associated with the channelid
- The locally assigned channel identifierjava.io.IOException
- If failed to process the initializationprotected void signalChannelInitialized() throws java.io.IOException
java.io.IOException
protected void signalChannelInitialized(ChannelListener listener)
protected void signalChannelOpenSuccess()
protected void signalChannelOpenSuccess(ChannelListener listener)
public boolean isInitialized()
true
if call to Channel.init(ConnectionService, Session, int)
was successfully completedprotected void signalChannelOpenFailure(java.lang.Throwable reason)
protected void signalChannelOpenFailure(ChannelListener listener, java.lang.Throwable reason)
protected void notifyStateChanged(java.lang.String hint)
protected void notifyStateChanged(ChannelListener listener, java.lang.String hint)
public void addChannelListener(ChannelListener listener)
ChannelListenerManager
addChannelListener
in interface ChannelListenerManager
listener
- The ChannelListener
to add - not null
public void removeChannelListener(ChannelListener listener)
ChannelListenerManager
removeChannelListener
in interface ChannelListenerManager
listener
- The ChannelListener
to removepublic ChannelListener getChannelListenerProxy()
getChannelListenerProxy
in interface ChannelListenerManager
null
proxy ChannelListener
that represents all the currently registered
listeners. Any method invocation on the proxy is replicated to the currently registered listenerspublic void handleClose() throws java.io.IOException
Channel
SSH_MSG_CHANNEL_CLOSE
receivedjava.io.IOException
- If failed to handle the messageprotected Closeable getInnerCloseable()
getInnerCloseable
in class AbstractInnerCloseable
protected void preClose()
AbstractCloseable
preClose
in class AbstractCloseable
public void signalChannelClosed(java.lang.Throwable reason)
protected void signalChannelClosed(ChannelListener listener, java.lang.Throwable reason)
protected void invokeChannelSignaller(Invoker<ChannelListener,java.lang.Void> invoker) throws java.lang.Throwable
java.lang.Throwable
public IoWriteFuture writePacket(Buffer buffer) throws java.io.IOException
Channel
buffer
- the buffer to encode and send. NOTE: the buffer must not be touched until the returned
write future is completed.IoWriteFuture
that can be used to check when the packet has actually been sentjava.io.IOException
- if an error occurred when encoding or sending the packetpublic void handleData(Buffer buffer) throws java.io.IOException
Channel
SSH_MSG_CHANNEL_DATA
receivedbuffer
- The rest of the message data Buffer
after decoding the channel identifiersjava.io.IOException
- If failed to handle the messagepublic void handleExtendedData(Buffer buffer) throws java.io.IOException
Channel
SSH_MSG_CHANNEL_EXTENDED_DATA
receivedbuffer
- The rest of the message data Buffer
after decoding the channel identifiersjava.io.IOException
- If failed to handle the messageprotected long validateIncomingDataSize(int cmd, long len)
public void handleEof() throws java.io.IOException
Channel
SSH_MSG_CHANNEL_EOF
receivedjava.io.IOException
- If failed to handle the messagepublic boolean isEofSignalled()
true
if the peer signaled that it will not send any more datapublic void handleWindowAdjust(Buffer buffer) throws java.io.IOException
Channel
SSH_MSG_CHANNEL_WINDOW_ADJUST
receivedbuffer
- The rest of the message data Buffer
after decoding the channel identifiersjava.io.IOException
- If failed to handle the messagepublic void handleSuccess() throws java.io.IOException
Channel
SSH_MSG_CHANNEL_SUCCESS
receivedjava.io.IOException
- If failed to handle the messagepublic void handleFailure() throws java.io.IOException
Channel
SSH_MSG_CHANNEL_FAILURE
receivedjava.io.IOException
- If failed to handle the messageprotected abstract void doWriteData(byte[] data, int off, long len) throws java.io.IOException
java.io.IOException
protected abstract void doWriteExtendedData(byte[] data, int off, long len) throws java.io.IOException
java.io.IOException
protected IoWriteFuture sendEof() throws java.io.IOException
SSH_MSG_CHANNEL_EOF
provided not already sent and current channel state allows it.IoWriteFuture
of the sent packet - null
if message not sent due to
channel state (or already sent)java.io.IOException
- If failed to send the packetpublic boolean isEofSent()
public java.util.Map<java.lang.String,java.lang.Object> getProperties()
PropertyResolver
A map of properties that can be used to configure the SSH server or client. This map will never be changed by either the server or client and is not supposed to be changed at runtime (changes are not bound to have any effect on a running client or server), though it may affect the creation of sessions later as these values are usually not cached.
Note: the type of the mapped property should match the expected configuration value type -
Long, Integer, Boolean,
String
, etc.... If it doesn't, the toString()
result of the mapped value is used to convert it to the
required type. E.g., if the mapped value is the string "1234" and the expected value is a
long
then it will be parsed into one. Also, if the mapped value is an Integer
but a long
is expected, then it will be converted into one.
getProperties
in interface PropertyResolver
Map
containing configuration values, never null
. Note: may be
immutable.public int getAttributesCount()
getAttributesCount
in interface AttributeRepository
public <T> T getAttribute(AttributeRepository.AttributeKey<T> key)
AttributeRepository
getAttribute
in interface AttributeRepository
T
- The generic attribute typekey
- The key of the attribute; must not be null
.null
if there is no value associated with the specified keypublic java.util.Collection<AttributeRepository.AttributeKey<?>> attributeKeys()
attributeKeys
in interface AttributeRepository
Collection
snapshot of all the currently registered attributes in the repositorypublic <T> T computeAttributeIfAbsent(AttributeRepository.AttributeKey<T> key, java.util.function.Function<? super AttributeRepository.AttributeKey<T>,? extends T> resolver)
AttributeStore
null
), attempts to compute
its value using the given mapping function and enters it into this map unless null
.computeAttributeIfAbsent
in interface AttributeStore
T
- The generic attribute typekey
- The key of the attribute; must not be null
.resolver
- The (never null
) mapping function to use if value not already mapped. If returns
null
then value is not mapped to the provided key.null
if value not mapped and resolver did not return a
non-null
value for itpublic <T> T setAttribute(AttributeRepository.AttributeKey<T> key, T value)
AttributeStore
setAttribute
in interface AttributeStore
T
- The generic attribute typekey
- The key of the attribute; must not be null
.value
- The value of the attribute; must not be null
.null
if it is new.public <T> T removeAttribute(AttributeRepository.AttributeKey<T> key)
AttributeStore
removeAttribute
in interface AttributeStore
T
- The generic attribute typekey
- The key of the attribute; must not be null
.null
if no previous valuepublic void clearAttributes()
AttributeStore
clearAttributes
in interface AttributeStore
protected void configureWindow()
protected void sendWindowAdjust(long len) throws java.io.IOException
java.io.IOException
public java.lang.String toString()
toString
in class java.lang.Object