Skip to content

Commit

Permalink
Merge branch 'main' into release-brancher/1.23.x
Browse files Browse the repository at this point in the history
  • Loading branch information
zhumin8 authored Aug 28, 2024
2 parents aa49353 + d7c9da7 commit 62cecf7
Show file tree
Hide file tree
Showing 19 changed files with 399 additions and 132 deletions.
2 changes: 1 addition & 1 deletion .kokoro/presubmit/graalvm-native-a.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.9.1"
value: "gcr.io/cloud-devrel-public-resources/graalvm_a:1.11.0"
}

env_vars: {
Expand Down
2 changes: 1 addition & 1 deletion .kokoro/presubmit/graalvm-native-b.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.9.1"
value: "gcr.io/cloud-devrel-public-resources/graalvm_b:1.11.0"
}

env_vars: {
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## [1.24.1](https://github.com/googleapis/google-auth-library-java/compare/v1.24.0...v1.24.1) (2024-08-13)


### Bug Fixes

* Retry sign blob call with exponential backoff ([#1452](https://github.com/googleapis/google-auth-library-java/issues/1452)) ([d42f30a](https://github.com/googleapis/google-auth-library-java/commit/d42f30acae7c7bd81afbecbfa83ebde5c6db931a))

## [1.24.0](https://github.com/googleapis/google-auth-library-java/compare/v1.23.0...v1.24.0) (2024-07-09)


Expand Down
2 changes: 1 addition & 1 deletion appengine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-parent</artifactId>
<version>1.24.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
<version>1.24.2-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
8 changes: 4 additions & 4 deletions bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-bom</artifactId>
<version>1.24.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-bom:current} -->
<version>1.24.2-SNAPSHOT</version><!-- {x-version-update:google-auth-library-bom:current} -->
<packaging>pom</packaging>
<name>Google Auth Library for Java BOM</name>
<description>
Expand Down Expand Up @@ -83,15 +83,15 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.8.0</version>
<version>3.10.0</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.12.1</version>
<version>3.20.0</version>
<configuration>
<skip>true</skip>
</configuration>
Expand Down Expand Up @@ -122,7 +122,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.2.4</version>
<version>3.2.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
Expand Down
2 changes: 1 addition & 1 deletion credentials/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-parent</artifactId>
<version>1.24.1-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
<version>1.24.2-SNAPSHOT</version><!-- {x-version-update:google-auth-library-parent:current} -->
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,10 @@ static GoogleAuthException createWithTokenEndpointIOException(
if (message == null) {
// TODO: temporarily setting retry Count to service account default to remove a direct
// dependency, to be reverted after release
return new GoogleAuthException(
true, ServiceAccountCredentials.DEFAULT_NUMBER_OF_RETRIES, ioException);
return new GoogleAuthException(true, OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES, ioException);
} else {
return new GoogleAuthException(
true, ServiceAccountCredentials.DEFAULT_NUMBER_OF_RETRIES, message, ioException);
true, OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES, message, ioException);
}
}

Expand Down
48 changes: 38 additions & 10 deletions oauth2_http/java/com/google/auth/oauth2/IamUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,28 @@
package com.google.auth.oauth2;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpBackOffIOExceptionHandler;
import com.google.api.client.http.HttpBackOffUnsuccessfulResponseHandler;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.json.JsonHttpContent;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonObjectParser;
import com.google.api.client.util.ExponentialBackOff;
import com.google.api.client.util.GenericData;
import com.google.auth.Credentials;
import com.google.auth.ServiceAccountSigner;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.common.io.BaseEncoding;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
* This internal class provides shared utilities for interacting with the IAM API for common
Expand All @@ -60,6 +67,11 @@ class IamUtils {
private static final String PARSE_ERROR_MESSAGE = "Error parsing error message response. ";
private static final String PARSE_ERROR_SIGNATURE = "Error parsing signature response. ";

// Following guidance for IAM retries:
// https://cloud.google.com/iam/docs/retry-strategy#errors-to-retry
static final Set<Integer> IAM_RETRYABLE_STATUS_CODES =
new HashSet<>(Arrays.asList(500, 502, 503, 504));

/**
* Returns a signature for the provided bytes.
*
Expand All @@ -78,11 +90,12 @@ static byte[] sign(
byte[] toSign,
Map<String, ?> additionalFields) {
BaseEncoding base64 = BaseEncoding.base64();
HttpRequestFactory factory =
transport.createRequestFactory(new HttpCredentialsAdapter(credentials));
String signature;
try {
signature =
getSignature(
serviceAccountEmail, credentials, transport, base64.encode(toSign), additionalFields);
getSignature(serviceAccountEmail, base64.encode(toSign), additionalFields, factory);
} catch (IOException ex) {
throw new ServiceAccountSigner.SigningException("Failed to sign the provided bytes", ex);
}
Expand All @@ -91,10 +104,9 @@ static byte[] sign(

private static String getSignature(
String serviceAccountEmail,
Credentials credentials,
HttpTransport transport,
String bytes,
Map<String, ?> additionalFields)
Map<String, ?> additionalFields,
HttpRequestFactory factory)
throws IOException {
String signBlobUrl = String.format(SIGN_BLOB_URL_FORMAT, serviceAccountEmail);
GenericUrl genericUrl = new GenericUrl(signBlobUrl);
Expand All @@ -106,13 +118,27 @@ private static String getSignature(
}
JsonHttpContent signContent = new JsonHttpContent(OAuth2Utils.JSON_FACTORY, signRequest);

HttpCredentialsAdapter adapter = new HttpCredentialsAdapter(credentials);
HttpRequest request =
transport.createRequestFactory(adapter).buildPostRequest(genericUrl, signContent);
HttpRequest request = factory.buildPostRequest(genericUrl, signContent);

JsonObjectParser parser = new JsonObjectParser(OAuth2Utils.JSON_FACTORY);
request.setParser(parser);
request.setThrowExceptionOnExecuteError(false);
request.setNumberOfRetries(OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES);

ExponentialBackOff backoff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(OAuth2Utils.RETRY_MULTIPLIER)
.build();

// Retry on 500, 502, 503, and 503 status codes
request.setUnsuccessfulResponseHandler(
new HttpBackOffUnsuccessfulResponseHandler(backoff)
.setBackOffRequired(
response ->
IamUtils.IAM_RETRYABLE_STATUS_CODES.contains(response.getStatusCode())));
request.setIOExceptionHandler(new HttpBackOffIOExceptionHandler(backoff));

HttpResponse response = request.execute();
int statusCode = response.getStatusCode();
Expand All @@ -125,6 +151,8 @@ private static String getSignature(
String.format(
"Error code %s trying to sign provided bytes: %s", statusCode, errorMessage));
}

// Request will have retried a 5xx error 3 times and is still receiving a 5xx error code
if (statusCode != HttpStatusCodes.STATUS_CODE_OK) {
throw new IOException(
String.format(
Expand Down Expand Up @@ -152,8 +180,8 @@ private static String getSignature(
* @param additionalFields additional fields to send in the IAM call
* @return IdToken issed to the serviceAccount
* @throws IOException if the IdToken cannot be issued.
* @see
* https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateIdToken
* @see <a
* href="https://cloud.google.com/iam/credentials/reference/rest/v1/projects.serviceAccounts/generateIdToken">...</a>
*/
static IdToken getIdToken(
String serviceAccountEmail,
Expand Down
5 changes: 5 additions & 0 deletions oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class OAuth2Utils {

static final String TOKEN_RESPONSE_SCOPE = "scope";

static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000;
static final double RETRY_RANDOMIZATION_FACTOR = 0.1;
static final double RETRY_MULTIPLIER = 2;
static final int DEFAULT_NUMBER_OF_RETRIES = 3;

// Includes expected server errors from Google token endpoint
// Other 5xx codes are either not used or retries are unlikely to succeed
public static final Set<Integer> TOKEN_ENDPOINT_RETRYABLE_STATUS_CODES =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,6 @@ public class ServiceAccountCredentials extends GoogleCredentials
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
private static final int TWELVE_HOURS_IN_SECONDS = 43200;
private static final int DEFAULT_LIFETIME_IN_SECONDS = 3600;
private static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000;
private static final double RETRY_RANDOMIZATION_FACTOR = 0.1;
private static final double RETRY_MULTIPLIER = 2;
static final int DEFAULT_NUMBER_OF_RETRIES = 3;

private final String clientId;
private final String clientEmail;
Expand Down Expand Up @@ -505,17 +501,17 @@ public AccessToken refreshAccessToken() throws IOException {
HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);

if (this.defaultRetriesEnabled) {
request.setNumberOfRetries(DEFAULT_NUMBER_OF_RETRIES);
request.setNumberOfRetries(OAuth2Utils.DEFAULT_NUMBER_OF_RETRIES);
} else {
request.setNumberOfRetries(0);
}
request.setParser(new JsonObjectParser(jsonFactory));

ExponentialBackOff backoff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(RETRY_MULTIPLIER)
.setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(OAuth2Utils.RETRY_MULTIPLIER)
.build();

request.setUnsuccessfulResponseHandler(
Expand Down
9 changes: 3 additions & 6 deletions oauth2_http/java/com/google/auth/oauth2/TokenVerifier.java
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,6 @@ public TokenVerifier build() {
/** Custom CacheLoader for mapping certificate urls to the contained public keys. */
static class PublicKeyLoader extends CacheLoader<String, Map<String, PublicKey>> {
private static final int DEFAULT_NUMBER_OF_RETRIES = 2;
private static final int INITIAL_RETRY_INTERVAL_MILLIS = 1000;
private static final double RETRY_RANDOMIZATION_FACTOR = 0.1;
private static final double RETRY_MULTIPLIER = 2;
private final HttpTransportFactory httpTransportFactory;

/**
Expand Down Expand Up @@ -330,9 +327,9 @@ public Map<String, PublicKey> load(String certificateUrl) throws Exception {

ExponentialBackOff backoff =
new ExponentialBackOff.Builder()
.setInitialIntervalMillis(INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(RETRY_MULTIPLIER)
.setInitialIntervalMillis(OAuth2Utils.INITIAL_RETRY_INTERVAL_MILLIS)
.setRandomizationFactor(OAuth2Utils.RETRY_RANDOMIZATION_FACTOR)
.setMultiplier(OAuth2Utils.RETRY_MULTIPLIER)
.build();

request.setUnsuccessfulResponseHandler(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

import static org.junit.Assert.*;

import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.json.GenericJson;
import com.google.api.client.util.Clock;
import com.google.auth.Credentials;
Expand Down Expand Up @@ -609,6 +610,7 @@ public void fromStream_Impersonation_providesToken_WithQuotaProject() throws IOE
transportFactory.transport.setExpireTime(ImpersonatedCredentialsTest.getDefaultExpireTime());
transportFactory.transport.setAccessTokenEndpoint(
ImpersonatedCredentialsTest.IMPERSONATION_URL);
transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");

InputStream impersonationCredentialsStream =
ImpersonatedCredentialsTest.writeImpersonationCredentialsStream(
Expand Down Expand Up @@ -669,6 +671,7 @@ public void fromStream_Impersonation_providesToken_WithoutQuotaProject() throws
transportFactory.transport.setExpireTime(ImpersonatedCredentialsTest.getDefaultExpireTime());
transportFactory.transport.setAccessTokenEndpoint(
ImpersonatedCredentialsTest.IMPERSONATION_URL);
transportFactory.transport.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");

InputStream impersonationCredentialsStream =
ImpersonatedCredentialsTest.writeImpersonationCredentialsStream(
Expand Down
Loading

0 comments on commit 62cecf7

Please sign in to comment.