How to get status for circuit breaker status with netflix hystrix?

1.3k views Asked by At

This is my AppService Class, where I need to add logic for getting the status for the circuit breaker if it's open or closed but I am unable to find a way. Also, i have made use of ignoreExceptions but seems like trouble is there. Just new to coding and this feature and unable to get an appropriate answer. I am not sure how to use isCircuitBreakerOpen().

@Service
public class AppService {

    private static final Logger LOG = LoggerFactory.getLogger(AppService.class);
    private final RestTemplate restTemplate;

    public AppService(RestTemplate rest) {
        this.restTemplate = rest;
    }
    
    
    
    @HystrixCommand(fallbackMethod = "reliable", commandProperties= {
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "100"),
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "10000"),
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10")
            })
            public ResponseEntity<String> answerList() throws Exception {
                return callingDownStreamService404();
                }

    @HystrixCommand(fallbackMethod = "reliable", commandProperties= {
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "100"),
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "10000"),
            @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10")
        })
    public ResponseEntity<String> answerList503() throws Exception {
                return callingDownStreamService503();
                }
    
    
                private ResponseEntity<String> callingDownStreamService404() throws Exception {
                    URI uri = URI.create("http://localhost:8090/recommended/404");

                    RestTemplate restTemplate = new RestTemplate();
                    HttpHeaders headers = new HttpHeaders();
                    HttpEntity<Object> entity = new HttpEntity<Object>(headers);

                    ResponseEntity<String> out = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
                    System.out.println("Application code : " + out.getStatusCode());
                    return out;

                }

                private ResponseEntity<String> callingDownStreamService503() throws Exception {
                    URI uri = URI.create("http://localhost:8090/recommended/503");

                    RestTemplate restTemplate = new RestTemplate();
                    HttpHeaders headers = new HttpHeaders();
                    HttpEntity<Object> entity = new HttpEntity<Object>(headers);

                    ResponseEntity<String> out = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
                    System.out.println("Application code : " + out.getStatusCode());

                    if (out.getStatusCode().toString().startsWith("5")) {
                        throw new HystrixBadRequestException("bad request messageg");
                    }

                    return out;

                }

                @HystrixCommand(commandKey = "MyHystrixCommand",fallbackMethod = "myHystrixFallback", threadPoolKey = "ThreadPoolKey",commandProperties= {
                      @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "100"),
                      @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "10000"),
                      @HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "10")},
                    ignoreExceptions = {HttpServerErrorException.class, HystrixBadRequestException.class, HttpClientErrorException.class})
                
                public ResponseEntity<String> getServiceCallResponse(String serviceUrl, HttpEntity<?> entity) {
                     serviceUrl = "http://localhost:8090/recommended/500";
                    
                    ResponseEntity<String> resp = null;
                    
                    try {
                        System.out.println("Calling -----" + serviceUrl);
                        resp = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, String.class);
                        
                        }
                    catch(RestClientException e) {
                        System.out.println("Calling -----" + serviceUrl + "Exception is this" + e.getRootCause());
                        handleExceptionForHystrix("getServiceCallResponse", e);
                    }
                    return resp;
                    }

                    private void handleExceptionForHystrix(String function, Exception e) {
                            if (e instanceof HttpStatusCodeException) {
                                HttpStatus httpStatusCode = ((HttpStatusCodeException)e).getStatusCode();
                                if(httpStatusCode.equals(HttpStatus.BAD_REQUEST) || httpStatusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
                                    throw new HystrixBadRequestException("Hystrix Bad Request Exception Occurred" + httpStatusCode, e);
                                }
                                throw new RuntimeException(function, e);
                            }
                            throw new RuntimeException(function, e);
                        }


                    public ResponseEntity<String> myHystrixFallback(String serviceUrl, HttpEntity<?> entity, Throwable hystrixCommandExp) {
                        
                                return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
                            }
                
                @Recover()
                public ResponseEntity<String> reliable() {
                    return new ResponseEntity<String>(
                            "The downstream application is unavailable and the circuit is open", HttpStatus.OK);
                }
                
                
            }

this is the main class where i have placed the endpoints. I am also making use of AppStore which is the downstream app and same enpoints are configured there.

@EnableHystrixDashboard
@EnableCircuitBreaker
@RestController
@SpringBootApplication
public class DavinciCircuitbreakerApplication {
    
      @Autowired
      private AppService appService;
      
      @Bean
      public RestTemplate rest(RestTemplateBuilder builder) {
      return builder.build();
      }

          
      @RequestMapping("/to-answer/404")
      public ResponseEntity<String> toAnswer() {
          ResponseEntity<String> response = null;
        try{
            response = appService.answerList();
        }catch(Exception e){
            System.out.println("excpetion"+ e.getMessage());
            return new ResponseEntity<String>("failure", HttpStatus.valueOf(500));
        }


      return response;
      }

    @RequestMapping("/to-answer/503")
    public ResponseEntity<String> toAnswer503() {
        ResponseEntity<String> response = null;
        try{
            response = appService.answerList503();
        }catch(Exception e){
            System.out.println("excpetion"+ e.getMessage());
            return new ResponseEntity<String>("failure", HttpStatus.valueOf(503));
        }


        return response;
    }
    
    @RequestMapping("/to-answer/500")
    public ResponseEntity<String> toAnswer500() {
        ResponseEntity<String> response = null;
        try{
            response = appService.getServiceCallResponse(null, response);
        }catch(Exception e){
            System.out.println("excpetion"+ e.getMessage());
            return new ResponseEntity<String>("Internal Server Error", HttpStatus.valueOf(500));
        }


    return response;
}

public static void main(String[] args) {
      SpringApplication.run(DavinciCircuitbreakerApplication.class, args);
    }

}

1

There are 1 answers

0
FlapPy On

You can use HystrixCircuitBreaker.Factory.getInstance(...) to get instance of HystrixCommand. Refer to link for more details.

Further you can call isCircuitBreakerOpen() on this HystrixCommand instance.