1

I have two services "product-service" and "rating-service". I am making a rest call from product-service to rating-service to get the data. I have written the Retry configuration in product-service and expecting whenever an exception raised from rating-service, product-service retry the rest call as per configuration. But it is not happening. Whenever an exception thrown from rating-service, product-service also throws the exception without retrying and also fallback. Please find below code of both the services. Check the code of the both services here.

product-service >> ProductServiceImpl.java

    @Retry(name = "rating-service", fallbackMethod = "getDefaultProductRating")
    public List<ProductRatingDTO> getProductRating(String id) {
        String reqRatingServiceUrl = ratingServiceUrl + "/" + id;
        log.info("Making a request to " + reqRatingServiceUrl + " at :" + LocalDateTime.now());
        ResponseEntity<List<ProductRatingDTO>> productRatingDTOListRE = restTemplate.exchange(reqRatingServiceUrl,
                HttpMethod.GET, null, new ParameterizedTypeReference<List<ProductRatingDTO>>() {
                });
        List<ProductRatingDTO> productRatingDTOList = productRatingDTOListRE.getBody();
        log.info("Retrieved rating for id {} are: {}", id, productRatingDTOList);
        return productRatingDTOList;
    }

    public List<ProductRatingDTO> getDefaultProductRating(String id, Exception ex) {
        log.warn("fallback method: " + ex.getMessage());
        return new ArrayList<>();
    }

product-service >> application.yml

resilience4j.retry:
  instances:
    rating-service:
      maxAttempts: 3
      waitDuration: 10s
      retryExceptions:
        - org.springframework.web.client.HttpServerErrorException
      ignoreExceptions:
        - java.lang.ArrayIndexOutOfBoundsException

rating-service >> RatingsServiceImpl.java

    @Override
    public List<RatingsDTO> getRatings(String productId) {
        log.info("Ratings required for product id: "+productId);
        List<RatingsDTO> ratingsDTOList = ratingsRepository.getRatingsByProductId(productId);
        log.info("Ratings fetched for product id {} are : {}",productId,ratingsDTOList);
        if (ThreadLocalRandom.current().nextInt(0,5) == 0){ // Erratic block
            log.error("Erratic");
            throw new org.springframework.web.client.HttpServerErrorException(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return ratingsDTOList;
    }

Please let me know where I am doing the mistake?

Rasool
  • 43
  • 1
  • 4
  • I didn't use Resilience4J that much myself but I'm not sure the retry can be directly added to the RestTemplate call. So if the rest call throws an exception so will your product service which then should be retried - if you set up Resilience4J correctly. Did you check your configuration is in the correct format? And how is `getProductRating()` called? If the product service directly calls this on the same instance the calling method is running in there'd not be any chance for an interceptor to chime in - so try to make the call to another service instance. – Thomas Feb 22 '22 at 07:02
  • @Thomas, Configuration is in correct format. `getProductRating()` is called from the controller of product-service. – Rasool Feb 22 '22 at 11:47
  • I have added the Github link of the code. Please check [here](https://github.com/Rasool-Ansari-Shaik/resilience4j-learn) – Rasool Feb 22 '22 at 12:22

0 Answers0