private Connection getVerifiedReaderConnection()

in wrapper/src/main/java/software/amazon/jdbc/plugin/AuroraInitialConnectionStrategyPlugin.java [247:345]


  private Connection getVerifiedReaderConnection(
      final Properties props,
      final boolean isInitialConnection,
      final JdbcCallable<Connection, SQLException> connectFunc)
      throws SQLException {

    final int retryDelayMs = OPEN_CONNECTION_RETRY_INTERVAL_MS.getInteger(props);

    final long endTimeNano = this.getTime()
        + TimeUnit.MILLISECONDS.toNanos(OPEN_CONNECTION_RETRY_TIMEOUT_MS.getInteger(props));

    Connection readerCandidateConn;
    HostSpec readerCandidate;

    while (this.getTime() < endTimeNano) {

      readerCandidateConn = null;
      readerCandidate = null;

      try {
        readerCandidate = this.getReader(props);

        if (readerCandidate == null || this.rdsUtils.isRdsClusterDns(readerCandidate.getHost())) {

          // Reader is not found. It seems that topology is outdated.
          readerCandidateConn = connectFunc.call();
          this.pluginService.forceRefreshHostList(readerCandidateConn);
          readerCandidate = this.pluginService.identifyConnection(readerCandidateConn);

          if (readerCandidate == null) {
            this.closeConnection(readerCandidateConn);
            this.delay(retryDelayMs);
            continue;
          }

          if (readerCandidate.getRole() != HostRole.READER) {
            if (this.hasNoReaders()) {
              // It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
              // and return the current (writer) connection.
              if (isInitialConnection) {
                hostListProviderService.setInitialConnectionHostSpec(readerCandidate);
              }
              return readerCandidateConn;
            }
            this.closeConnection(readerCandidateConn);
            this.delay(retryDelayMs);
            continue;
          }

          if (isInitialConnection) {
            hostListProviderService.setInitialConnectionHostSpec(readerCandidate);
          }
          return readerCandidateConn;
        }

        readerCandidateConn = this.pluginService.connect(readerCandidate, props, this);

        if (this.pluginService.getHostRole(readerCandidateConn) != HostRole.READER) {
          // If the new connection resolves to a writer instance, this means the topology is outdated.
          // Force refresh to update the topology.
          this.pluginService.forceRefreshHostList(readerCandidateConn);

          if (this.hasNoReaders()) {
            // It seems that cluster has no readers. Simulate Aurora reader cluster endpoint logic
            // and return the current (writer) connection.
            if (isInitialConnection) {
              hostListProviderService.setInitialConnectionHostSpec(readerCandidate);
            }
            return readerCandidateConn;
          }

          this.closeConnection(readerCandidateConn);
          this.delay(retryDelayMs);
          continue;
        }

        // Reader connection is valid and verified.
        if (isInitialConnection) {
          hostListProviderService.setInitialConnectionHostSpec(readerCandidate);
        }
        return readerCandidateConn;

      } catch (SQLException ex) {
        this.closeConnection(readerCandidateConn);
        if (this.pluginService.isLoginException(ex, this.pluginService.getTargetDriverDialect())) {
          throw WrapperUtils.wrapExceptionIfNeeded(SQLException.class, ex);
        } else {
          if (readerCandidate != null) {
            this.pluginService.setAvailability(readerCandidate.asAliases(), HostAvailability.NOT_AVAILABLE);
          }
        }
      } catch (Throwable ex) {
        this.closeConnection(readerCandidateConn);
        throw ex;
      }
    }

    return null;
  }