/**
   * Returns a configured instance of {@code AsyncRestTemplate} used to retrieve repository source
   * files from Stash.
   *
   * @return
   */
  @Bean(name = "fileAsyncRestTemplate")
  AsyncRestTemplate fileAsyncRestTemplate() {

    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(maxThreads);
    executor.setMaxPoolSize(maxThreads);
    executor.initialize();

    AsyncRestTemplate template = new AsyncRestTemplate(executor);
    template.setErrorHandler(
        new StatusCheckingResponseErrorHandler() {

          @Override
          public void handleClientError(HttpStatus statusCode) {

            if (HttpStatus.NOT_FOUND.equals(statusCode)) {
              throw new RestClientException(
                  messageSource.getMessage(
                      MESSAGE_KEY_NOT_FOUND, null, "Not Found", LocaleContextHolder.getLocale()));
            }

            if (HttpStatus.UNAUTHORIZED.equals(statusCode)) {
              throw new RestClientException(
                  messageSource.getMessage(
                      MESSAGE_KEY_FILE_UNAUTHORIZED,
                      null,
                      "Unauthorized or Not Found",
                      LocaleContextHolder.getLocale()));
            }
          }
        });

    return template;
  }
 @RequestMapping(method = RequestMethod.GET, value = "/test")
 @ResponseBody
 public String test() {
   ListenableFuture<ResponseEntity<ApiResponse>> future =
       asyncRestTemplate.getForEntity("http://localhost:8088/api/async/slow", ApiResponse.class);
   return "OK";
 }
 private MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
   for (HttpMessageConverter httpMessageConverter : asyncRestTemplate.getMessageConverters()) {
     if (httpMessageConverter instanceof MappingJackson2HttpMessageConverter) {
       return (MappingJackson2HttpMessageConverter) httpMessageConverter;
     }
   }
   return null;
 }
  private void makeAsyncRequests() {
    ListenableFuture<ResponseEntity<String>> listenableFuture =
        restTemplate.exchange(
            BASE_URL + "response-body", HttpMethod.GET, HttpEntity.EMPTY, String.class);
    listenableFuture.addCallback(
        new ListenableFutureCallback<ResponseEntity>() {
          @Override
          public void onSuccess(ResponseEntity result) {
            System.out.println("Response received (async callable): " + result.getBody());
          }

          @Override
          public void onFailure(Throwable t) {
            System.out.println("Response failed " + t.getMessage());
          }
        });
  }
  @Test
  public void getAllSeriesAsync() throws InterruptedException, ExecutionException {
    logger.info("Calling async /series");
    Future<ResponseEntity<Series[]>> futureEntity =
        asyncRestTemplate.getForEntity(BASE_URI, Series[].class);
    logger.info("Doing other async stuff...");

    logger.info("Blocking to receive response...");
    ResponseEntity<Series[]> entity = futureEntity.get();
    logger.info("Response received");
    Series[] series = entity.getBody();

    assertNotNull(series);
    assertEquals(2, series.length);
    assertEquals(1L, series[0].getId());
    assertEquals("The walking dead", series[0].getName());
    assertEquals("USA", series[0].getCountry());
    assertEquals("Thriller", series[0].getGenre());
    assertEquals(2L, series[1].getId());
    assertEquals("Homeland", series[1].getName());
    assertEquals("USA", series[1].getCountry());
    assertEquals("Drama", series[1].getGenre());
  }
 /** Make an HTTP request with custom headers */
 protected <T, U> ListenableFuture<ResponseEntity<T>> request(
     HttpMethod method, String uri, HttpHeaders httpHeaders, U body, Class<T> responseType) {
   HttpEntity<U> requestEntity = new HttpEntity<>(body, httpHeaders);
   return asyncRestTemplate.exchange(uri, method, requestEntity, responseType);
 }