import org.sonar.server.user.UserSession;
import org.sonar.server.ws.WsUtils;
+import static org.sonar.server.platform.ws.HealthActionSupport.LOCAL_PARAM;
+
public class HealthAction implements SystemWsAction {
private final WebServer webServer;
private final HealthActionSupport support;
throw new ForbiddenException("Insufficient privileges");
}
- if (webServer.isStandalone()) {
+ boolean localParam = request.mandatoryParamAsBoolean(LOCAL_PARAM);
+ if (webServer.isStandalone() || localParam) {
WsUtils.writeProtobuf(support.checkNodeHealth(), request, response);
} else {
WsUtils.writeProtobuf(support.checkClusterHealth(), request, response);
import static org.sonar.api.utils.DateUtils.formatDateTime;
public class HealthActionSupport {
+ static final String LOCAL_PARAM = "local";
private static final Comparator<NodeHealth> NODE_HEALTH_COMPARATOR = Comparator.<NodeHealth>comparingInt(s -> s.getDetails().getType().ordinal())
.thenComparing(a -> a.getDetails().getName())
.thenComparing(a -> a.getDetails().getHost())
}
void define(WebService.NewController controller, SystemWsAction handler) {
- controller.createAction("health")
+ WebService.NewAction action = controller.createAction("health")
.setDescription("Provide health status of SonarQube." +
"<p>Require 'Administer System' permission or authentication with passcode</p>" +
"<p> " +
.setSince("6.6")
.setResponseExample(Resources.getResource(this.getClass(), "example-health.json"))
.setHandler(handler);
+
+ action.createParam(LOCAL_PARAM)
+ .setDescription("True: Provide health for the node only, False: cluster-wide health (Only applies to SonarQube Datacenter Edition)")
+ .setExampleValue(false)
+ .setDefaultValue(false)
+ .setSince("9.1")
+ .setRequired(false);
}
System.HealthResponse checkNodeHealth() {
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.api.utils.DateUtils.parseDateTime;
assertThat(definition.since()).isEqualTo("6.6");
assertThat(definition.isInternal()).isFalse();
assertThat(definition.responseExample()).isNotNull();
- assertThat(definition.params()).isEmpty();
+ assertThat(definition.params()).extracting(WebService.Param::key).containsOnly("local");
}
@Test
.containsExactly(expected);
}
+ @Test
+ public void request_returns_only_node_health_when_cluster_with_local_parameter_true() {
+ authenticateWithRandomMethod();
+
+ when(webServer.isStandalone()).thenReturn(false);
+ Health.Builder builder = newHealthCheckBuilder().setStatus(Health.Status.GREEN);
+ Health health = builder.build();
+ when(healthChecker.checkNode()).thenReturn(health);
+
+ System.HealthResponse response = underTest.newRequest().setParam("local", "true")
+ .executeProtobuf(System.HealthResponse.class);
+
+ assertThat(response.getHealth().name()).isEqualTo(health.getStatus().name());
+ assertThat(response.getNodes().getNodesList()).isEmpty();
+ verify(healthChecker, never()).checkCluster();
+ }
+
private NodeHealth randomNodeHealth() {
NodeHealth.Builder builder = newNodeHealthBuilder()
.setStatus(NodeHealth.Status.values()[random.nextInt(NodeHealth.Status.values().length)]);
assertThat(definition.since()).isEqualTo("6.6");
assertThat(definition.isInternal()).isFalse();
assertThat(definition.responseExample()).isNotNull();
- assertThat(definition.params()).isEmpty();
+ assertThat(definition.params()).extracting(WebService.Param::key).containsOnly("local");
}
@Test