Combining Mono boolean results

Viewed 1785

I have these two methods which call an async API and return a Mono<Boolean> if a value exists. I am returning a random boolean value for the sake of this example,

private Mono<Boolean> checkFirstExists() {
  // Replacing actual API call here
  return Mono.just(Boolean.FALSE);
}

private Mono<Boolean> checkSecondExists() {
  // Replacing actual API call here
  return Mono.just(Boolean.TRUE);
}

Now, I have another method that should combine the results of these two methods and simply return a boolean if either checkFirstExists or checkSecondExists is true.

private boolean checkIfExists() {
  // Should return true if any of the underlying method returns true
  final Flux<Boolean> exists = Flux.concat(checkFirstExists(), checkSecondExists());
  return exists.blockFirst();
}

What's the best way of doing this? Mono.zip maybe? Any help would be great.

1 Answers

Mono.zip is the correct approach for awaiting completion of multiple async operations before continuing. Something like this should work:

    return Mono.zip(checkFirstExists(), checkSecondExists(), (first, second) -> first && second);

Or if a list is provided instead:

    private boolean checkIfExists()
    {
        return allTrue(Arrays.asList(checkFirstExists(), checkSecondExists())).blockOptional().orElseThrow(() -> new IllegalStateException("Invalid State")); 
    }

    private Mono<Boolean> allTrue(List<Mono<Boolean>> toAggregate) 
    {
        return mergeMonos(toAggregate).map(list -> list.stream().allMatch(val -> val)); 
    }

    @SuppressWarnings("unchecked")
    private <T> Mono<List<T>> mergeMonos(List<Mono<T>> toAggregate) 
    {
        return Mono.zip(toAggregate, array -> Stream.of(array).map(o -> (T) o).collect(Collectors.toList())); 
    }

Unrelated Note:

In general, it is worth keeping the operation async as long as possible when constructing reactive flows. It may be worth having the 'checkIfExists' function return a Mono instead of blocking.

Related