default void orElseRun(Consumer<? super Throwable> action) { Objects.requireNonNull(action, "action is null"); if (isFailure()) { action.accept(getCause()); } }
default <X extends Throwable> T getOrElseThrow(Function<? super Throwable, X> exceptionProvider) throws X { Objects.requireNonNull(exceptionProvider, "exceptionProvider is null"); if (isFailure()) { throw exceptionProvider.apply(getCause()); } else { return get(); } }
default T getOrElseGet(Function<? super Throwable, ? extends T> other) { Objects.requireNonNull(other, "other is null"); if (isFailure()) { return other.apply(getCause()); } else { return get(); } }
/** * Folds either the {@code Failure} or the {@code Success} side of the Try value. * * @param ifFail maps the left value if this is a {@code Failure} * @param f maps the value if this is a {@code Success} * @param <X> type of the folded value * @return A value of type X */ default <X> X fold(Function<? super Throwable, ? extends X> ifFail, Function<? super T, ? extends X> f) { if (isFailure()) { return ifFail.apply(getCause()); } else { return f.apply(get()); } }
/** * Returns {@code Success(throwable)} if this is a {@code Failure(throwable)}, otherwise * a {@code Failure(new NoSuchElementException("Success.failed()"))} if this is a Success. * * @return a new Try */ default Try<Throwable> failed() { if (isFailure()) { return new Success<>(getCause()); } else { return new Failure<>(new NoSuchElementException("Success.failed()")); } }
/** * Checks if this Future completed with a failure. * * @return true, if this Future completed and is a Failure, false otherwise. */ default boolean isFailure() { return isCompleted() && getValue().get().isFailure(); }
/** * Converts this {@code Try} to an {@link Either}. * * @return A new {@code Either} */ default Either<Throwable, T> toEither() { if (isFailure()) { return Either.left(getCause()); } else { return Either.right(get()); } }
@Test public void shouldDecorateConsumerAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When Consumer<String> consumer = Bulkhead.decorateConsumer(bulkhead, (value) -> {throw new RuntimeException("BAM!");}); Try<Void> result = Try.run(() -> consumer.accept("Tom")); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateCheckedRunnableAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When CheckedRunnable checkedRunnable = Bulkhead.decorateCheckedRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try<Void> result = Try.run(checkedRunnable); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateRunnableAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When Runnable runnable = Bulkhead.decorateRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try<Void> result = Try.run(runnable::run); //Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateCheckedConsumerAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); // When CheckedConsumer<String> checkedConsumer = Bulkhead.decorateCheckedConsumer(bulkhead, (value) -> { throw new RuntimeException("BAM!"); }); Try<Void> result = Try.run(() -> checkedConsumer.accept("Tom")); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void decorateConsumer() throws Exception { Consumer<Integer> consumer = mock(Consumer.class); Consumer<Integer> decorated = RateLimiter.decorateConsumer(limit, consumer); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(false); Try<Integer> decoratedConsumerResult = Try.success(1).andThen(decorated); then(decoratedConsumerResult.isFailure()).isTrue(); then(decoratedConsumerResult.getCause()).isInstanceOf(RequestNotPermitted.class); verify(consumer, never()).accept(any()); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(true); Try secondConsumerResult = Try.success(1).andThen(decorated); then(secondConsumerResult.isSuccess()).isTrue(); verify(consumer, times(1)).accept(1); }
@Test public void decorateFunction() throws Exception { Function<Integer, String> function = mock(Function.class); Function<Integer, String> decorated = RateLimiter.decorateFunction(limit, function); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(false); Try<String> decoratedFunctionResult = Try.success(1).map(decorated); then(decoratedFunctionResult.isFailure()).isTrue(); then(decoratedFunctionResult.getCause()).isInstanceOf(RequestNotPermitted.class); verify(function, never()).apply(any()); when(limit.getPermission(config.getTimeoutDuration())) .thenReturn(true); Try secondFunctionResult = Try.success(1).map(decorated); then(secondFunctionResult.isSuccess()).isTrue(); verify(function, times(1)).apply(1); }
@Test public void shouldDecorateFunctionAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithName("Tom")).willThrow(new RuntimeException("BAM!")); // When Function<String, String> function = Bulkhead.decorateFunction(bulkhead, helloWorldService::returnHelloWorldWithName); Try<String> result = Try.of(() -> function.apply("Tom")); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateSupplierAndReturnWithException() throws Throwable { BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new RuntimeException("BAM!")); // And measure the call with a Timer Supplier<String> supplier = Timer.decorateSupplier(timer, helloWorldService::returnHelloWorld); Try<String> result = Try.of(supplier::get); assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(timer.getMetrics().getNumberOfTotalCalls()).isEqualTo(1); assertThat(timer.getMetrics().getNumberOfSuccessfulCalls()).isEqualTo(0); assertThat(timer.getMetrics().getNumberOfFailedCalls()).isEqualTo(1); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorld(); }
@Test public void shouldDecorateCheckedFunctionAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithNameWithException("Tom")).willThrow(new RuntimeException("BAM!")); // When CheckedFunction1<String, String> function = Bulkhead.decorateCheckedFunction(bulkhead, helloWorldService::returnHelloWorldWithNameWithException); Try<String> result = Try.of(() -> function.apply("Tom")); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }
@Test public void shouldDecorateSupplierAndReturnWithException() { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new RuntimeException("BAM!")); // When Supplier<String> supplier = Bulkhead.decorateSupplier(bulkhead, helloWorldService::returnHelloWorld); Try<String> result = Try.of(supplier::get); //Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorld(); }
@Test public void shouldDecorateCallableAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willThrow(new RuntimeException("BAM!")); // When Callable<String> callable = Bulkhead.decorateCallable(bulkhead, helloWorldService::returnHelloWorldWithException); Try<String> result = Try.of(callable::call); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorldWithException(); }
@Test public void shouldDecorateCheckedSupplierAndReturnWithException() throws Throwable { // Given Bulkhead bulkhead = Bulkhead.of("test", config); BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willThrow(new RuntimeException("BAM!")); // When CheckedFunction0<String> checkedSupplier = Bulkhead.decorateCheckedSupplier(bulkhead, helloWorldService::returnHelloWorldWithException); Try<String> result = Try.of(checkedSupplier); // Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); BDDMockito.then(helloWorldService).should(times(1)).returnHelloWorldWithException(); }
@Test public void shouldReturnFailureWithRuntimeException() { // Given BulkheadConfig config = BulkheadConfig.custom().maxConcurrentCalls(2).build(); Bulkhead bulkhead = Bulkhead.of("test", config); bulkhead.isCallPermitted(); //v When CheckedRunnable checkedRunnable = Bulkhead.decorateCheckedRunnable(bulkhead, () -> {throw new RuntimeException("BAM!");}); Try result = Try.run(checkedRunnable); //Then assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(bulkhead.getMetrics().getAvailableConcurrentCalls()).isEqualTo(1); }