RateLimitersHealthIndicator implements HealthIndicator { @Override public Health health() { Map<String, Health> healths = rateLimiterRegistry.getAllRateLimiters().toJavaStream() .filter(this::isRegisterHealthIndicator) .collect(Collectors.toMap(RateLimiter::getName, this::mapRateLimiterHealth)); Status status = statusAggregator.getAggregateStatus(healths.values().stream().map(Health::getStatus).collect(Collectors.toSet())); return Health.status(status).withDetails(healths).build(); } RateLimitersHealthIndicator(RateLimiterRegistry rateLimiterRegistry,
        RateLimiterConfigurationProperties rateLimiterProperties,
        StatusAggregator statusAggregator); @Override Health health();  }
@Test public void health() throws Exception { RateLimiterConfig config = mock(RateLimiterConfig.class); AtomicRateLimiter.AtomicRateLimiterMetrics metrics = mock( AtomicRateLimiter.AtomicRateLimiterMetrics.class); AtomicRateLimiter rateLimiter = mock(AtomicRateLimiter.class); RateLimiterRegistry rateLimiterRegistry = mock(RateLimiterRegistry.class); io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties.InstanceProperties instanceProperties = mock( io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties.InstanceProperties.class); RateLimiterConfigurationProperties rateLimiterProperties = mock( RateLimiterConfigurationProperties.class); when(rateLimiter.getRateLimiterConfig()).thenReturn(config); when(rateLimiter.getName()).thenReturn("test"); when(rateLimiterProperties.findRateLimiterProperties("test")) .thenReturn(Optional.of(instanceProperties)); when(instanceProperties.getRegisterHealthIndicator()).thenReturn(true); when(instanceProperties.getAllowHealthIndicatorToFail()).thenReturn(true); when(rateLimiter.getMetrics()).thenReturn(metrics); when(rateLimiter.getDetailedMetrics()).thenReturn(metrics); when(rateLimiterRegistry.getAllRateLimiters()).thenReturn(Array.of(rateLimiter)); when(config.getTimeoutDuration()).thenReturn(Duration.ofNanos(30L)); when(metrics.getAvailablePermissions()) .thenReturn(5, -1, -2); when(metrics.getNumberOfWaitingThreads()) .thenReturn(0, 1, 2); when(metrics.getNanosToWait()) .thenReturn(20L, 40L); RateLimitersHealthIndicator healthIndicator = new RateLimitersHealthIndicator(rateLimiterRegistry, rateLimiterProperties, new SimpleStatusAggregator()); Health health = healthIndicator.health(); then(health.getStatus()).isEqualTo(Status.UP); health = healthIndicator.health(); then(health.getStatus()).isEqualTo(Status.UNKNOWN); health = healthIndicator.health(); then(health.getStatus()).isEqualTo(Status.DOWN); then(health.getDetails().get("test")).isInstanceOf(Health.class); then(((Health) health.getDetails().get("test")).getDetails()) .contains( entry("availablePermissions", -2), entry("numberOfWaitingThreads", 2) ); }
@Test public void healthIndicatorMaxImpactCanBeOverridden() throws Exception { RateLimiterConfig config = mock(RateLimiterConfig.class); AtomicRateLimiter.AtomicRateLimiterMetrics metrics = mock(AtomicRateLimiter.AtomicRateLimiterMetrics.class); AtomicRateLimiter rateLimiter = mock(AtomicRateLimiter.class); RateLimiterRegistry rateLimiterRegistry = mock(RateLimiterRegistry.class); io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties.InstanceProperties instanceProperties = mock(io.github.resilience4j.common.ratelimiter.configuration.RateLimiterConfigurationProperties.InstanceProperties.class); RateLimiterConfigurationProperties rateLimiterProperties = mock(RateLimiterConfigurationProperties.class); when(rateLimiter.getRateLimiterConfig()).thenReturn(config); when(rateLimiter.getName()).thenReturn("test"); when(rateLimiterProperties.findRateLimiterProperties("test")).thenReturn(Optional.of(instanceProperties)); when(instanceProperties.getRegisterHealthIndicator()).thenReturn(true); boolean allowHealthIndicatorToFail = false; when(instanceProperties.getAllowHealthIndicatorToFail()).thenReturn(allowHealthIndicatorToFail); when(rateLimiter.getMetrics()).thenReturn(metrics); when(rateLimiter.getDetailedMetrics()).thenReturn(metrics); when(rateLimiterRegistry.getAllRateLimiters()).thenReturn(Array.of(rateLimiter)); when(config.getTimeoutDuration()).thenReturn(Duration.ofNanos(30L)); when(metrics.getAvailablePermissions()) .thenReturn(-2); when(metrics.getNumberOfWaitingThreads()) .thenReturn(2); when(metrics.getNanosToWait()) .thenReturn(40L); RateLimitersHealthIndicator healthIndicator = new RateLimitersHealthIndicator(rateLimiterRegistry, rateLimiterProperties, new SimpleStatusAggregator()); Health health = healthIndicator.health(); then(health.getStatus()).isEqualTo(Status.UNKNOWN); then(((Health) health.getDetails().get("test")).getStatus()).isEqualTo(new Status("RATE_LIMITED")); then(health.getDetails().get("test")).isInstanceOf(Health.class); then(((Health) health.getDetails().get("test")).getDetails()) .contains( entry("availablePermissions", -2), entry("numberOfWaitingThreads", 2) ); }