Merge pull request #11703 from mdabrowski-eu/BAEL-5301

BAEL-5301 Retrying Feign Calls
This commit is contained in:
doodoroma 2022-01-31 17:52:59 +01:00 committed by GitHub
commit 19d7034d42
4 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1,27 @@
package com.baeldung.feign.retry;
import feign.FeignException;
import feign.Response;
import feign.RetryableException;
import feign.codec.ErrorDecoder;
import static feign.FeignException.errorStatus;
public class Custom5xxErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
FeignException exception = errorStatus(methodKey, response);
int status = response.status();
if (status >= 500) {
return new RetryableException(
response.status(),
exception.getMessage(),
response.request().httpMethod(),
exception,
null,
response.request());
}
return exception;
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.feign.retry;
import feign.RetryableException;
import feign.Retryer;
public class NaiveRetryer implements feign.Retryer {
@Override
public void continueOrPropagate(RetryableException e) {
try {
Thread.sleep(1000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw e;
}
}
@Override
public Retryer clone() {
return new NaiveRetryer();
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.feign.retry;
import com.baeldung.feign.clients.BookClient;
import feign.Feign;
import feign.Logger;
import feign.Retryer;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
import feign.okhttp.OkHttpClient;
import feign.slf4j.Slf4jLogger;
import lombok.Getter;
import java.util.concurrent.TimeUnit;
@Getter
public class ResilientFeignClientBuilder {
public BookClient bookClient = createClient(BookClient.class, "http://localhost:8081/api/books");
public static <T> T createClient(Class<T> type, String uri) {
return Feign.builder()
.client(new OkHttpClient())
.encoder(new GsonEncoder())
.decoder(new GsonDecoder())
.retryer(new Retryer.Default(100L, TimeUnit.SECONDS.toMillis(3L), 5))
.errorDecoder(new Custom5xxErrorDecoder())
.target(type, uri);
}
}

View File

@ -0,0 +1,51 @@
package com.baeldung.feign.retry;
import feign.*;
import feign.codec.ErrorDecoder;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class Custom5xxErrorDecoderUnitTest {
@Test
public void given5xxResponse_whenDecode_thenReturnRetryableException() {
// given
ErrorDecoder decoder = new Custom5xxErrorDecoder();
Response response = responseStub(500);
// when
Exception exception = decoder.decode("GET", response);
// then
assertTrue(exception instanceof RetryableException);
}
@Test
public void given4xxResponse_whenDecode_thenReturnFeignException() {
// given
ErrorDecoder decoder = new Custom5xxErrorDecoder();
Response response = responseStub(400);
// when
Exception exception = decoder.decode("GET", response);
// then
assertTrue(exception instanceof FeignException);
assertFalse(exception instanceof RetryableException);
}
@NotNull
private Response responseStub(int status) {
return Response.builder()
.request(Request.create(
Request.HttpMethod.GET, "url", new HashMap<>(), new byte[0], Charset.defaultCharset(), new RequestTemplate()))
.status(status)
.build();
}
}