Class NettyConnection

    • Field Detail

      • LOGGER

        private static final Logger LOGGER
        Logger for this class.
      • 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.
      • 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.
      • 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 Detail

      • NettyConnection

        public 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 Detail

      • 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
      • 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
      • 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

        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 NettyConnection.BindOperationHandle operation​(BindRequest request)
        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
      • 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
      • 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