There is a service which uses Spring AsyncRestTemplate
for sending rest calls. Each call of AsyncRestTemplate.exchange()
returns ListenableFuture
. Something like this:
ListenableFuture future1 = new AsyncRestTemplate().exchange(...); ListenableFuture future2 = new AsyncRestTemplate().exchange(...); ListenableFuture future3 = new AsyncRestTemplate().exchange(...);
Is there a way for create single ListenableFuture
which combines all other calls? Something like Futures.allAsList
from Guava.
2 Answers
Step #1: Convert each ListenableFuture to CompletableFuture
public CompletableFuture<T> toCompletableFuture(ListenableFuture<ResponseEntity<String>> listenableFuture) { final CompletableFuture<T> completableFuture = new CompletableFuture<>(); listenableFuture.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() { @Override public void onFailure(Throwable e) { completableFuture.completeExceptionally(e); } } @Override public void onSuccess(ResponseEntity<String> result) { completableFuture.complete(parseResponse(result)); } } }); return completableFuture; }
Step #2: call CompletableFuture.allOf(cF1, cF2, cF3...)
1Since Spring 5.0, ListenableFuture
implements the method completable()
which does exactly what you need:
/** * Expose this {@link ListenableFuture} as a JDK {@link CompletableFuture}. * @since 5.0 */ default CompletableFuture<T> completable() {
ncG1vNJzZmirpJawrLvVnqmfpJ%2Bse6S7zGiorp2jqbawutJoa2xrZGp9dYOOsJiirF2bvLN50qiknmWjpb%2BqusZmo6KrpJq7oq7Lnp2urKWnsg%3D%3D