/** * Decorates and executes the decorated Callable. * * @param callable the original Callable * * @return the result of the decorated Callable. * @param <T> the result type of callable * @throws Exception if unable to compute a result */ default <T> T executeCallable(Callable<T> callable) throws Exception{ return decorateCallable(this, callable).call(); }
@Test public void shouldDecorateCallableAndReturnWithSuccess() throws Throwable { // Given CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults(); CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("testName"); CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics(); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(0); // Given the HelloWorldService returns Hello world BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willReturn("Hello world"); //When Callable<String> callable = CircuitBreaker.decorateCallable(circuitBreaker, helloWorldService::returnHelloWorldWithException); //Then assertThat(callable.call()).isEqualTo("Hello world"); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(1); assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(0); assertThat(metrics.getNumberOfSuccessfulCalls()).isEqualTo(1); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorldWithException(); }
@Test public void shouldDecorateCallableAndReturnWithException() throws Throwable { // Given CircuitBreakerRegistry circuitBreakerRegistry = CircuitBreakerRegistry.ofDefaults(); CircuitBreaker circuitBreaker = circuitBreakerRegistry.circuitBreaker("testName"); CircuitBreaker.Metrics metrics = circuitBreaker.getMetrics(); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(0); // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorldWithException()).willThrow(new RuntimeException("BAM!")); //When Callable<String> callable = CircuitBreaker.decorateCallable(circuitBreaker, helloWorldService::returnHelloWorldWithException); //Then Try<String> result = Try.of(callable::call); assertThat(result.isFailure()).isTrue(); assertThat(result.failed().get()).isInstanceOf(RuntimeException.class); assertThat(metrics.getNumberOfBufferedCalls()).isEqualTo(1); assertThat(metrics.getNumberOfFailedCalls()).isEqualTo(1); assertThat(metrics.getNumberOfSuccessfulCalls()).isEqualTo(0); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorldWithException(); }
@Override public <T> T run(Supplier<T> toRun) { TimeLimiter timeLimiter = TimeLimiter.of(timeLimiterConfig); Supplier<Future<T>> futureSupplier = () -> executorService.submit(toRun::get); Callable restrictedCall = TimeLimiter .decorateFutureSupplier(timeLimiter, futureSupplier); io.github.resilience4j.circuitbreaker.CircuitBreaker defaultCircuitBreaker = registry.circuitBreaker(id, circuitBreakerConfig); Callable<T> callable = io.github.resilience4j.circuitbreaker.CircuitBreaker .decorateCallable(defaultCircuitBreaker, restrictedCall); return Try.of(callable::call).get(); }
@Override public <T> T run(Supplier<T> toRun, Function<Throwable, T> fallback) { TimeLimiter timeLimiter = TimeLimiter.of(timeLimiterConfig); Supplier<Future<T>> futureSupplier = () -> executorService.submit(toRun::get); Callable restrictedCall = TimeLimiter .decorateFutureSupplier(timeLimiter, futureSupplier); io.github.resilience4j.circuitbreaker.CircuitBreaker defaultCircuitBreaker = registry.circuitBreaker(id, circuitBreakerConfig); Callable<T> callable = io.github.resilience4j.circuitbreaker.CircuitBreaker .decorateCallable(defaultCircuitBreaker, restrictedCall); return Try.of(callable::call).recover(fallback).get(); } }