Skip to content

Instantly share code, notes, and snippets.

@mhewedy
Last active May 4, 2024 00:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mhewedy/5a1b68f0a19edf6b4060e74cce3d0015 to your computer and use it in GitHub Desktop.
Save mhewedy/5a1b68f0a19edf6b4060e74cce3d0015 to your computer and use it in GitHub Desktop.
Annotation for feign retry
/**
* Enable retries on selected Feign methods.
* <p>
* <ol>
* <li>In the feign config class add:
* <pre>
* {@code
* @Bean
* public Retryer feignRetryer() {
* return new AnnotationRetryer(new Retryer.Default());
* }
* }
* </pre>
* </li>
* <li>Annotate feign method with @FeignRetryable:
* <pre>
* {@code
*
* @FeignRetryable
* @PostMapping("/api/url")
* ResponseDto callTheApi(@RequestBody RequestDto request);
* }
* </pre>
* </li>
* </ol>
* Now only the annotated methods will be retryable according to the delegate Retryer passed to {@link AnnotationRetryer},
* other methods will not be retryable.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface FeignRetryable {
class AnnotationRetryer implements Retryer {
private final Retryer delegate;
public AnnotationRetryer(Retryer delegate) {
this.delegate = delegate;
}
@Override
public void continueOrPropagate(RetryableException e) {
boolean hasAnnotation =
e.request().requestTemplate().methodMetadata().method().getAnnotation(FeignRetryable.class) != null;
if (hasAnnotation) {
delegate.continueOrPropagate(e);
} else {
throw e;
}
}
@Override
public Retryer clone() {
return new AnnotationRetryer(delegate.clone());
}
}
}
@Phlaxith
Copy link

Phlaxith commented Dec 5, 2023

Thanks for this gist, worked perfectly 👍

@mrmikopi
Copy link

mrmikopi commented Apr 30, 2024

Thanks for this solution

I'm using Feign Client with Java Annotations, like: @FeignClient(value="myClient", url="URL", configuration="MyConfig.class").
I've added the @Bean Retryer to MyConfig class and annotated the called method with @FeignRetryer interface.

When I debug this code, e.request().requestTemplate().methodMetadata().method().getAnnotation(FeignRetryable.class) doesn't bring the annotation that I've written to the client method.

Is this related with Spring AOP? Any solutions that you can think of?
EDIT: My bad, found out that a diffrent method was called. Spring AOP works normal.

@mhewedy
Copy link
Author

mhewedy commented May 4, 2024

Thanks for this solution

I'm using Feign Client with Java Annotations, like: @FeignClient(value="myClient", url="URL", configuration="MyConfig.class"). I've added the @Bean Retryer to MyConfig class and annotated the called method with @FeignRetryer interface.

When I debug this code, e.request().requestTemplate().methodMetadata().method().getAnnotation(FeignRetryable.class) doesn't bring the annotation that I've written to the client method.

Is this related with Spring AOP? Any solutions that you can think of? EDIT: My bad, found out that a diffrent method was called. Spring AOP works normal.

happy it worked with you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment