diff options
author | Kun Zhang <zhangkun@google.com> | 2016-06-21 16:56:50 -0700 |
---|---|---|
committer | Kun Zhang <zhangkun@google.com> | 2016-06-21 16:56:50 -0700 |
commit | d6a090a88431a8d9c9e625630e3ccb06708636b3 (patch) | |
tree | 59c2f94bc3ee8126fe4c0f78e96c253588acb794 /auth | |
parent | 920d8a1bfc2e9434aa968b27bbca4d72af9814e8 (diff) | |
download | grpc-grpc-java-d6a090a88431a8d9c9e625630e3ccb06708636b3.tar.gz |
auth: handle null value from getRequestMetadata().
It appears some Credentials implementations may return null.
Diffstat (limited to 'auth')
-rw-r--r-- | auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java | 8 | ||||
-rw-r--r-- | auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTests.java | 31 |
2 files changed, 37 insertions, 2 deletions
diff --git a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java index e5b5cd731..85ab1b581 100644 --- a/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java +++ b/auth/src/main/java/io/grpc/auth/GoogleAuthLibraryCallCredentials.java @@ -50,6 +50,7 @@ import java.net.URISyntaxException; import java.util.List; import java.util.Map; import java.util.concurrent.Executor; +import javax.annotation.Nullable; /** * Wraps {@link Credentials} as a {@link CallCredentials}. @@ -84,17 +85,20 @@ final class GoogleAuthLibraryCallCredentials implements CallCredentials { try { // Credentials is expected to manage caching internally if the metadata is fetched over // the network. + // // TODO(zhangkun83): we don't know whether there is valid cache data. If there is, we // would waste a context switch by always scheduling in executor. However, we have to // do so because we can't risk blocking the network thread. This can be resolved after // https://github.com/google/google-auth-library-java/issues/3 is resolved. + // + // Some implementations may return null here. Map<String, List<String>> metadata = creds.getRequestMetadata(uri); // Re-use the headers if getRequestMetadata() returns the same map. It may return a // different map based on the provided URI, i.e., for JWT. However, today it does not // cache JWT and so we won't bother tring to save its return value based on the URI. Metadata headers; synchronized (GoogleAuthLibraryCallCredentials.this) { - if (lastMetadata != metadata) { + if (lastMetadata == null || lastMetadata != metadata) { lastMetadata = metadata; lastHeaders = toHeaders(metadata); } @@ -146,7 +150,7 @@ final class GoogleAuthLibraryCallCredentials implements CallCredentials { } } - private static Metadata toHeaders(Map<String, List<String>> metadata) { + private static Metadata toHeaders(@Nullable Map<String, List<String>> metadata) { Metadata headers = new Metadata(); if (metadata != null) { for (String key : metadata.keySet()) { diff --git a/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTests.java b/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTests.java index d99812f3d..c993625e4 100644 --- a/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTests.java +++ b/auth/src/test/java/io/grpc/auth/GoogleAuthLibraryCallCredentialsTests.java @@ -37,6 +37,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -71,6 +72,7 @@ import java.io.IOException; import java.net.URI; import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.concurrent.Executor; /** @@ -194,6 +196,35 @@ public class GoogleAuthLibraryCallCredentialsTests { } @Test + @SuppressWarnings("unchecked") + public void credentialsReturnNullMetadata() throws Exception { + ListMultimap<String, String> values = LinkedListMultimap.create(); + values.put("Authorization", "token1"); + when(credentials.getRequestMetadata(eq(expectedUri))) + .thenReturn(null, Multimaps.<String, String>asMap(values), null); + + GoogleAuthLibraryCallCredentials callCredentials = + new GoogleAuthLibraryCallCredentials(credentials); + for (int i = 0; i < 3; i++) { + callCredentials.applyRequestMetadata(method, attrs, executor, applier); + } + + assertEquals(3, runPendingRunnables()); + verify(credentials, times(3)).getRequestMetadata(eq(expectedUri)); + + verify(applier, times(3)).apply(headersCaptor.capture()); + List<Metadata> headerList = headersCaptor.getAllValues(); + assertEquals(3, headerList.size()); + + assertEquals(0, headerList.get(0).headerCount()); + + Iterable<String> authorization = headerList.get(1).getAll(AUTHORIZATION); + assertArrayEquals(new String[]{"token1"}, Iterables.toArray(authorization, String.class)); + + assertEquals(0, headerList.get(2).headerCount()); + } + + @Test public void oauth2Credential() { final AccessToken token = new AccessToken("allyourbase", new Date(Long.MAX_VALUE)); final OAuth2Credentials credentials = new OAuth2Credentials() { |