Add SentinelHealthIndicator to do some health check for Sentinel #265

pull/671/head
cdfive 6 years ago
parent 5fd04277cb
commit 9c638b8d3f

@ -1,6 +1,8 @@
spring.application.name=sentinel-example
server.port=18083
management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
spring.cloud.sentinel.transport.dashboard=localhost:8080
spring.cloud.sentinel.eager=true
@ -19,4 +21,4 @@ spring.cloud.sentinel.datasource.ds4.file.file=classpath: system.json
spring.cloud.sentinel.datasource.ds4.file.rule-type=system
spring.cloud.sentinel.datasource.ds5.file.file=classpath: param-flow.json
spring.cloud.sentinel.datasource.ds5.file.rule-type=param-flow
spring.cloud.sentinel.datasource.ds5.file.rule-type=param_flow

@ -17,6 +17,7 @@
package org.springframework.cloud.alibaba.sentinel.endpoint;
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -38,4 +39,10 @@ public class SentinelEndpointAutoConfiguration {
return new SentinelEndpoint(sentinelProperties);
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnEnabledHealthIndicator("sentinel")
public SentinelHealthIndicator sentinelHealthIndicator(SentinelProperties sentinelProperties) {
return new SentinelHealthIndicator(sentinelProperties);
}
}

@ -0,0 +1,67 @@
package org.springframework.cloud.alibaba.sentinel.endpoint;
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider;
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.actuate.health.Status;
import org.springframework.cloud.alibaba.sentinel.SentinelProperties;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* {@link HealthIndicator} for Sentinel.
* <p>
* Check the status of Sentinel Dashboard by sending a heartbeat message to it.
*
* Note: if sentinel isn't enabled or sentinel-dashboard isn't configured,
* the health status is up and more infos are provided in detail.
* </p>
*
* @author cdfive
*/
public class SentinelHealthIndicator extends AbstractHealthIndicator {
private SentinelProperties sentinelProperties;
public SentinelHealthIndicator(SentinelProperties sentinelProperties) {
this.sentinelProperties = sentinelProperties;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
Map<String, Object> detailMap = new HashMap<>();
// If sentinel isn't enabled, set the status up and set the enabled to false in detail
if (!sentinelProperties.isEnabled()) {
detailMap.put("enabled", false);
builder.up().withDetails(detailMap);
return;
}
detailMap.put("enabled", true);
String consoleServer = TransportConfig.getConsoleServer();
// If dashboard isn't configured, set the status to UNKNOWN
if (StringUtils.isEmpty(consoleServer)) {
detailMap.put("dashboard", new Status(Status.UNKNOWN.getCode(), "dashboard isn't configured"));
builder.up().withDetails(detailMap);
return;
}
// If dashboard is configured, send a heartbeat message to it and check the result
HeartbeatSender heartbeatSender = HeartbeatSenderProvider.getHeartbeatSender();
boolean result = heartbeatSender.sendHeartbeat();
if (result) {
detailMap.put("dashboard", Status.UP);
builder.up().withDetails(detailMap);
} else {
detailMap.put("dashboard", new Status(Status.DOWN.getCode(), consoleServer + " can't be connected"));
builder.down().withDetails(detailMap);
}
}
}

@ -0,0 +1,90 @@
package org.springframework.cloud.alibaba.sentinel.endpoint;
import com.alibaba.csp.sentinel.config.SentinelConfig;
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider;
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.actuate.health.Health;
import org.springframework.boot.actuate.health.Status;
import org.springframework.cloud.alibaba.sentinel.SentinelProperties;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
/**
* Test cases for {@link SentinelHealthIndicator}.
*
* @author cdfive
*/
public class SentinelHealthIndicatorTests {
private SentinelHealthIndicator sentinelHealthIndicator;
private SentinelProperties sentinelProperties;
private HeartbeatSender heartbeatSender;
@Before
public void setUp() {
sentinelProperties = mock(SentinelProperties.class);
sentinelHealthIndicator = new SentinelHealthIndicator(sentinelProperties);
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "");
heartbeatSender = mock(HeartbeatSender.class);
Field heartbeatSenderField = ReflectionUtils.findField(HeartbeatSenderProvider.class, "heartbeatSender");
heartbeatSenderField.setAccessible(true);
ReflectionUtils.setField(heartbeatSenderField, null, heartbeatSender);
}
@Test
public void testSentinelNotEnabled() {
when(sentinelProperties.isEnabled()).thenReturn(false);
Health health = sentinelHealthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("enabled")).isEqualTo(false);
}
@Test
public void testSentinelDashboardNotConfigured() {
when(sentinelProperties.isEnabled()).thenReturn(true);
Health health = sentinelHealthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
assertThat(health.getDetails().get("dashboard")).isEqualTo(Status.UNKNOWN);
}
@Test
public void testSentinelDashboardConfiguredCheckSuccess() throws Exception {
when(sentinelProperties.isEnabled()).thenReturn(true);
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "localhost:8080");
when(heartbeatSender.sendHeartbeat()).thenReturn(true);
Health health = sentinelHealthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.UP);
}
@Test
public void testSentinelDashboardConfiguredCheckFailed() throws Exception {
when(sentinelProperties.isEnabled()).thenReturn(true);
SentinelConfig.setConfig(TransportConfig.CONSOLE_SERVER, "localhost:8080");
when(heartbeatSender.sendHeartbeat()).thenReturn(false);
Health health = sentinelHealthIndicator.health();
assertThat(health.getStatus()).isEqualTo(Status.DOWN);
assertThat(health.getDetails().get("dashboard")).isEqualTo(new Status(Status.DOWN.getCode(), "localhost:8080 can't be connected"));
}
}
Loading…
Cancel
Save