RefreshingOAuth2CredentialsInterceptor implements ClientInterceptor { @Override public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall( MethodDescriptor<ReqT, RespT> method, final CallOptions callOptions, Channel next) { return new SimpleForwardingClientCall<ReqT, RespT>(next.newCall(method, callOptions)) { private volatile boolean unauthorized = false; @Override public void start(Listener<RespT> responseListener, Metadata headers) { final long timeout; if (callOptions.getDeadline() != null) { timeout = callOptions.getDeadline().timeRemaining(TimeUnit.MILLISECONDS); } else { timeout = TIMEOUT_MILLISECONDS; } HeaderToken token = store.getHeader(timeout, TimeUnit.MILLISECONDS); if (!token.getStatus().isOk()) { unauthorized = true; responseListener.onClose(token.getStatus(), new Metadata()); return; } headers.put(AUTHORIZATION_HEADER_KEY, token.getHeader()); delegate().start(new UnAuthResponseListener<>(responseListener, token), headers); } @Override public void request(int numMessages) { if (!unauthorized) { delegate().request(numMessages); } } @Override public void sendMessage(ReqT message) { if (!unauthorized) { delegate().sendMessage(message); } } @Override public void halfClose() { if (!unauthorized) { delegate().halfClose(); } } @Override public void cancel(String message, Throwable cause) { if (!unauthorized) { delegate().cancel(message, cause); } } }; } RefreshingOAuth2CredentialsInterceptor(
      ExecutorService scheduler, OAuth2Credentials credentials); @VisibleForTesting  RefreshingOAuth2CredentialsInterceptor(OAuthCredentialsCache store); @Override ClientCall<ReqT, RespT> interceptCall(
      MethodDescriptor<ReqT, RespT> method, final CallOptions callOptions, Channel next);  }
@Test public void testInvalidAuthToken() throws IOException { Status grpcStatus = Status.UNAUTHENTICATED; when(mockCache.getHeader(any(Long.class), any(TimeUnit.class))) .thenReturn(new OAuthCredentialsCache.HeaderToken(grpcStatus, null)); ClientCall<ReadRowsRequest, ReadRowsResponse> call = underTest.interceptCall(BigtableGrpc.getReadRowsMethod(), CallOptions.DEFAULT, mockChannel); call.start(mockListener, new Metadata()); verify(mockListener, times(1)).onClose(same(grpcStatus), any(Metadata.class)); call.request(1); verify(mockClientCall, times(0)).request(anyInt()); call.halfClose(); verify(mockClientCall, times(0)).halfClose(); call.sendMessage(ReadRowsRequest.getDefaultInstance()); verify(mockClientCall, times(0)).sendMessage(any(ReadRowsRequest.class)); call.cancel("", null); verify(mockClientCall, times(0)).cancel(anyString(), any(Throwable.class)); }