Search code examples
javaspringspring-bootspring-retry

How to get the label specified in spring retryable annotation at class level in a MethodInvocationRetryListenerSupport?


I have specified a @Retryable annotation in a spring bean like below.

@EnableRetry
@Import({GrpcClientRetryConfig.class})
@Retryable(interceptor = "grpcClientRetryInterceptor", label = "ProfileGrpcClient")
public class ProfileGrpcClient {
  public RateLimitConfig getRateLimitConfig()

@Component
@AllArgsConstructor
public class RateLimits {
  private final ProfileGrpcClient client;

  // Some method calls client.getRateLimitConfig()
}

Interceptor is defined in GrpcClientRetryConfig

@EnableRetry
public class GrpcClientRetryConfig {
 @Bean
 public RetryOperationsInterceptor grpcClientRetryInterceptor() {
    val template = new RetryTemplate();
    val backOffPolicy = new ExponentialBackOffPolicy();
    // Set the exponential backoff parameter
    val interceptor = new RetryOperationsInterceptor();
    template.setRetryPolicy(new SimpleRetryPolicy());
    template.setBackOffPolicy(backOffPolicy);
    template.setListeners(new GrpcClientRetryListener[] {new GrpcClientRetryListener()});
    interceptor.setRetryOperations(template);
    return interceptor;
 }
}

In GrpcClientRetryListener I am trying to get the label specified in the @Retryable

@Slf4j
@Component
public class GrpcClientRetryListener extends MethodInvocationRetryListenerSupport {

  @Override
  public <T, E extends Throwable> void onSuccess(
      RetryContext context, RetryCallback<T, E> callback, T result) {
    if (callback instanceof MethodInvocationRetryCallback<T, E> methodInvocationRetryCallback) {
      log.info(
          "Retry Succeeded: {}, Count: {}",
          getMethodName(methodInvocationRetryCallback),
          context.getRetryCount());
    }
    super.onSuccess(context, callback, result);
  }

  @Override
  public <T, E extends Throwable> void onError(
      RetryContext context, RetryCallback<T, E> callback, Throwable throwable) {
    if (callback instanceof MethodInvocationRetryCallback<T, E> methodInvocationRetryCallback) {
      log.info(
          "Retry Failing: {}, Count: {}",
          getMethodName(methodInvocationRetryCallback),
          context.getRetryCount());
    }
    super.onError(context, callback, throwable);
  }

  private <T, E extends Throwable> String getMethodName(
      MethodInvocationRetryCallback<T, E> methodInvocationRetryCallback) {
    return methodInvocationRetryCallback.getLabel();
  }
}

But during retry, I am seeing getting the label like public com.abc.proto.v2.common.ratelimit.RateLimits com.abc.grpcclients.ProfileGrpcClient.getRateLimitConfig(). Complete log is like below

Retry Failing: public com.abc.proto.v2.common.ratelimit.RateLimits com.abc.grpcclients.ProfileGrpcClient.getRateLimitConfig(), Count: 5

Is there a way for me to get the label as specified in @Retryable in MethodInvocationRetryListenerSupport?


Solution

  • See @Retryable(interceptor) Javadocs:

    /**
     * Retry interceptor bean name to be applied for retryable method. Is mutually
     * exclusive with other attributes.
     * @return the retry interceptor bean name
     */
    String interceptor() default "";
    

    So, if you specify an interceptor, all other annotation attributes are ignored.

    Since you provide your own RetryOperationsInterceptor, see its respective setLabel(String label) property.