mirror of https://github.com/grpc/grpc-java.git
auth: Add support for Retryable interface
Retryable was added in google-auth-library 1.5.3 to make clear the situations that deserve a retry of the RPC. Bump to that version and swap away from the imprecise IOException heuristic. go/auth-correct-retry Fixes #6808
This commit is contained in:
parent
eeeeff0702
commit
0963f3151d
|
@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
|
||||
import com.google.auth.Credentials;
|
||||
import com.google.auth.RequestMetadataCallback;
|
||||
import com.google.auth.Retryable;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.grpc.Metadata;
|
||||
|
@ -27,7 +28,6 @@ import io.grpc.MethodDescriptor;
|
|||
import io.grpc.SecurityLevel;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.StatusException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URI;
|
||||
|
@ -133,8 +133,8 @@ final class GoogleAuthLibraryCallCredentials extends io.grpc.CallCredentials {
|
|||
|
||||
@Override
|
||||
public void onFailure(Throwable e) {
|
||||
if (e instanceof IOException) {
|
||||
// Since it's an I/O failure, let the call be retried with UNAVAILABLE.
|
||||
if (e instanceof Retryable && ((Retryable) e).isRetryable()) {
|
||||
// Let the call be retried with UNAVAILABLE.
|
||||
applier.fail(Status.UNAVAILABLE
|
||||
.withDescription("Credentials failed to obtain metadata")
|
||||
.withCause(e));
|
||||
|
|
|
@ -30,6 +30,7 @@ import static org.mockito.Mockito.when;
|
|||
|
||||
import com.google.auth.Credentials;
|
||||
import com.google.auth.RequestMetadataCallback;
|
||||
import com.google.auth.Retryable;
|
||||
import com.google.auth.http.HttpTransportFactory;
|
||||
import com.google.auth.oauth2.AccessToken;
|
||||
import com.google.auth.oauth2.GoogleCredentials;
|
||||
|
@ -191,8 +192,9 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void credentialsFailsWithIoException() throws Exception {
|
||||
Exception exception = new IOException("Broken");
|
||||
public void credentialsFailsWithRetryableRetryableException() throws Exception {
|
||||
boolean retryable = true;
|
||||
Exception exception = new RetryableException(retryable);
|
||||
when(credentials.getRequestMetadata(eq(expectedUri))).thenThrow(exception);
|
||||
|
||||
GoogleAuthLibraryCallCredentials callCredentials =
|
||||
|
@ -206,6 +208,23 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
assertEquals(exception, status.getCause());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void credentialsFailsWithUnretryableRetryableException() throws Exception {
|
||||
boolean retryable = false;
|
||||
Exception exception = new RetryableException(retryable);
|
||||
when(credentials.getRequestMetadata(eq(expectedUri))).thenThrow(exception);
|
||||
|
||||
GoogleAuthLibraryCallCredentials callCredentials =
|
||||
new GoogleAuthLibraryCallCredentials(credentials);
|
||||
callCredentials.applyRequestMetadata(new RequestInfoImpl(), executor, applier);
|
||||
|
||||
verify(credentials).getRequestMetadata(eq(expectedUri));
|
||||
verify(applier).fail(statusCaptor.capture());
|
||||
Status status = statusCaptor.getValue();
|
||||
assertEquals(Status.Code.UNAUTHENTICATED, status.getCode());
|
||||
assertEquals(exception, status.getCause());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void credentialsFailsWithRuntimeException() throws Exception {
|
||||
Exception exception = new RuntimeException("Broken");
|
||||
|
@ -453,4 +472,21 @@ public class GoogleAuthLibraryCallCredentialsTest {
|
|||
return Attributes.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
private static class RetryableException extends IOException implements Retryable {
|
||||
private final boolean retryable;
|
||||
|
||||
public RetryableException(boolean retryable) {
|
||||
super("Broken");
|
||||
this.retryable = retryable;
|
||||
}
|
||||
|
||||
@Override public boolean isRetryable() {
|
||||
return retryable;
|
||||
}
|
||||
|
||||
@Override public int getRetryCount() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ subprojects {
|
|||
|
||||
nettyVersion = '4.1.72.Final'
|
||||
guavaVersion = '31.0.1-android'
|
||||
googleauthVersion = '1.4.0'
|
||||
googleauthVersion = '1.5.3'
|
||||
protobufVersion = '3.19.2'
|
||||
protocVersion = protobufVersion
|
||||
opencensusVersion = '0.28.0'
|
||||
|
|
|
@ -28,16 +28,15 @@ dependencies {
|
|||
implementation project(':grpc-protobuf'),
|
||||
project(':grpc-stub'),
|
||||
project(':grpc-alts'),
|
||||
libraries.google_auth_credentials,
|
||||
libraries.google_auth_oauth2_http,
|
||||
libraries.autovalue_annotation,
|
||||
libraries.perfmark,
|
||||
('com.google.guava:guava:31.0.1-jre'),
|
||||
('com.google.errorprone:error_prone_annotations:2.11.0'),
|
||||
('com.google.auth:google-auth-library-credentials:1.4.0'),
|
||||
('org.checkerframework:checker-qual:3.20.0'),
|
||||
('com.google.auto.value:auto-value-annotations:1.9'),
|
||||
('com.google.http-client:google-http-client:1.41.0'),
|
||||
('com.google.http-client:google-http-client-gson:1.41.0'),
|
||||
('com.google.http-client:google-http-client:1.41.3'),
|
||||
('com.google.http-client:google-http-client-gson:1.41.3'),
|
||||
('com.google.api.grpc:proto-google-common-protos:2.7.1'),
|
||||
("com.google.cloud:google-cloud-logging:${cloudLoggingVersion}")
|
||||
|
||||
|
|
|
@ -100,7 +100,6 @@ import io.opencensus.tags.TagValue;
|
|||
import io.opencensus.trace.Span;
|
||||
import io.opencensus.trace.SpanContext;
|
||||
import io.opencensus.trace.Tracing;
|
||||
import io.opencensus.trace.unsafe.ContextUtils;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
|
@ -1547,6 +1546,7 @@ public abstract class AbstractInteropTest {
|
|||
Collections.singleton(streamingRequest), Collections.singleton(goldenStreamingResponse));
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Test(timeout = 10000)
|
||||
public void censusContextsPropagated() {
|
||||
Assume.assumeTrue("Skip the test because server is not in the same process.", server != null);
|
||||
|
@ -1561,7 +1561,7 @@ public abstract class AbstractInteropTest {
|
|||
.emptyBuilder()
|
||||
.putLocal(StatsTestUtils.EXTRA_TAG, TagValue.create("extra value"))
|
||||
.build());
|
||||
ctx = ContextUtils.withValue(ctx, clientParentSpan);
|
||||
ctx = io.opencensus.trace.unsafe.ContextUtils.withValue(ctx, clientParentSpan);
|
||||
Context origCtx = ctx.attach();
|
||||
try {
|
||||
blockingStub.unaryCall(SimpleRequest.getDefaultInstance());
|
||||
|
@ -1581,7 +1581,7 @@ public abstract class AbstractInteropTest {
|
|||
}
|
||||
assertTrue("tag not found", tagFound);
|
||||
|
||||
Span span = ContextUtils.getValue(serverCtx);
|
||||
Span span = io.opencensus.trace.unsafe.ContextUtils.getValue(serverCtx);
|
||||
assertNotNull(span);
|
||||
SpanContext spanContext = span.getContext();
|
||||
assertEquals(clientParentSpan.getContext().getTraceId(), spanContext.getTraceId());
|
||||
|
|
|
@ -12,8 +12,8 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||
IO_GRPC_GRPC_JAVA_ARTIFACTS = [
|
||||
"com.google.android:annotations:4.1.1.4",
|
||||
"com.google.api.grpc:proto-google-common-protos:2.0.1",
|
||||
"com.google.auth:google-auth-library-credentials:0.22.0",
|
||||
"com.google.auth:google-auth-library-oauth2-http:0.22.0",
|
||||
"com.google.auth:google-auth-library-credentials:1.5.3",
|
||||
"com.google.auth:google-auth-library-oauth2-http:1.5.3",
|
||||
"com.google.code.findbugs:jsr305:3.0.2",
|
||||
"com.google.code.gson:gson:2.8.9",
|
||||
"com.google.auto.value:auto-value:1.7.4",
|
||||
|
|
Loading…
Reference in New Issue