core/src/main/java/com/google/cloud/sql/core/CoreSocketFactory.java
@VisibleForTesting
  synchronized InstanceSslInfo getInstanceSslInfo(
      String instanceConnectionString, CertificateCaching certificateCaching) {

    if (certificateCaching.equals(CertificateCaching.USE_CACHE)) {
      InstanceLookupResult lookupResult = cache.get(instanceConnectionString);
      if (lookupResult != null) {
        if (!lookupResult.isSuccessful()
            && (clock.now() - lookupResult.getLastFailureMillis()) < 60 * 1000) {
          logger.warning(
              "Re-throwing cached exception due to attempt to refresh instance information too "
                  + "soon after error.");
          throw lookupResult.getException().get();
        } else if (lookupResult.isSuccessful()) {
          InstanceSslInfo details = lookupResult.getInstanceSslInfo().get();
          // Check if the cached certificate is still valid.
          if (details != null) {
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.setTimeInMillis(clock.now());
            calendar.add(Calendar.MINUTE, 5);
            try {
              details.getEphemeralCertificate().checkValidity(calendar.getTime());
            } catch (CertificateException err) {
              logger.info(
                  String.format(
                      "Ephemeral certificate for Cloud SQL instance [%s] is about to expire, "
                          + "obtaining new one.",
                      instanceConnectionString));
              details = null;
            }
          }

          if (details != null) {
            return details;
          }
        }
      }
    }

    String invalidInstanceError =
        String.format(
            "Invalid Cloud SQL instance [%s], expected value in form [project:region:name].",
            instanceConnectionString);

    int beforeNameIndex = instanceConnectionString.lastIndexOf(':');
    if (beforeNameIndex <= 0) {
      throw new IllegalArgumentException(invalidInstanceError);
    }

    int beforeRegionIndex = instanceConnectionString.lastIndexOf(':', beforeNameIndex - 1);
    if (beforeRegionIndex <= 0) {
      throw new IllegalArgumentException(invalidInstanceError);
    }

    String projectId = instanceConnectionString.substring(0, beforeRegionIndex);
    String region = instanceConnectionString.substring(beforeRegionIndex + 1, beforeNameIndex);
    String instanceName = instanceConnectionString.substring(beforeNameIndex + 1);

    InstanceLookupResult instanceLookupResult;
    InstanceSslInfo details;
    try {
      details = fetchInstanceSslInfo(instanceConnectionString, projectId, region, instanceName);
      instanceLookupResult = new InstanceLookupResult(details);
      cache.put(instanceConnectionString, instanceLookupResult);
    } catch (RuntimeException err) {
      instanceLookupResult = new InstanceLookupResult(err);
      cache.put(instanceConnectionString, instanceLookupResult);
      throw err;
    }

    return details;
  }
@VisibleForTesting
  synchronized InstanceSslInfo getInstanceSslInfo(
      String instanceConnectionString, CertificateCaching certificateCaching) {

    if (certificateCaching.equals(CertificateCaching.USE_CACHE)) {
      InstanceLookupResult lookupResult = cache.get(instanceConnectionString);
      if (lookupResult != null) {
        if (!lookupResult.isSuccessful()
            && (clock.now() - lookupResult.getLastFailureMillis()) < 60 * 1000) {
          logger.warning(
              "Re-throwing cached exception due to attempt to refresh instance information too "
                  + "soon after error.");
          throw lookupResult.getException().get();
        } else if (lookupResult.isSuccessful()) {
          InstanceSslInfo details = lookupResult.getInstanceSslInfo().get();
          // Check if the cached certificate is still valid.
          if (details != null) {
            GregorianCalendar calendar = new GregorianCalendar();
            calendar.setTimeInMillis(clock.now());
            calendar.add(Calendar.MINUTE, 5);
            try {
              details.getEphemeralCertificate().checkValidity(calendar.getTime());
            } catch (CertificateException err) {
              logger.info(
                  String.format(
                      "Ephemeral certificate for Cloud SQL instance [%s] is about to expire, "
                          + "obtaining new one.",
                      instanceConnectionString));
              details = null;
            }
          }

          if (details != null) {
            return details;
          }
        }
      }
    }

    String invalidInstanceError =
        String.format(
            "Invalid Cloud SQL instance [%s], expected value in form [project:region:name].",
            instanceConnectionString);

    int beforeNameIndex = instanceConnectionString.lastIndexOf(':');
    if (beforeNameIndex <= 0) {
      throw new IllegalArgumentException(invalidInstanceError);
    }

    int beforeRegionIndex = instanceConnectionString.lastIndexOf(':', beforeNameIndex - 1);
    if (beforeRegionIndex <= 0) {
      throw new IllegalArgumentException(invalidInstanceError);
    }

    String projectId = instanceConnectionString.substring(0, beforeRegionIndex);
    String region = instanceConnectionString.substring(beforeRegionIndex + 1, beforeNameIndex);
    String instanceName = instanceConnectionString.substring(beforeNameIndex + 1);

    InstanceLookupResult instanceLookupResult;
    InstanceSslInfo details;
    try {
      details = fetchInstanceSslInfo(instanceConnectionString, projectId, region, instanceName);
      instanceLookupResult = new InstanceLookupResult(details);
      cache.put(instanceConnectionString, instanceLookupResult);
    } catch (RuntimeException err) {
      instanceLookupResult = new InstanceLookupResult(err);
      cache.put(instanceConnectionString, instanceLookupResult);
      throw err;
    }

    return details;
  }
@ VisibleForTesting synchronized InstanceSslInfo getInstanceSslInfo ( String instanceConnectionString , CertificateCaching certificateCaching ) { if ( certificateCaching . equals ( CertificateCaching . USE_CACHE ) ) { InstanceLookupResult lookupResult = cache . get ( instanceConnectionString ) ; if ( lookupResult != null ) { if ( ! lookupResult . isSuccessful ( ) && ( clock . now ( ) - lookupResult . getLastFailureMillis ( ) ) < 60 * 1000 ) { logger . warning ( "Re-throwing cached exception due to attempt to refresh instance information too " + "soon after error." ) ; throw lookupResult . getException ( ) . get ( ) ; } else if ( lookupResult . isSuccessful ( ) ) { InstanceSslInfo details = lookupResult . getInstanceSslInfo ( ) . get ( ) ; // Check if the cached certificate is still valid. if ( details != null ) { GregorianCalendar calendar = new GregorianCalendar ( ) ; calendar . setTimeInMillis ( clock . now ( ) ) ; calendar . add ( Calendar . MINUTE , 5 ) ; try { details . getEphemeralCertificate ( ) . checkValidity ( calendar . getTime ( ) ) ; } catch ( CertificateException err ) { logger . info ( String . format ( "Ephemeral certificate for Cloud SQL instance [%s] is about to expire, " + "obtaining new one." , instanceConnectionString ) ) ; details = null ; } } if ( details != null ) { return details ; } } } } String invalidInstanceError = String . format ( "Invalid Cloud SQL instance [%s], expected value in form [project:region:name]." , instanceConnectionString ) ; int beforeNameIndex = instanceConnectionString . lastIndexOf ( ' ' ) ; if ( beforeNameIndex <= 0 ) { throw new IllegalArgumentException ( invalidInstanceError ) ; } int beforeRegionIndex = instanceConnectionString . lastIndexOf ( ' ' , beforeNameIndex - 1 ) ; if ( beforeRegionIndex <= 0 ) { throw new IllegalArgumentException ( invalidInstanceError ) ; } String projectId = instanceConnectionString . substring ( 0 , beforeRegionIndex ) ; String region = instanceConnectionString . substring ( beforeRegionIndex + 1 , beforeNameIndex ) ; String instanceName = instanceConnectionString . substring ( beforeNameIndex + 1 ) ; InstanceLookupResult instanceLookupResult ; InstanceSslInfo details ; try { details = fetchInstanceSslInfo ( instanceConnectionString , projectId , region , instanceName ) ; instanceLookupResult = new InstanceLookupResult ( details ) ; cache . put ( instanceConnectionString , instanceLookupResult ) ; } catch ( RuntimeException err ) { instanceLookupResult = new InstanceLookupResult ( err ) ; cache . put ( instanceConnectionString , instanceLookupResult ) ; throw err ; } return details ; }
TODO(berezv): synchronize per instance, instead of globally
TODO ( berezv ) : synchronize per instance instead of globally