@Override
  protected void initChannel(SocketChannel ch) throws Exception {
    // If channel handler implementations are not annotated with @Sharable, Netty creates a new instance of every class
    // in the pipeline for every connection.
    // i.e. if there are a 1000 active connections there will be a 1000 NettyMessageProcessor instances.
    ChannelPipeline pipeline = ch.pipeline();
    // connection stats handler to track connection related metrics
    pipeline.addLast("connectionStatsHandler", connectionStatsHandler);
    // if SSL is enabled, add an SslHandler before the HTTP codec
    if (sslFactory != null) {
      InetSocketAddress peerAddress = ch.remoteAddress();
      String peerHost = peerAddress.getHostName();
      int peerPort = peerAddress.getPort();
      SslHandler sslHandler = new SslHandler(sslFactory.createSSLEngine(peerHost, peerPort, SSLFactory.Mode.SERVER));
      pipeline.addLast("sslHandler", sslHandler);
    }
    pipeline
        // for http encoding/decoding.
        .addLast("codec",
            new HttpServerCodec(nettyConfig.nettyServerMaxInitialLineLength, nettyConfig.nettyServerMaxHeaderSize,
                nettyConfig.nettyServerMaxChunkSize))
        // for health check request handling
        .addLast("healthCheckHandler", new HealthCheckHandler(restServerState, nettyMetrics))
        // for public access logging
        .addLast("publicAccessLogHandler", new PublicAccessLogHandler(publicAccessLogger, nettyMetrics))
        // for detecting connections that have been idle too long - probably because of an error.
        .addLast("idleStateHandler", new IdleStateHandler(0, 0, nettyConfig.nettyServerIdleTimeSeconds))
        // for safe writing of chunks for responses
        .addLast("chunker", new ChunkedWriteHandler());
    if (addedChannelHandlers != null) {
      pipeline.addLast(addedChannelHandlers.toArray(new ChannelHandler[0]));
    }
    // custom processing class that interfaces with a RestRequestService.
    pipeline.addLast("processor",
        new NettyMessageProcessor(nettyMetrics, nettyConfig, performanceConfig, requestHandler));
  }
Construct a {@link FrontendNettyChannelInitializer}.
@param nettyConfig the config to use when instantiating certain handlers on this pipeline.
@param performanceConfig the config to use when evaluating ambry service level objectives that include latency.
@param nettyMetrics the {@link NettyMetrics} object to use.
@param connectionStatsHandler the {@link ConnectionStatsHandler} to use.
@param requestHandler the {@link RestRequestHandler} to handle requests on this pipeline.
@param publicAccessLogger the {@link PublicAccessLogger} to use.
@param restServerState the {@link RestServerState} object to use.
@param sslFactory the {@link SSLFactory} to use for generating {@link javax.net.ssl.SSLEngine} instances,
                  or {@code null} if SSL is not enabled in this pipeline.
@param addedChannelHandlers a list of {@link ChannelHandler} to add to the {@link io.netty.channel.ChannelInitializer} before
                            the final handler.
ambry-rest/src/main/java/com/github/ambry/rest/FrontendNettyChannelInitializer.java