@Override
  public void handlerAdded(ChannelHandlerContext ctx) {
    // dispose the saslRpcClient when the channel is closed, since saslRpcClient is final, it is
    // safe to reference it in lambda expr.
    NettyFutureUtils.addListener(ctx.channel().closeFuture(), f -> saslRpcClient.dispose());
    try {
      byte[] initialResponse = ugi.doAs(new PrivilegedExceptionAction<byte[]>() {

        @Override
        public byte[] run() throws Exception {
          return saslRpcClient.getInitialResponse();
        }
      });
      assert initialResponse != null;
      writeResponse(ctx, initialResponse);
      // HBASE-23881 We do not want to check if the SaslClient thinks the handshake is
      // complete as, at this point, we've not heard a back from the server with it's reply
      // to our first challenge response. We should wait for at least one reply
      // from the server before calling negotiation complete.
      //
      // Each SASL mechanism has its own handshake. Some mechanisms calculate a single client buffer
      // to be sent to the server while others have multiple exchanges to negotiate authentication.
      // GSSAPI(Kerberos) and DIGEST-MD5 both are examples of mechanisms which have multiple steps.
      // Mechanisms which have multiple steps will not return true on `SaslClient#isComplete()`
      // until the handshake has fully completed. Mechanisms which only send a single buffer may
      // return true on `isComplete()` after that initial response is calculated.

      // HBASE-28337 We still want to check if the SaslClient completed the handshake, because
      // there are certain mechs like PLAIN which doesn't have a server response after the
      // initial authentication request. We cannot remove this tryComplete(), otherwise mechs
      // like PLAIN will fail with call timeout.
      tryComplete(ctx);
    } catch (Exception e) {
      // the exception thrown by handlerAdded will not be passed to the exceptionCaught below
      // because netty will remove a handler if handlerAdded throws an exception.
      exceptionCaught(ctx, e);
    }
  }
@param saslPromise {@code true} if success, {@code false} if server tells us to fallback to
                   simple.
hbase-client/src/main/java/org/apache/hadoop/hbase/security/NettyHBaseSaslRpcClientHandler.java