@Override protected AsyncRestTemplate newClient(HttpTracing httpTracing) { OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(ok); AsyncRestTemplate result = new AsyncRestTemplate(factory); result.setInterceptors(Collections.singletonList( TracingAsyncClientHttpRequestInterceptor.create(httpTracing ))); return result; }
public <T> CompletableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException { return toCompletableFuture(template.exchange(url, method, requestEntity, responseType, uriVariables)); }
@Test public void multipleFutureGets() throws Exception { Future<ResponseEntity<String>> future = template.getForEntity(baseUrl + "/{method}", String.class, "get"); future.get(); future.get(); }
@Override public <T> ListenableFuture<ResponseEntity<T>> getForEntity(URI url, Class<T> responseType) throws RestClientException { AsyncRequestCallback requestCallback = acceptHeaderRequestCallback(responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, HttpMethod.GET, requestCallback, responseExtractor); }
@Override public ListenableFuture<HttpHeaders> headForHeaders(String url, Object... uriVariables) throws RestClientException { ResponseExtractor<HttpHeaders> headersExtractor = headersExtractor(); return execute(url, HttpMethod.HEAD, null, headersExtractor, uriVariables); }
@Override public ListenableFuture<URI> postForLocation(String url, @Nullable HttpEntity<?> request, Object... uriVars) throws RestClientException { AsyncRequestCallback callback = httpEntityCallback(request); ResponseExtractor<HttpHeaders> extractor = headersExtractor(); ListenableFuture<HttpHeaders> future = execute(url, HttpMethod.POST, callback, extractor, uriVars); return adaptToLocationHeader(future); }
@Override protected AsyncRestTemplate newClient() { return new AsyncRestTemplate(new OkHttp3ClientHttpRequestFactory(ok)); }
/** * @param surroundCallsWithSubspan Pass in true to have the returned {@link AsyncRestTemplate} surround all calls * with a subspan and propagate the subspan's tracing info, or false to have only the current span propagated at * the time of the call (no subspan). * @return A new {@link AsyncRestTemplate} instance with a {@link WingtipsAsyncClientHttpRequestInterceptor} * already added and with the subspan option on or off depending on the value of the {@code * surroundCallsWithSubspan} argument, and using the default {@link HttpTagAndSpanNamingStrategy} and * {@link HttpTagAndSpanNamingAdapter} ({@link ZipkinHttpTagStrategy} and {@link SpringHttpClientTagAdapter}). */ public static AsyncRestTemplate createTracingEnabledAsyncRestTemplate(boolean surroundCallsWithSubspan) { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); asyncRestTemplate.getInterceptors().add( new WingtipsAsyncClientHttpRequestInterceptor(surroundCallsWithSubspan) ); return asyncRestTemplate; }
@Bean @Resource(name = "jsonV1Converter") public AsyncRestTemplate asyncRestTemplate(AsyncClientHttpRequestFactory asyncClientHttpRequestFactory, MappingJackson2HttpMessageConverter jsonConverter) { AsyncRestTemplate restTemplate = new AsyncRestTemplate(asyncClientHttpRequestFactory); // Replace the default json converter by our converter // Remove for(HttpMessageConverter httpMessageConverter : restTemplate.getMessageConverters()) { if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) { restTemplate.getMessageConverters().remove(httpMessageConverter); break; } } // Add restTemplate.getMessageConverters().add(jsonConverter); return restTemplate; }
@Override public <T> ListenableFuture<ResponseEntity<T>> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return execute(url, method, requestCallback, responseExtractor, uriVariables); }
@Test @SuppressWarnings("deprecation") public void testAsyncTemplate() throws Exception { org.springframework.web.client.AsyncRestTemplate template = new org.springframework.web.client.AsyncRestTemplate( new MockMvcClientHttpRequestFactory(this.mockMvc)); ListenableFuture<ResponseEntity<String>> entity = template.getForEntity("/foo", String.class); assertEquals("bar", entity.get().getBody()); }
public <T> CompletableFuture<ResponseEntity<T>> postForEntity(String url, HttpEntity<?> request, Class<T> responseType, Object... uriVariables) throws RestClientException { return toCompletableFuture(template.postForEntity(url, request, responseType, uriVariables)); }
@Test(expected=SystemException.class) public void bug() throws Exception { AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(); HttpHeaders headers = new HttpHeaders(); String authHeader = "Basic " + new String(Base64.getEncoder().encode(("user:secret").getBytes())); headers.add(AUTHORIZATION, authHeader); ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.exchange("http://localhost:8080/sleepingendpoint", GET, new HttpEntity<String>(headers), String.class); future.addCallback(s -> {}, f -> { System.err.println("BUG -> SystemException not propaging up the chain <- BUG"); throw new SystemException(f); // <-- this fails in executor thread }); ResponseEntity<String> resp = future.get(); // <-- this fails with ExecutionException assertTrue(resp.getStatusCode().is2xxSuccessful()); }
@PostConstruct public void init() { if (this.restTemplates != null) { for (AsyncRestTemplate restTemplate : this.restTemplates) { List<AsyncClientHttpRequestInterceptor> interceptors = new ArrayList<>( restTemplate.getInterceptors()); interceptors.add(this.clientInterceptor); restTemplate.setInterceptors(interceptors); } } }
@Test public void getAndInterceptError() throws Exception { RequestInterceptor interceptor = new RequestInterceptor(); template.setInterceptors(Collections.singletonList(interceptor)); template.getForEntity(baseUrl + "/status/notfound", String.class); interceptor.latch.await(5, TimeUnit.SECONDS); assertNotNull(interceptor.response); assertEquals(HttpStatus.NOT_FOUND, interceptor.response.getStatusCode()); assertNull(interceptor.exception); }
public void customize(final AsyncRestTemplate restTemplate) { UriTemplateHandler templateHandler = restTemplate.getUriTemplateHandler(); templateHandler = this.interceptor.createUriTemplateHandler(templateHandler); restTemplate.setUriTemplateHandler(templateHandler); List<AsyncClientHttpRequestInterceptor> interceptors = new ArrayList<>(); interceptors.add(this.interceptor); interceptors.addAll(restTemplate.getInterceptors()); restTemplate.setInterceptors(interceptors); } }
@Override public ListenableFuture<?> put(String url, @Nullable HttpEntity<?> request, Map<String, ?> uriVars) throws RestClientException { AsyncRequestCallback requestCallback = httpEntityCallback(request); return execute(url, HttpMethod.PUT, requestCallback, null, uriVars); }
private <T> AsyncDispatcher execute(final HttpMethod method, final URI url, final HttpEntity<T> entity) { final List<HttpMessageConverter<?>> converters = template.getMessageConverters(); final Callback<T> callback = new Callback<>(converters, entity); final ListenableFuture<ClientHttpResponse> future = template.execute(url, method, new AsyncRequestCallbackAdapter<>(callback), BufferingClientHttpResponse::buffer); return new AsyncDispatcher(converters, future, router); }
private void assertLoadBalanced(AsyncRestTemplate restTemplate) { List<AsyncClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors(); MatcherAssert.assertThat(interceptors, hasSize(1)); AsyncClientHttpRequestInterceptor interceptor = interceptors.get(0); MatcherAssert.assertThat(interceptor, is(instanceOf(AsyncLoadBalancerInterceptor.class))); }
public NIORestClient(AsyncRestTemplate template) { super(); this.template = template; MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(JacksonUtil.getMapper()); template.getMessageConverters().add(converter); }