@GuardedBy("fetchDataLock")
  @CanIgnoreReturnValue
  private String fetchAndCacheData() throws IOException {
    long currentTimeInMillis = getCurrentTimeInMillis();
    HttpRequest httpRequest =
        httpTransport.createRequestFactory().buildGetRequest(new GenericUrl(url));
    HttpResponse httpResponse = httpRequest.execute();
    if (httpResponse.getStatusCode() != HttpStatusCodes.STATUS_CODE_OK) {
      throw new IOException("Unexpected status code = " + httpResponse.getStatusCode());
    }
    String data;
    InputStream contentStream = httpResponse.getContent();
    try {
      InputStreamReader reader = new InputStreamReader(contentStream, UTF_8);
      data = readerToString(reader);
    } finally {
      contentStream.close();
    }
    synchronized (instanceStateLock) {
      this.cachedTimeInMillis = currentTimeInMillis;
      this.cacheExpirationDurationInMillis =
          getExpirationDurationInSeconds(httpResponse.getHeaders()) * 1000;
      this.cachedData = data;
    }
    return data;
  }
Returns the current time in milliseconds since epoch.

<p>Visible so tests can override it in subclasses.
java_src/src/main/java/com/google/crypto/tink/util/KeysDownloader.java