public DecorateCompletionStage<T> withRetry(AsyncRetry retryContext, ScheduledExecutorService scheduler) { stageSupplier = AsyncRetry.decorateCompletionStage(retryContext, scheduler, stageSupplier); return this; }
/** * Decorates and executes the decorated CompletionStage. * @param scheduler execution service to use to schedule retries * @param supplier the original CompletionStage * @param <T> the type of results supplied by this supplier * @return the decorated CompletionStage. */ default <T> CompletionStage<T> executeCompletionStage( ScheduledExecutorService scheduler, Supplier<CompletionStage<T>> supplier){ return decorateCompletionStage(this, scheduler, supplier).get(); }
@Test public void shouldRetryInCaseOfAnExceptionAtAsyncStage() { CompletableFuture<String> failedFuture = new CompletableFuture<>(); failedFuture.completeExceptionally(new WebServiceException("BAM!")); // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(failedFuture) .willReturn(completedFuture("Hello world")); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When String result = awaitResult(supplier.get()); // Then the helloWorldService should be invoked 2 times BDDMockito.then(helloWorldService).should(Mockito.times(2)).returnHelloWorld(); Assertions.assertThat(result).isEqualTo("Hello world"); }
@Test public void shouldNotRetry() throws InterruptedException, ExecutionException, TimeoutException { // Given the HelloWorldService returns Hello world BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(completedFuture("Hello world")); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When String result = awaitResult(supplier); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld(); Assertions.assertThat(result).isEqualTo("Hello world"); }
@Test public void shouldRegisterMetricsWithRetry() { //Given AsyncRetryRegistry retryRegistry = AsyncRetryRegistry.ofDefaults(); AsyncRetry retry = retryRegistry.retry("testName"); metricRegistry.registerAll(AsyncRetryMetrics.ofAsyncRetryRegistry(retryRegistry)); // Given the HelloWorldService returns Hello world BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(failedFuture(new WebServiceException("BAM!"))) .willReturn(CompletableFuture.completedFuture("Hello world")) .willReturn(failedFuture(new WebServiceException("BAM!"))) .willReturn(failedFuture(new WebServiceException("BAM!"))) .willReturn(failedFuture(new WebServiceException("BAM!"))); // Setup circuitbreaker with retry String value1 = awaitResult(retry.executeCompletionStage(scheduler, helloWorldService::returnHelloWorld)); Try.ofCallable(() -> awaitResult(AsyncRetry.decorateCompletionStage(retry, scheduler, helloWorldService::returnHelloWorld).get())); //Then assertThat(value1).isEqualTo("Hello world"); // Then the helloWorldService should be invoked 5 times BDDMockito.then(helloWorldService).should(times(5)).returnHelloWorld(); assertThat(metricRegistry.getMetrics()).hasSize(4); assertThat(metricRegistry.getGauges().get("resilience4j.retry.testName." + SUCCESSFUL_CALLS_WITH_RETRY).getValue()).isEqualTo(1L); assertThat(metricRegistry.getGauges().get("resilience4j.retry.testName." + SUCCESSFUL_CALLS_WITHOUT_RETRY).getValue()).isEqualTo(0L); assertThat(metricRegistry.getGauges().get("resilience4j.retry.testName." + FAILED_CALLS_WITH_RETRY).getValue()).isEqualTo(1L); assertThat(metricRegistry.getGauges().get("resilience4j.retry.testName." + FAILED_CALLS_WITHOUT_RETRY).getValue()).isEqualTo(0L); }
@Test public void shouldRetryInCaseOfExceptionAtSyncStage() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()) .willThrow(new WebServiceException("BAM!")) .willReturn(completedFuture("Hello world")); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When String result = awaitResult(supplier.get()); // Then the helloWorldService should be invoked 2 times BDDMockito.then(helloWorldService).should(Mockito.times(2)).returnHelloWorld(); Assertions.assertThat(result).isEqualTo("Hello world"); }
private void shouldCompleteFutureAfterAttemptsInCaseOfExceptionAtAsyncStage(int noOfAttempts) { CompletableFuture<String> failedFuture = new CompletableFuture<>(); failedFuture.completeExceptionally(new WebServiceException("BAM!")); // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(failedFuture); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.of( "id", RetryConfig .custom() .maxAttempts(noOfAttempts) .build()); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When Try<String> resultTry = Try.of(() -> awaitResult(supplier.get())); // Then the helloWorldService should be invoked n + 1 times BDDMockito.then(helloWorldService).should(Mockito.times(noOfAttempts)).returnHelloWorld(); Assertions.assertThat(resultTry.isFailure()).isTrue(); Assertions.assertThat(resultTry.getCause().getCause()).isInstanceOf(WebServiceException.class); }
private void shouldCompleteFutureAfterAttemptsInCaseOfExceptionAtSyncStage(int noOfAttempts) { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()) .willThrow(new WebServiceException("BAM!")); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.of( "id", RetryConfig .custom() .maxAttempts(noOfAttempts) .build()); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When Try<String> resultTry = Try.of(() -> awaitResult(supplier.get())); // Then the helloWorldService should be invoked n + 1 times BDDMockito.then(helloWorldService).should(Mockito.times(noOfAttempts)).returnHelloWorld(); Assertions.assertThat(resultTry.isFailure()).isTrue(); Assertions.assertThat(resultTry.getCause().getCause()).isInstanceOf(WebServiceException.class); }
@Test public void shouldNotRetryWithThatResult() throws InterruptedException, ExecutionException, TimeoutException { // Given the HelloWorldService returns Hello world BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(completedFuture("Hello world")); // Create a Retry with default configuration final RetryConfig retryConfig = RetryConfig.<String>custom().retryOnResult(s -> s.contains("NoRetry")) .maxAttempts(1) .build(); AsyncRetry retryContext = AsyncRetry.of("id", retryConfig); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When String result = awaitResult(supplier); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld(); Assertions.assertThat(result).isEqualTo("Hello world"); // for code quality scan , it does not not recognize assertJ do not why Assert.assertEquals(result, "Hello world"); }
private void shouldCompleteFutureAfterAttemptsInCaseOfRetyOnResultAtAsyncStage(int noOfAttempts, String retryResponse) { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()) .willReturn(completedFuture("Hello world")); // Create a Retry with default configuration AsyncRetry retryContext = AsyncRetry.of( "id", RetryConfig .<String>custom() .maxAttempts(noOfAttempts) .retryOnResult(s -> s.contains(retryResponse)) .build()); // Decorate the invocation of the HelloWorldService Supplier<CompletionStage<String>> supplier = AsyncRetry.decorateCompletionStage( retryContext, scheduler, () -> helloWorldService.returnHelloWorld()); // When Try<String> resultTry = Try.of(() -> awaitResult(supplier.get())); // Then the helloWorldService should be invoked n + 1 times BDDMockito.then(helloWorldService).should(Mockito.times(noOfAttempts)).returnHelloWorld(); Assert.assertTrue(resultTry.isSuccess()); }