@Override
  public int write(ByteBuffer src) throws IOException {
    if (closing) {
      throw new IllegalStateException("Channel is in closing state");
    } else if (!handshakeComplete) {
      return 0;
    } else if (!flush(netWriteBuffer)) {
      return 0;
    }

    int written = 0;
    while (src.remaining() != 0) {
      netWriteBuffer.clear();
      long startTimeNs = SystemTime.getInstance().nanoseconds();
      SSLEngineResult wrapResult = sslEngine.wrap(src, netWriteBuffer);
      long encryptionTimeNs = SystemTime.getInstance().nanoseconds() - startTimeNs;
      logger.trace("SSL encryption time: {} ns for {} bytes", encryptionTimeNs, wrapResult.bytesConsumed());
      if (wrapResult.bytesConsumed() > 0) {
        metrics.sslEncryptionTimeInUsPerKB.mark(encryptionTimeNs / wrapResult.bytesConsumed());
      }
      netWriteBuffer.flip();
      //handle ssl renegotiation
      if (wrapResult.getHandshakeStatus() != HandshakeStatus.NOT_HANDSHAKING && wrapResult.getStatus() == Status.OK) {
        handshake();
        metrics.sslRenegotiationCount.inc();
        break;
      }

      if (wrapResult.getStatus() == SSLEngineResult.Status.OK) {
        written += wrapResult.bytesConsumed();
        if (!flush(netWriteBuffer)) {
          // break if socketChannel can't accept all data in netWriteBuffer
          break;
        }
        // otherwise, we are safe to clear the buffer for next iteration.
      } else if (wrapResult.getStatus() == Status.BUFFER_OVERFLOW) {
        handleWrapOverflow();
      } else if (wrapResult.getStatus() == Status.BUFFER_UNDERFLOW) {
        throw new IllegalStateException("SSL BUFFER_UNDERFLOW during write");
      } else if (wrapResult.getStatus() == Status.CLOSED) {
        throw new EOFException();
      }
    }
    return written;
  }
Writes a sequence of bytes to this channel from the given buffer.

@param src The buffer from which bytes are to be retrieved
@return The number of bytes decrypted and written to netWriteBuffer. No guarantee that data in the temporary
buffer will be completely written to the underlying channel right away. So the caller has to make sure to check
the remaining bytes in the netWriteBuffer apart from checking the remaining bytes in src bytebuffer. This method
is called from write() in the same class
@throws IOException If some other I/O error occurs
ambry-network/src/main/java/com/github/ambry/network/SSLTransmission.java