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