private void closeClient() {
      if (transport != null) {
        try {
          transport.flush();
        } catch (TTransportException e) {
        } finally {
          try {
            transport.close();
          } catch (Exception e) {
          } finally {
            transport = null;
          }
        }
      }

      if (socket != null) {
        try {
          socket.close();
        } catch (Exception e) {
        } finally {
          socket = null;
        }
      }
    }
    @Override
    public void open() throws ConnectionException {
      if (cassandraClient != null) {
        throw new IllegalStateException("Open called on already open connection");
      }

      long startTime = System.currentTimeMillis();
      try {
        final SSLConnectionContext sslCxt = cpConfig.getSSLConnectionContext();
        if (sslCxt != null) {
          TSSLTransportParameters params =
              new TSSLTransportParameters(
                  sslCxt.getSslProtocol(), sslCxt.getSslCipherSuites().toArray(new String[0]));
          params.setTrustStore(sslCxt.getSslTruststore(), sslCxt.getSslTruststorePassword());
          // thrift's SSL implementation does not allow you set the socket connect timeout, only
          // read timeout
          socket =
              TSSLTransportFactory.getClientSocket(
                  getHost().getIpAddress(),
                  getHost().getPort(),
                  cpConfig.getSocketTimeout(),
                  params);
        } else {
          socket =
              new TSocket(
                  getHost().getIpAddress(), getHost().getPort(), cpConfig.getConnectTimeout());
        }

        socket.getSocket().setTcpNoDelay(true);
        socket.getSocket().setKeepAlive(true);
        socket.getSocket().setSoLinger(false, 0);

        setTimeout(cpConfig.getSocketTimeout());
        transport = new TFramedTransport(socket);
        if (!transport.isOpen()) transport.open();

        cassandraClient =
            new Cassandra.Client(new TBinaryProtocol.Factory().getProtocol(transport));
        monitor.incConnectionCreated(getHost());

        AuthenticationCredentials credentials = cpConfig.getAuthenticationCredentials();
        if (credentials != null) {
          Map<String, String> thriftCredentials = Maps.newHashMapWithExpectedSize(2);
          thriftCredentials.put("username", credentials.getUsername());
          thriftCredentials.put("password", credentials.getPassword());
          cassandraClient.login(new AuthenticationRequest(thriftCredentials));
        }
      } catch (Exception e) {
        pool.addLatencySample(
            TimeUnit.NANOSECONDS.convert(cpConfig.getSocketTimeout(), TimeUnit.MILLISECONDS),
            System.nanoTime());
        closeClient();
        ConnectionException ce =
            ThriftConverter.ToConnectionPoolException(e)
                .setHost(getHost())
                .setLatency(System.currentTimeMillis() - startTime);
        monitor.incConnectionCreateFailed(getHost(), ce);
        throw ce;
      } catch (Throwable t) {
        LOG.error("Error creating connection", t);
        pool.addLatencySample(
            TimeUnit.NANOSECONDS.convert(cpConfig.getSocketTimeout(), TimeUnit.MILLISECONDS),
            System.nanoTime());
        closeClient();
        ConnectionException ce =
            ThriftConverter.ToConnectionPoolException(
                    new RuntimeException("Error openning connection", t))
                .setHost(getHost())
                .setLatency(System.currentTimeMillis() - startTime);
        monitor.incConnectionCreateFailed(getHost(), ce);
        throw ce;
      }
    }