private RunConnectionState runConnection()

in src/main/java/com/google/cloud/spanner/pgadapter/ConnectionHandler.java [392:497]


  private RunConnectionState runConnection(boolean ssl) {
    RunConnectionState result = RunConnectionState.TERMINATED;
    try (ConnectionMetadata connectionMetadata =
        new ConnectionMetadata(this.socket.getInputStream(), this.socket.getOutputStream())) {
      this.connectionMetadata = connectionMetadata;

      try {
        this.message = this.server.recordMessage(BootstrapMessage.create(this));
      } catch (EOFException ignore) {
        // Just ignore the connection and close it if the client never sends us a valid startup
        // message. This also prevents probers that just check for an open TCP port to cause errors
        // to be logged.
        return result;
      } catch (Exception exception) {
        this.handleError(
            PGException.newBuilder(exception)
                .setSeverity(Severity.FATAL)
                .setSQLState(SQLState.InternalError)
                .build());
        throw exception;
      }
      try {
        if (!ssl
            && getServer().getOptions().getSslMode().isSslEnabled()
            && this.message instanceof SSLMessage) {
          this.message.send();
          this.connectionMetadata.markForRestart();
          result = RunConnectionState.RESTART_WITH_SSL;
          return result;
        }
        // Check whether the connection is valid. That is, the connection satisfies any restrictions
        // on non-localhost connections and SSL requirements.
        if (!checkValidConnection(ssl)) {
          return result;
        }
        this.message.send();

        while (this.status == ConnectionStatus.UNAUTHENTICATED) {
          try {
            message.nextHandler();
            message.send();
          } catch (EOFException eofException) {
            // This indicates that the frontend terminated the connection before we got
            // authenticated. This is in most cases an indication that the frontend killed the
            // connection after having requested SSL and gotten an SSL denied message.
            this.status = ConnectionStatus.TERMINATED;
            break;
          }
        }
        while (this.status != ConnectionStatus.TERMINATED) {
          handleMessages();
        }
      } catch (PGException pgException) {
        this.handleError(pgException);
      } catch (Exception exception) {
        this.handleError(
            PGException.newBuilder(exception)
                .setSeverity(Severity.FATAL)
                .setSQLState(SQLState.InternalError)
                .build());
      }
    } catch (Exception e) {
      logger.log(
          Level.WARNING,
          e,
          () ->
              String.format(
                  "Exception on connection handler with ID %s for client %s: %s",
                  getName(),
                  socket == null || socket.getInetAddress() == null
                      ? "(none)"
                      : socket.getInetAddress().getHostAddress(),
                  e));
    } finally {
      if (result != RunConnectionState.RESTART_WITH_SSL) {
        logger.log(
            Level.INFO,
            Logging.format(
                "RunConnection",
                () -> String.format("Closing connection handler with ID %s", getName())));
        try {
          if (this.spannerConnection != null) {
            this.spannerConnection.close();
          }
          this.socket.close();
        } catch (SpannerException | IOException e) {
          logger.log(
              Level.WARNING,
              e,
              Logging.format(
                  "RunConnection",
                  () ->
                      String.format(
                          "Exception while closing connection handler with ID %s", getName())));
        } finally {
          this.server.deregister(this);
          logger.log(
              Level.INFO,
              Logging.format(
                  "RunConnection",
                  () -> String.format("Connection handler with ID %s closed", getName())));
        }
      }
    }
    return result;
  }