private InstanceMetadata fetchMetadata()

in core/src/main/java/com/google/cloud/sql/core/DefaultConnectionInfoRepository.java [245:367]


  private InstanceMetadata fetchMetadata(CloudSqlInstanceName instanceName, AuthType authType) {
    try {
      ConnectSettings instanceMetadata =
          new ApiClientRetryingCallable<>(
                  () ->
                      apiClient
                          .connect()
                          .get(instanceName.getProjectId(), instanceName.getInstanceId())
                          .execute())
              .call();

      // Validate the instance will support the authenticated connection.
      if (!instanceMetadata.getRegion().equals(instanceName.getRegionId())) {
        throw new TerminalException(
            String.format(
                "[%s] The region specified for the Cloud SQL instance is"
                    + " incorrect. Please verify the instance connection name.",
                instanceName.getConnectionName()));
      }
      if (!instanceMetadata.getBackendType().equals("SECOND_GEN")) {
        throw new TerminalException(
            String.format(
                "[%s] Connections to Cloud SQL instance not supported - not a Second Generation "
                    + "instance.",
                instanceName.getConnectionName()));
      }

      checkDatabaseCompatibility(instanceMetadata, authType, instanceName.getConnectionName());

      Map<IpType, String> ipAddrs = new HashMap<>();
      if (instanceMetadata.getIpAddresses() != null) {
        // Update the IP addresses and types need to connect with the instance.
        for (IpMapping addr : instanceMetadata.getIpAddresses()) {
          if ("PRIVATE".equals(addr.getType())) {
            ipAddrs.put(IpType.PRIVATE, addr.getIpAddress());
          } else if ("PRIMARY".equals(addr.getType())) {
            ipAddrs.put(IpType.PUBLIC, addr.getIpAddress());
          }
          // otherwise, we don't know how to handle this type, ignore it.
        }
      }

      // If PSC is enabled, resolve DnsName into IP address for PSC
      boolean pscEnabled =
          instanceMetadata.getPscEnabled() != null
              && instanceMetadata.getPscEnabled().booleanValue();

      if (pscEnabled) {
        // Search the dns_names field for the PSC DNS Name.
        String pscDnsName = null;
        if (instanceMetadata.getDnsNames() != null) {
          for (DnsNameMapping dnm : instanceMetadata.getDnsNames()) {
            if ("PRIVATE_SERVICE_CONNECT".equals(dnm.getConnectionType())
                && "INSTANCE".equals(dnm.getDnsScope())) {
              pscDnsName = dnm.getName();
              break;
            }
          }
        }

        // If the psc dns name was not found, use the legacy dns_name field
        if (pscDnsName == null
            && instanceMetadata.getDnsName() != null
            && !instanceMetadata.getDnsName().isEmpty()) {
          pscDnsName = instanceMetadata.getDnsName();
        }

        // If the psc dns name was found, add it to the ipaddrs map.
        if (pscDnsName != null) {
          ipAddrs.put(IpType.PSC, pscDnsName);
        }
      }

      // Verify the instance has at least one IP type assigned that can be used to connect.
      if (ipAddrs.isEmpty()) {
        throw new TerminalException(
            String.format(
                "[%s] Unable to connect to Cloud SQL instance: instance does not have an assigned "
                    + "IP address.",
                instanceName.getConnectionName()));
      }

      // Find a DNS name to use to validate the certificate from the dns_names field. Any
      // name in the list may be used to validate the server TLS certificate.
      // Fall back to legacy dns_name field if necessary.
      String serverName = null;
      if (instanceMetadata.getDnsNames() != null && !instanceMetadata.getDnsNames().isEmpty()) {
        serverName = instanceMetadata.getDnsNames().get(0).getName();
      }
      if (serverName == null) {
        serverName = instanceMetadata.getDnsName();
      }

      // Update the Server CA certificate used to create the SSL connection with the instance.
      try {
        List<Certificate> instanceCaCertificates =
            parseCertificateChain(instanceMetadata.getServerCaCert().getCert());

        logger.debug(String.format("[%s] METADATA DONE", instanceName));

        return new InstanceMetadata(
            instanceName,
            ipAddrs,
            instanceCaCertificates,
            isCasManagedCertificate(instanceMetadata.getServerCaMode()),
            serverName,
            pscEnabled);
      } catch (CertificateException ex) {
        throw new RuntimeException(
            String.format(
                "[%s] Unable to parse the server CA certificate for the Cloud SQL instance.",
                instanceName.getConnectionName()),
            ex);
      }
    } catch (Exception ex) {
      throw addExceptionContext(
          ex,
          String.format(
              "[%s] Failed to update metadata for Cloud SQL instance.",
              instanceName.getConnectionName()),
          instanceName);
    }
  }