Class NettyConnection

java.lang.Object
org.ldaptive.transport.TransportConnection
org.ldaptive.transport.netty.NettyConnection
All Implemented Interfaces:
AutoCloseable, Connection

final class NettyConnection extends TransportConnection
Netty based connection implementation.
  • Field Details

    • LOGGER

      private static final Logger LOGGER
      Logger for this class.
    • REQUEST_ENCODER

      private static final NettyConnection.RequestEncoder REQUEST_ENCODER
      Request encoder pipeline handler.
    • READ_NEXT_MESSAGE

      private static final NettyConnection.AutoReadEventHandler READ_NEXT_MESSAGE
      Inbound handler to read the next message if autoRead is false.
    • channelType

      private final Class<? extends io.netty.channel.Channel> channelType
      Type of channel.
    • ioWorkerGroup

      private final io.netty.channel.EventLoopGroup ioWorkerGroup
      Event worker group used to process I/O.
    • messageWorkerGroup

      private final io.netty.channel.EventLoopGroup messageWorkerGroup
      Event worker group used to process inbound messages.
    • shutdownOnClose

      private final boolean shutdownOnClose
      Whether to shutdown the event loop groups on Connection.close().
    • channelOptions

      private final Map<io.netty.channel.ChannelOption,Object> channelOptions
      Netty channel configuration options.
    • pendingResponses

      private final HandleMap pendingResponses
      Queue holding requests that haven't received a response.
    • closeListener

      private final NettyConnection.CloseFutureListener closeListener
      Listener notified when the connection is closed.
    • messageID

      private final AtomicInteger messageID
      Message ID counter, incremented as requests are sent.
    • reconnectLock

      private final ReentrantReadWriteLock reconnectLock
      Block operations while a reconnect is occurring.
    • bindLock

      private final ReentrantReadWriteLock bindLock
      Operation lock when a bind occurs.
    • connectionExecutor

      private ExecutorService connectionExecutor
      Executor for scheduling various connection related tasks that cannot or should not be handled by the netty event loop groups. Reconnects in particular require a dedicated thread as the event loop group may be shared or may not be configured with enough threads to handle the task.
    • ldapURL

      private LdapURL ldapURL
      URL derived from the connection strategy.
    • channel

      private io.netty.channel.Channel channel
      Connection to the LDAP server.
    • connectTime

      private Instant connectTime
      Time this connection was successfully established, null if the connection is not open.
    • inboundException

      private Throwable inboundException
      Last exception received on the inbound pipeline.
  • Constructor Details

    • NettyConnection

      NettyConnection(ConnectionConfig config, Class<? extends io.netty.channel.Channel> type, io.netty.channel.EventLoopGroup ioGroup, io.netty.channel.EventLoopGroup messageGroup, boolean shutdownGroups)
      Creates a new connection. Netty supports various transport implementations including NIO, EPOLL, KQueue, etc. The class type and event loop group are tightly coupled in this regard.
      Parameters:
      config - connection configuration
      type - type of channel
      ioGroup - event loop group that handles I/O and supports the channel type, cannot be null
      messageGroup - event loop group that handles inbound messages, can be null
      shutdownGroups - whether to shutdown the event loop groups when the connection is closed
  • Method Details

    • convertChannelOption

      private Object convertChannelOption(String value)
      Performs a best effort at converting a channel option value to the correct type. Handles Boolean and Integer types.
      Parameters:
      value - to convert
      Returns:
      converted value or the supplied value if no conversion occurred
    • createBootstrap

      private io.netty.bootstrap.Bootstrap createBootstrap(NettyConnection.ClientInitializer initializer)
      Creates a Netty Bootstrap with the supplied client initializer.
      Parameters:
      initializer - to provide to the bootstrap
      Returns:
      Netty bootstrap
    • test

      protected boolean test(LdapURL url)
      Description copied from class: TransportConnection
      Determine whether the supplied URL is acceptable for use.
      Specified by:
      test in class TransportConnection
      Parameters:
      url - LDAP URL to test
      Returns:
      whether URL can be become active
    • open

      protected void open(LdapURL url) throws LdapException
      Description copied from class: TransportConnection
      Attempt to open a connection to the supplied LDAP URL.
      Specified by:
      open in class TransportConnection
      Parameters:
      url - LDAP URL to connect to
      Throws:
      LdapException - if opening the connection fails
    • openInitialize

      private void openInitialize(LdapURL url) throws LdapException
      Initializes this connection for use after it has been established. If startTLS is configured it will be performed. Any configured connection initializers are invoked.
      Parameters:
      url - LDAP URL to connect to
      Throws:
      LdapException - if initializing the connection fails
    • getLdapURL

      public LdapURL getLdapURL()
      Description copied from interface: Connection
      Returns the URL that was selected for this connection. The existence of this value does not indicate a current established connection.
      Returns:
      LDAP URL
    • connectInternal

      private io.netty.channel.Channel connectInternal() throws ConnectException
      Creates a Netty bootstrap and connects to the LDAP server. Handles the details of adding an SSL handler to the pipeline. This method waits until the connection is established.
      Returns:
      channel for the established connection.
      Throws:
      ConnectException - if the connection fails
    • createClientInitializer

      private NettyConnection.ClientInitializer createClientInitializer() throws ConnectException
      Creates a new client initializer. If the ldapURL is LDAPS an SSL handler is added to the client initializer.
      Returns:
      client initializer
      Throws:
      ConnectException - if the SSL engine cannot be initialized
    • createSslHandler

      private io.netty.handler.ssl.SslHandler createSslHandler(ConnectionConfig config) throws SSLException
      Creates a Netty SSL handler using the supplied connection config.
      Parameters:
      config - containing SSL config
      Returns:
      SSL handler
      Throws:
      SSLException - if the SSL engine cannot be initialized
    • connectBootstrap

      private io.netty.channel.ChannelFuture connectBootstrap(NettyConnection.ClientInitializer initializer)
      Creates a new bootstrap with the supplied initializer and uses that bootstrap to connect to the ldapURL.
      Parameters:
      initializer - to create bootstrap with
      Returns:
      channel future produced from the connect invocation
    • waitForConnectionEstablish

      private void waitForConnectionEstablish(NettyConnection.ClientInitializer initializer, io.netty.channel.ChannelFuture future) throws ConnectException
      Waits until the TCP connection has completed.
      Parameters:
      initializer - used to determine whether to wait for the SSL handshake to complete
      future - to wait on
      Throws:
      ConnectException - if the connection fails
    • waitForSSLHandshake

      private void waitForSSLHandshake(io.netty.channel.Channel ch) throws SSLException
      Waits until the SSL handshake has completed.
      Parameters:
      ch - that the handshake is occurring on
      Throws:
      SSLException - if the handshake fails
    • operation

      Result operation(StartTLSRequest request) throws LdapException
      Performs a startTLS operation. This method can only be invoked when a connection is opened.
      Parameters:
      request - to send
      Returns:
      result of the startTLS operation
      Throws:
      LdapException - if the operation fails
    • operation

      protected void operation(UnbindRequest request)
      Description copied from class: TransportConnection
      Executes an unbind operation. Clients should close connections using Connection.close().
      Specified by:
      operation in class TransportConnection
      Parameters:
      request - unbind request
    • operation

      public BindResponse operation(SaslClientRequest request) throws LdapException
      Performs a SASL bind operation that uses a custom client.
      Parameters:
      request - to send
      Returns:
      result of the GSS-API bind operation
      Throws:
      LdapException - if the operation fails or another bind is in progress
    • operation

      public BindResponse operation(DefaultSaslClientRequest request) throws LdapException
      Performs a SASL client bind operation.
      Parameters:
      request - to send
      Returns:
      result of the SASL client bind operation
      Throws:
      LdapException - if the operation fails or another bind is in progress
    • operation

      public void operation(AbandonRequest request)
      Description copied from interface: Connection
      Executes an abandon operation. Clients should execute abandons using OperationHandle.abandon().
      Parameters:
      request - abandon request
    • operation

      Description copied from interface: Connection
      Creates a handle for an add operation.
      Parameters:
      request - add request
      Returns:
      operation handle
    • operation

      Description copied from interface: Connection
      Creates a handle for a bind operation. Since clients must not send requests while a bind is in progress, some methods may not be supported on the operation handle.
      Parameters:
      request - bind request
      Returns:
      operation handle
    • operation

      public DefaultCompareOperationHandle operation(CompareRequest request)
      Description copied from interface: Connection
      Creates a handle for a compare operation.
      Parameters:
      request - compare request
      Returns:
      compare operation handle
    • operation

      Description copied from interface: Connection
      Creates a handle for a delete operation.
      Parameters:
      request - delete request
      Returns:
      operation handle
    • operation

      public DefaultExtendedOperationHandle operation(ExtendedRequest request)
      Description copied from interface: Connection
      Creates a handle for an extended operation.
      Parameters:
      request - extended request
      Returns:
      extended operation handle
    • operation

      Description copied from interface: Connection
      Creates a handle for a modify operation.
      Parameters:
      request - modify request
      Returns:
      operation handle
    • operation

      Description copied from interface: Connection
      Creates a handle for a modify dn operation.
      Parameters:
      request - modify dn request
      Returns:
      operation handle
    • operation

      public DefaultSearchOperationHandle operation(SearchRequest request)
      Description copied from interface: Connection
      Creates a handle for a search operation.
      Parameters:
      request - search request
      Returns:
      search operation handle
    • write

      protected void write(DefaultOperationHandle<?,?> handle)
      Description copied from class: TransportConnection
      Write the request in the supplied handle to the LDAP server. This method does not throw, it should report exceptions to the handle.
      Specified by:
      write in class TransportConnection
      Parameters:
      handle - for the operation write
    • complete

      protected void complete(DefaultOperationHandle<?,?> handle)
      Description copied from class: TransportConnection
      Report that the supplied handle has completed. Allows the connection to clean up any resources associated with the handle.
      Specified by:
      complete in class TransportConnection
      Parameters:
      handle - that has completed
    • getAndIncrementMessageID

      int getAndIncrementMessageID()
      Returns the value of the next message ID and increments the counter.
      Returns:
      message ID
    • getMessageID

      int getMessageID()
      Returns the value of the next message ID.
      Returns:
      message ID
    • setMessageID

      void setMessageID(int i)
      Sets the value of the next message ID.
      Parameters:
      i - message ID
    • getChannelOptions

      Map<io.netty.channel.ChannelOption,Object> getChannelOptions()
      Returns the channel options.
      Returns:
      channel options
    • getIoWorkerGroup

      io.netty.channel.EventLoopGroup getIoWorkerGroup()
      Returns the I/O worker group.
      Returns:
      I/O worker group
    • getMessageWorkerGroup

      io.netty.channel.EventLoopGroup getMessageWorkerGroup()
      Returns the message worker group.
      Returns:
      message worker group
    • close

      public void close(RequestControl... controls)
      Closes this connection. Abandons all pending responses and sends an unbind to the LDAP server if the connection is open when this method is invoked.
      Parameters:
      controls - to send with the unbind request when closing the connection
    • notifyOperationHandlesOfClose

      private void notifyOperationHandlesOfClose()
      Sends an exception notification to all pending responses that the connection has been closed. Since this invokes any configured exception handlers, notifications will use the messageWorkerGroup if it is configured.
    • reconnect

      private void reconnect()
      Attempts to reestablish the channel for this connection.
      Throws:
      IllegalStateException - if the connection is open
    • isOpen

      public boolean isOpen()
      Returns whether the underlying Netty channel is open. See Channel.isOpen().
      Returns:
      whether the Netty channel is open
    • isOpening

      private boolean isOpening()
      Returns whether this connection is currently attempting to open.
      Returns:
      whether the Netty channel is in the process of opening
    • isClosing

      private boolean isClosing()
      Returns whether this connection is currently attempting to close.
      Returns:
      whether the Netty channel is in the process of closing
    • throwIfClosed

      private void throwIfClosed() throws LdapException
      Throws an exception if the Netty channel is closed. See isOpen().
      Throws:
      LdapException - if the connection is closed
    • toString

      public String toString()
      Overrides:
      toString in class Object