/* * * Copyright 2019 Mahmoud Romeh * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. * * */ package io.github.resilience4j.feign; import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder; import com.github.tomakehurst.wiremock.junit.WireMockRule; import feign.FeignException; import io.github.resilience4j.feign.test.TestService; import io.github.resilience4j.ratelimiter.RateLimiterConfig; import io.github.resilience4j.ratelimiter.RequestNotPermitted; import io.github.resilience4j.retry.Retry; import io.github.resilience4j.retry.RetryConfig; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import static com.github.tomakehurst.wiremock.client.WireMock.*; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; /** * Tests the integration of the {@link Resilience4jFeign} with {@link Retry} */ public class Resilience4jFeignRetryTest { private static final String MOCK_URL = "http://localhost:8080/"; @Rule public WireMockRule wireMockRule = new WireMockRule(); private TestService testService; private Retry retry; @Before public void setUp() { retry = Retry.ofDefaults("test"); final FeignDecorators decorators = FeignDecorators.builder() .withRetry(retry) .build(); testService = Resilience4jFeign.builder(decorators) .target(TestService.class, MOCK_URL); } @Test public void testSuccessfulCall() { givenResponse(200); testService.greeting(); verify(1, getRequestedFor(urlPathEqualTo("/greeting"))); } @Test(expected = FeignException.class) public void testFailedHttpCall() { givenResponse(400); testService.greeting(); } @Test(expected = FeignException.class) public void testFailedHttpCallWithRetry() { retry = Retry.of("test",RetryConfig.custom().retryExceptions(FeignException.class).maxAttempts(2).build()); final FeignDecorators decorators = FeignDecorators.builder() .withRetry(retry) .build(); testService = Resilience4jFeign.builder(decorators) .target(TestService.class, MOCK_URL); givenResponse(400); testService.greeting(); assertThat(retry.getMetrics().getNumberOfFailedCallsWithRetryAttempt()).isEqualTo(2); } @Test public void testRetryOnResult() { retry = Retry.of("test",RetryConfig.<String>custom().retryOnResult(s->s.equalsIgnoreCase("hello world")).maxAttempts(2).build()); final FeignDecorators decorators = FeignDecorators.builder() .withRetry(retry) .build(); testService = Resilience4jFeign.builder(decorators) .target(TestService.class, MOCK_URL); givenResponse(200); testService.greeting(); assertThat(retry.getMetrics().getNumberOfFailedCallsWithRetryAttempt()).isEqualTo(1); } private void givenResponse(int responseCode) { stubFor(get(urlPathEqualTo("/greeting")) .willReturn(aResponse() .withStatus(responseCode) .withHeader("Content-Type", "text/plain") .withBody("hello world"))); } }