/**
   * Detects if we're connecting to a Found Elasticsearch cluster (using pre-configured host
   * suffixes) and adds a SSL handler at the beginning of the pipeline if we're connecting to a
   * SSL-endpoint (using a list of pre-configured ports).
   */
  @Override
  public void connectRequested(final ChannelHandlerContext ctx, final ChannelStateEvent e)
      throws Exception {
    if (e.getValue() instanceof InetSocketAddress) {
      InetSocketAddress inetSocketAddress = (InetSocketAddress) e.getValue();

      for (String suffix : hostSuffixes) {
        isFoundCluster = isFoundCluster || inetSocketAddress.getHostString().endsWith(suffix);
      }

      if (isFoundCluster) {
        for (int sslPort : sslPorts) {
          if (inetSocketAddress.getPort() == sslPort) {
            logger.debug(
                "Enabling SSL on transport layer with unsafeAllowSelfSigned=[{}].",
                unsafeAllowSelfSigned);
            FoundSSLHandler handler =
                FoundSSLUtils.getSSLHandler(unsafeAllowSelfSigned, inetSocketAddress);
            ctx.getPipeline().addFirst("ssl", handler);
            break;
          }
        }
      } else {
        ctx.getPipeline().remove(this);
      }
    }
    super.connectRequested(ctx, e);
  }
  /**
   * {@inheritDoc} Down-casts the received downstream event into more meaningful sub-type event and
   * calls an appropriate handler method with the down-casted event.
   */
  public void handleDownstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {

    if (e instanceof MessageEvent) {
      writeRequested(ctx, (MessageEvent) e);
    } else if (e instanceof ChannelStateEvent) {
      ChannelStateEvent evt = (ChannelStateEvent) e;
      switch (evt.getState()) {
        case OPEN:
          if (!Boolean.TRUE.equals(evt.getValue())) {
            closeRequested(ctx, evt);
          }
          break;
        case BOUND:
          if (evt.getValue() != null) {
            bindRequested(ctx, evt);
          } else {
            unbindRequested(ctx, evt);
          }
          break;
        case CONNECTED:
          if (evt.getValue() != null) {
            connectRequested(ctx, evt);
          } else {
            disconnectRequested(ctx, evt);
          }
          break;
        case INTEREST_OPS:
          setInterestOpsRequested(ctx, evt);
          break;
        default:
          ctx.sendDownstream(e);
      }
    } else {
      ctx.sendDownstream(e);
    }
  }