public DecorateCheckedSupplier<T> withRetry(Retry retryContext) { supplier = Retry.decorateCheckedSupplier(retryContext, supplier); return this; }
@Test public void shouldReturnAfterThreeAttemptsAndRecover() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")); // Create a Retry with default configuration Retry retry = Retry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier).recover((throwable) -> "Hello world from recovery function"); assertThat(retry.getMetrics().getNumberOfFailedCallsWithRetryAttempt()).isEqualTo(1); // Then the helloWorldService should be invoked 3 times BDDMockito.then(helloWorldService).should(Mockito.times(3)).returnHelloWorld(); // and the returned exception should be of type RuntimeException assertThat(result.get()).isEqualTo("Hello world from recovery function"); assertThat(sleptTime).isEqualTo(RetryConfig.DEFAULT_WAIT_DURATION * 2); }
@Test public void shouldReturnAfterThreeAttempts() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")); // Create a Retry with default configuration Retry retry = Retry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier); // Then the helloWorldService should be invoked 3 times BDDMockito.then(helloWorldService).should(Mockito.times(3)).returnHelloWorld(); // and the result should be a failure assertThat(result.isFailure()).isTrue(); // and the returned exception should be of type RuntimeException assertThat(result.failed().get()).isInstanceOf(WebServiceException.class); assertThat(sleptTime).isEqualTo(RetryConfig.DEFAULT_WAIT_DURATION * 2); }
@Test public void shouldReturnSuccessfullyAfterSecondAttempt() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")) .willReturn("Hello world"); // Create a Retry with default configuration Retry retry = Retry.ofDefaults("id"); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier); // Then the helloWorldService should be invoked 2 times BDDMockito.then(helloWorldService).should(Mockito.times(2)).returnHelloWorld(); assertThat(result.get()).isEqualTo("Hello world"); assertThat(sleptTime).isEqualTo(RetryConfig.DEFAULT_WAIT_DURATION); }
@Test public void shouldReturnAfterOneAttempt() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")); // Create a Retry with custom configuration RetryConfig config = RetryConfig.custom().maxAttempts(1).build(); Retry retry = Retry.of("id", config); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier); // Then the helloWorldService should be invoked 1 time BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld(); // and the result should be a failure assertThat(result.isFailure()).isTrue(); // and the returned exception should be of type RuntimeException assertThat(result.failed().get()).isInstanceOf(WebServiceException.class); assertThat(sleptTime).isEqualTo(0); }
@Test public void shouldReturnAfterThreeAttemptsAndRecoverWithResult() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")) .willReturn("Hello world") .willThrow(new WebServiceException("BAM!")); // Create a Retry with default configuration final RetryConfig tryAgain = RetryConfig.<String>custom().retryOnResult(s -> s.contains("Hello world")) .maxAttempts(3).build(); Retry retry = Retry.of("id", tryAgain); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier).recover((throwable) -> "Hello world from recovery function"); // Then the helloWorldService should be invoked 3 times BDDMockito.then(helloWorldService).should(Mockito.times(3)).returnHelloWorld(); // and the returned exception should be of type RuntimeException assertThat(result.get()).isEqualTo("Hello world from recovery function"); assertThat(sleptTime).isEqualTo(RetryConfig.DEFAULT_WAIT_DURATION * 2); }
@Test public void shouldTakeIntoAccountBackoffFunction() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")); // Create a Retry with a backoff function doubling the interval RetryConfig config = RetryConfig.custom().intervalFunction(IntervalFunction.ofExponentialBackoff(500, 2.0)) .build(); Retry retry = Retry.of("id", config); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier); // Then the slept time should be according to the backoff function BDDMockito.then(helloWorldService).should(Mockito.times(3)).returnHelloWorld(); assertThat(sleptTime).isEqualTo( RetryConfig.DEFAULT_WAIT_DURATION + RetryConfig.DEFAULT_WAIT_DURATION * 2); } }
@Test public void shouldReturnAfterOneAttemptAndIgnoreException() { // Given the HelloWorldService throws an exception BDDMockito.given(helloWorldService.returnHelloWorld()).willThrow(new WebServiceException("BAM!")); // Create a Retry with default configuration RetryConfig config = RetryConfig.custom() .retryOnException(throwable -> API.Match(throwable).of( API.Case($(Predicates.instanceOf(WebServiceException.class)), false), API.Case($(), true))) .build(); Retry retry = Retry.of("id", config); // Decorate the invocation of the HelloWorldService CheckedFunction0<String> retryableSupplier = Retry .decorateCheckedSupplier(retry, helloWorldService::returnHelloWorld); // When Try<String> result = Try.of(retryableSupplier); // Then the helloWorldService should be invoked only once, because the exception should be rethrown immediately. BDDMockito.then(helloWorldService).should(Mockito.times(1)).returnHelloWorld(); // and the result should be a failure assertThat(result.isFailure()).isTrue(); // and the returned exception should be of type RuntimeException assertThat(result.failed().get()).isInstanceOf(WebServiceException.class); assertThat(sleptTime).isEqualTo(0); }