private void validateSslConnection(ChannelHandlerContext ctx) throws Exception {
    SslHandler sslHandler = ctx.pipeline().get(SslHandler.class);
    if (sslHandler != null) {
      sslHandler.handshakeFuture().addListener(future -> {
        if (!future.isSuccess()) {
          logger.error("SSL handshake failed for channel: {}", ctx.channel(), future.cause());
        } else {
          logger.debug("SSL handshake succedded for channel: {}", ctx.channel(), future.cause());
          long startTimeMs = System.currentTimeMillis();
          try {
            SSLSession sslSession = sslHandler.engine().getSession();
            serverSecurityService.validateConnection(sslSession, (r, e) -> {
              if (e != null) {
                logger.error("security validation failed for channel: {}", ctx.channel(), e);
                serverMetrics.serverValidateConnectionFailure.inc();
                ctx.channel().close();
              } else {
                logger.debug("security validation succeeded for channel: {}", ctx.channel());
                serverMetrics.serverValidateConnectionSuccess.inc();
              }
            });
          } catch (Exception e) {
            logger.error("security validation failed for channel: {}", ctx.channel(), e);
            serverMetrics.serverValidateConnectionFailure.inc();
            ctx.channel().close();
          } finally {
            serverMetrics.securityServiceValidateConnectionTimeInMs.update(System.currentTimeMillis() - startTimeMs);
          }
        }
      });
    }
  }
Listen to the handshake future for the SSL termination, then apply the security policies, potentialy closing the
connection in case security check fails.
@param ctx the {@link ChannelHandlerContext}.
ambry-rest/src/main/java/com/github/ambry/rest/ServerSecurityHandler.java