HttpJsonDirectCallable extends UnaryCallable<RequestT, ResponseT> { @Override public ApiFuture<ResponseT> futureCall(RequestT request, ApiCallContext inputContext) { Preconditions.checkNotNull(request); HttpJsonCallContext context = HttpJsonCallContext.createDefault().nullToSelf(inputContext); @Nullable Instant deadline = context.getDeadline(); if (context.getTimeout() != null) { @Nonnull Instant newDeadline = Instant.now().plus(context.getTimeout()); if (deadline == null || newDeadline.isBefore(deadline)) { deadline = newDeadline; } } HttpJsonCallOptions callOptions = HttpJsonCallOptions.newBuilder() .setDeadline(deadline) .setCredentials(context.getCredentials()) .build(); return context.getChannel().issueFutureUnaryCall(callOptions, request, descriptor); } HttpJsonDirectCallable(ApiMethodDescriptor<RequestT, ResponseT> descriptor); @Override ApiFuture<ResponseT> futureCall(RequestT request, ApiCallContext inputContext); @Override String toString();  }
@SuppressWarnings("unchecked") @Test public void testTimeout() { HttpJsonChannel mockChannel = Mockito.mock(HttpJsonChannel.class); String expectedRequest = "fake"; HttpJsonDirectCallable<String, String> callable = new HttpJsonDirectCallable<>(API_DESCRIPTOR); ArgumentCaptor<HttpJsonCallOptions> capturedCallOptions = ArgumentCaptor.forClass(HttpJsonCallOptions.class); Mockito.when( mockChannel.issueFutureUnaryCall( capturedCallOptions.capture(), Mockito.anyString(), Mockito.any(ApiMethodDescriptor.class))) .thenReturn(SettableApiFuture.create()); Duration timeout = Duration.ofSeconds(10); Instant minExpectedDeadline = Instant.now().plus(timeout); HttpJsonCallContext callContext = HttpJsonCallContext.createDefault().withChannel(mockChannel).withTimeout(timeout); callable.futureCall(expectedRequest, callContext); Instant maxExpectedDeadline = Instant.now().plus(timeout); assertThat(capturedCallOptions.getValue().getDeadline()).isAtLeast(minExpectedDeadline); assertThat(capturedCallOptions.getValue().getDeadline()).isAtMost(maxExpectedDeadline); }
@SuppressWarnings("unchecked") @Test public void testTimeoutAfterDeadline() { HttpJsonChannel mockChannel = Mockito.mock(HttpJsonChannel.class); String expectedRequest = "fake"; HttpJsonDirectCallable<String, String> callable = new HttpJsonDirectCallable<>(API_DESCRIPTOR); ArgumentCaptor<HttpJsonCallOptions> capturedCallOptions = ArgumentCaptor.forClass(HttpJsonCallOptions.class); Mockito.when( mockChannel.issueFutureUnaryCall( capturedCallOptions.capture(), Mockito.anyString(), Mockito.any(ApiMethodDescriptor.class))) .thenReturn(SettableApiFuture.create()); Instant priorDeadline = Instant.now().plusSeconds(5); Duration timeout = Duration.ofSeconds(10); HttpJsonCallContext callContext = HttpJsonCallContext.createDefault() .withChannel(mockChannel) .withDeadline(priorDeadline) .withTimeout(timeout); callable.futureCall(expectedRequest, callContext); assertThat(capturedCallOptions.getValue().getDeadline()).isEqualTo(priorDeadline); }
@SuppressWarnings("unchecked") @Test public void testTimeoutBeforeDeadline() { HttpJsonChannel mockChannel = Mockito.mock(HttpJsonChannel.class); String expectedRequest = "fake"; HttpJsonDirectCallable<String, String> callable = new HttpJsonDirectCallable<>(API_DESCRIPTOR); ArgumentCaptor<HttpJsonCallOptions> capturedCallOptions = ArgumentCaptor.forClass(HttpJsonCallOptions.class); Mockito.when( mockChannel.issueFutureUnaryCall( capturedCallOptions.capture(), Mockito.anyString(), Mockito.any(ApiMethodDescriptor.class))) .thenReturn(SettableApiFuture.create()); Duration timeout = Duration.ofSeconds(10); Instant subsequentDeadline = Instant.now().plusSeconds(15); Instant minExpectedDeadline = Instant.now().plus(timeout); HttpJsonCallContext callContext = HttpJsonCallContext.createDefault() .withChannel(mockChannel) .withDeadline(subsequentDeadline) .withTimeout(timeout); callable.futureCall(expectedRequest, callContext); Instant maxExpectedDeadline = Instant.now().plus(timeout); assertThat(capturedCallOptions.getValue().getDeadline()).isAtLeast(minExpectedDeadline); assertThat(capturedCallOptions.getValue().getDeadline()).isAtMost(maxExpectedDeadline); }