public static <K, V> CompletableFuture<Map<K, V>> toFutureOfMap(Map<K, CompletableFuture<V>> keyToValueFutures) {
    return CompletableFuture
        .allOf(keyToValueFutures.values().toArray(new CompletableFuture[0]))
        .thenApply(v -> keyToValueFutures.entrySet().stream()
            .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().join())));
  }
Helper method to convert: {@code Map<K, CompletableFuture<V>>}
to:                       {@code CompletableFuture<Map<K, V>>}

Returns a future that completes when all value futures complete.
Returned future completes exceptionally if any of the value futures complete exceptionally.
samza-core/src/main/java/org/apache/samza/util/FutureUtil.java