Merge pull request #11703 from mdabrowski-eu/BAEL-5301
BAEL-5301 Retrying Feign Calls
This commit is contained in:
commit
19d7034d42
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue