Class CompletableFutureUtils

java.lang.Object
io.vrap.rmf.base.client.utils.CompletableFutureUtils

public final class CompletableFutureUtils extends Object
Tools to simplify the work with CompletionStage and CompletableFuture.
  • Method Details

    • successful

      public static <T> CompletableFuture<T> successful(T object)

      Creates a CompletableFuture which is completed successfully with the given object.

      final CompletableFuture<String> future = successful("hello");
      assertThat(future.join()).isEqualTo("hello");
      

      See the test code.

      Type Parameters:
      T - the type of the object
      Parameters:
      object - the result of the future
      Returns:
      future
    • exceptionallyCompletedFuture

      public static <T> CompletableFuture<T> exceptionallyCompletedFuture(Throwable e)

      Creates a CompletableFuture which is completed exceptionally with the given Exception. Alias of failed(Throwable).

      final RuntimeException e = new RuntimeException();
      final CompletableFuture<String> failed = failed(e);
      assertThatThrownBy(() -> failed.join()).hasCause(e);
      

      See the test code.

      Type Parameters:
      T - the type of the value of the success case
      Parameters:
      e - exception for the future
      Returns:
      future
    • failed

      public static <T> CompletableFuture<T> failed(Throwable e)

      Creates a CompletableFuture which is completed exceptionally with the given Exception.

      final RuntimeException e = new RuntimeException();
      final CompletableFuture<String> failed = failed(e);
      assertThatThrownBy(() -> failed.join()).hasCause(e);
      

      See the test code.

      Type Parameters:
      T - the type of the value of the success case
      Parameters:
      e - exception for the future
      Returns:
      future
    • transferResult

      public static <T> void transferResult(CompletionStage<T> source, CompletableFuture<T> target)
      Internal JVM SDK util.
      Type Parameters:
      T - type of the value of the future
      Parameters:
      source - the stage which may be completed at some time
      target - future which will receive the results of source
    • onFailure

      public static <T> CompletionStage<T> onFailure(CompletionStage<T> future, Consumer<? super Throwable> consumer)

      Executes a side-effect when the future completes exceptionally.

      final RuntimeException e = new RuntimeException("foo");
      final CompletableFuture<String> future = failed(e);
      final Throwable[] state = { null };
      catchThrowable(() -> CompletableFutureUtils.onFailure(future, exception -> state[0] = exception)
              .toCompletableFuture()
              .join());
      assertThat(state[0]).isEqualTo(e);
      

      See the test code.

      Type Parameters:
      T - type of the futures value
      Parameters:
      future - the observed future
      consumer - code which should be executed if the future completes exceptionally
      Returns:
      stage which is completed when the consumer is done or the future completed successfully
    • onSuccess

      public static <T> CompletionStage<T> onSuccess(CompletionStage<T> future, Consumer<? super T> consumer)

      Executes a side-effect when the future completes successfully.

      final CompletableFuture<String> future = successful("hello");
      final String[] state = { "" };
      CompletableFutureUtils.onSuccess(future, s -> state[0] = s).toCompletableFuture().join();
      assertThat(state[0]).isEqualTo("hello");
      

      See the test code.

      Type Parameters:
      T - type of the futures value
      Parameters:
      future - the observed future
      consumer - code which should be executed if the future completes successfully
      Returns:
      stage which is completed when the consumer is done or the future completed exceptionally
    • recover

      public static <T> CompletionStage<T> recover(CompletionStage<T> future, Function<Throwable,? extends T> f)

      Creates a CompletionStage which can be recovered if an error occurs. Alias for CompletionStage.exceptionally(Function). If the recovery function also requires to create a CompletionStage then use recoverWith(CompletionStage, Function).

      final String actual = recover(failed(new RuntimeException()), e -> "hi").toCompletableFuture().join();
      assertThat(actual).isEqualTo("hi");
      

      See the test code.

      Type Parameters:
      T - type of the value of the future
      Parameters:
      future - future which may completes exceptionally
      f - function how the exception should be handled to create a successfully completed future, but it also can throw exceptions
      Returns:
      a future which can be recovered from errors
    • recoverWith

      public static <T> CompletableFuture<T> recoverWith(CompletionStage<T> future, Function<? super Throwable,CompletionStage<T>> f)

      Creates a CompletionStage which can be recovered if an error occurs. If the recovery function does not require to create a CompletionStage then use recover(CompletionStage, Function).

      final CompletableFuture<String> future = failed(new RuntimeException());
      final Function<Throwable, CompletionStage<String>> recoverFunction = e -> delayedResult("hi");
      final CompletableFuture<String> recoveredFuture = recoverWith(future, recoverFunction);
      final String actual = recoveredFuture.join();
      assertThat(actual).isEqualTo("hi");
      

      See the test code.

      Type Parameters:
      T - type of the value of the future
      Parameters:
      future - future which may completes exceptionally
      f - function how the exception should be handled to create a successfully completed future
      Returns:
      a future which can be recovered from errors
    • recoverWith

      public static <T> CompletableFuture<T> recoverWith(CompletionStage<T> future, Function<? super Throwable,CompletionStage<T>> f, Executor executor)

      Creates a CompletionStage which can be recovered if an error occurs by executing a function in a certain thread pool. If the recovery does not require to create a CompletionStage then use recover(CompletionStage, Function).

      Have a look at recoverWith(CompletionStage, Function) for an example without the thread pool.

      Type Parameters:
      T - type of the value of the future
      Parameters:
      future - future which may completes exceptionally
      f - function how the exception should be handled to create a successfully completed future
      executor - thread pool to execute the recover function
      Returns:
      a future which may recovered from errors
    • orElseThrow

      public static <T, X extends Throwable> T orElseThrow(CompletionStage<T> stage, Supplier<? extends X> exceptionSupplier) throws X

      Tries to access the completed future if available and returns its value (or exception in case the future completed exceptionally), otherwise throws the given exception.

      final CompletableFuture<String> incompleteFuture = new CompletableFuture<>();
      
      final Throwable throwable = catchThrowable(() -> {
          final String s = CompletableFutureUtils.orElseThrow(incompleteFuture,
              () -> new RuntimeException("I don't want to wait anymore and throw an exception"));
      });
      
      assertThat(throwable).isInstanceOf(RuntimeException.class)
              .hasMessage("I don't want to wait anymore and throw an exception");
      

      See the test code.

      Type Parameters:
      T - the type of the future value
      X - the type of the exception to be thrown if the value is absent
      Parameters:
      stage - the future
      exceptionSupplier - code which should be executed if the future is not yet completed (either successfully or exceptionally)
      Returns:
      value
      Throws:
      X - exception in case the value is not available
    • orElseGet

      public static <T> T orElseGet(CompletionStage<T> stage, Supplier<T> other)

      Tries to access the completed future if available and returns its value (or exception in case the future completed exceptionally), otherwise uses the supplier to get a default value.

      final CompletableFuture<Integer> incompleteFuture = new CompletableFuture<>();
      final Integer result = CompletableFutureUtils.orElseGet(incompleteFuture, () -> 1 + 1);
      assertThat(result).isEqualTo(2);
      

      See the test code.

      Type Parameters:
      T - the type of the future value
      Parameters:
      stage - the future
      other - code which should be executed when the value is not available yet or the future completed exceptionally
      Returns:
      value
    • map

      public static <T, U> CompletionStage<U> map(CompletionStage<T> future, Function<? super T,? extends U> f)

      Applies a function to the successful result of a future. If the function needs to return a CompletionStage use flatMap(CompletionStage, Function) instead.

      final CompletionStage<String> future = successful("hello");
      final CompletionStage<Integer> result = map(future, s -> s.length());
      assertThat(result.toCompletableFuture().join()).isEqualTo(5);
      

      See the test code.

      Type Parameters:
      T - type of value of the future
      U - type of the value of the returned future which is also the return type of f
      Parameters:
      future - the future to map
      f - function which should be applied if the future completes successfully
      Returns:
      a new future which contains either the exception from the original future or as value the result of application of f to the value of the original future.
    • flatMap

      public static <T, U> CompletionStage<U> flatMap(CompletionStage<T> future, Function<? super T,CompletionStage<U>> f)

      Applies a function to the successful result of a future. If the function does not to return a CompletionStage use map(CompletionStage, Function) instead.

      final CompletionStage<String> future = successful("hello");
      final Function<String, CompletionStage<Integer>> f = s -> successful(s.length());
      final CompletionStage<Integer> result = flatMap(future, f);
      assertThat(result.toCompletableFuture().join()).isEqualTo(5);
      

      See the test code.

      Type Parameters:
      T - type of value of the future
      U - type of the value of the returned future which is also the return type of f
      Parameters:
      future - the future to map
      f - function which should be applied if the future completes successfully
      Returns:
      a new future which contains either the exception from the original future or as value the result of application of f to the value of the original future.
    • listOfFuturesToFutureOfList

      public static <T> CompletableFuture<List<T>> listOfFuturesToFutureOfList(List<? extends CompletionStage<T>> list)

      Transforms a list of CompletionStage into a CompletionStage of a list, that will be completed once all the elements of the given list are completed. In case multiple stages end exceptionally only one error is kept.

      Alias of sequence(List).

      final CompletableFuture<Integer> two = delayedResult(2);
      final List<CompletableFuture<Integer>> completableFutures = asList(successful(1), two, successful(3));
      final CompletionStage<List<Integer>> sequence = CompletableFutureUtils.sequence(completableFutures);
      final List<Integer> actual = sequence.toCompletableFuture().join();
      assertThat(actual).isEqualTo(asList(1, 2, 3));
      

      See the test code.

      final RuntimeException exception = new RuntimeException("failed");
      final List<CompletableFuture<Integer>> completableFutures = asList(delayedResult(1), failed(exception),
          successful(3));
      final CompletableFuture<List<Integer>> sequence = CompletableFutureUtils.sequence(completableFutures);
      assertThatThrownBy(() -> sequence.join()).hasCause(exception);
      

      See the test code.

      Type Parameters:
      T - the element obtained from the list of CompletionStage
      Parameters:
      list - list of CompletionStage
      Returns:
      the CompletableFuture of a list of elements
    • sequence

      public static <T> CompletableFuture<List<T>> sequence(List<? extends CompletionStage<T>> list)

      Transforms a list of CompletionStage into a CompletionStage of a list, that will be completed once all the elements of the given list are completed. In case multiple stages end exceptionally only one error is kept.

      Alias of listOfFuturesToFutureOfList(List).

      final CompletableFuture<Integer> two = delayedResult(2);
      final List<CompletableFuture<Integer>> completableFutures = asList(successful(1), two, successful(3));
      final CompletionStage<List<Integer>> sequence = CompletableFutureUtils.sequence(completableFutures);
      final List<Integer> actual = sequence.toCompletableFuture().join();
      assertThat(actual).isEqualTo(asList(1, 2, 3));
      

      See the test code.

      final RuntimeException exception = new RuntimeException("failed");
      final List<CompletableFuture<Integer>> completableFutures = asList(delayedResult(1), failed(exception),
          successful(3));
      final CompletableFuture<List<Integer>> sequence = CompletableFutureUtils.sequence(completableFutures);
      assertThatThrownBy(() -> sequence.join()).hasCause(exception);
      

      See the test code.

      Type Parameters:
      T - the element obtained from the list of CompletionStage
      Parameters:
      list - list of CompletionStage
      Returns:
      the CompletableFuture of a list of elements