import org.sonar.api.utils.text.JsonWriter;
import org.sonar.process.systeminfo.SystemInfoUtils;
import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
+import org.sonar.server.health.Health;
+import org.sonar.server.telemetry.TelemetryDataLoader;
import org.sonar.server.user.UserSession;
+import static org.sonar.server.telemetry.TelemetryDataJsonWriter.writeTelemetryData;
+
public abstract class BaseInfoWsAction implements SystemWsAction {
private static final String[] ORDERED_SECTION_NAMES = {
"Compute Engine Database Connection", "Compute Engine JVM State", "Compute Engine Logging", "Compute Engine Tasks", "Compute Engine JVM Properties"};
private final UserSession userSession;
+ private final TelemetryDataLoader telemetry;
- public BaseInfoWsAction(UserSession userSession) {
+ public BaseInfoWsAction(UserSession userSession, TelemetryDataLoader telemetry) {
this.userSession = userSession;
+ this.telemetry = telemetry;
}
@Override
protected abstract void doHandle(Request request, Response response);
- protected void writeSectionsToJson(Collection<ProtobufSystemInfo.Section> sections, JsonWriter json) {
+ protected void writeSections(Collection<ProtobufSystemInfo.Section> sections, JsonWriter json) {
SystemInfoUtils
.order(sections, ORDERED_SECTION_NAMES)
- .forEach(section -> writeSectionToJson(section, json));
+ .forEach(section -> writeSection(section, json));
}
- protected void writeSectionToJson(ProtobufSystemInfo.Section section, JsonWriter json) {
+ private void writeSection(ProtobufSystemInfo.Section section, JsonWriter json) {
json.name(section.getName());
json.beginObject();
for (ProtobufSystemInfo.Attribute attribute : section.getAttributesList()) {
- writeAttributeToJson(attribute, json);
+ writeAttribute(attribute, json);
}
json.endObject();
}
- protected void writeAttributeToJson(ProtobufSystemInfo.Attribute attribute, JsonWriter json) {
+ private void writeAttribute(ProtobufSystemInfo.Attribute attribute, JsonWriter json) {
switch (attribute.getValueCase()) {
case BOOLEAN_VALUE:
json.prop(attribute.getKey(), attribute.getBooleanValue());
throw new IllegalArgumentException("Unsupported type: " + attribute.getValueCase());
}
}
+
+ protected void writeHealth(Health health, JsonWriter json) {
+ json.prop("Health", health.getStatus().name());
+ json.name("Health Causes").beginArray().values(health.getCauses()).endArray();
+ }
+
+ protected void writeTelemetry(JsonWriter json) {
+ json.name("Statistics");
+ writeTelemetryData(json, telemetry.load());
+ }
}
import org.sonar.server.platform.monitoring.cluster.GlobalInfoLoader;
import org.sonar.server.platform.monitoring.cluster.NodeInfo;
import org.sonar.server.platform.monitoring.cluster.SearchNodesInfoLoader;
+import org.sonar.server.telemetry.TelemetryDataLoader;
import org.sonar.server.user.UserSession;
public class ClusterInfoAction extends BaseInfoWsAction {
private final HealthChecker healthChecker;
public ClusterInfoAction(UserSession userSession, GlobalInfoLoader globalInfoLoader,
- AppNodesInfoLoader appNodesInfoLoader, SearchNodesInfoLoader searchNodesInfoLoader, HealthChecker healthChecker) {
- super(userSession);
+ AppNodesInfoLoader appNodesInfoLoader, SearchNodesInfoLoader searchNodesInfoLoader,
+ HealthChecker healthChecker, TelemetryDataLoader telemetry) {
+ super(userSession, telemetry);
this.globalInfoLoader = globalInfoLoader;
this.appNodesInfoLoader = appNodesInfoLoader;
this.searchNodesInfoLoader = searchNodesInfoLoader;
try (JsonWriter json = response.newJsonWriter()) {
json.beginObject();
- json.prop("Health", clusterHealth.getHealth().getStatus().name());
- json.name("Health Causes").beginArray().values(clusterHealth.getHealth().getCauses()).endArray();
-
+ writeHealth(clusterHealth.getHealth(), json);
writeGlobalSections(json);
writeApplicationNodes(json, clusterHealth);
writeSearchNodes(json, clusterHealth);
+ writeTelemetry(json);
+
json.endObject();
}
}
private void writeGlobalSections(JsonWriter json) {
- globalInfoLoader.load().forEach(section -> writeSectionToJson(section, json));
+ writeSections(globalInfoLoader.load(), json);
}
private void writeApplicationNodes(JsonWriter json, ClusterHealth clusterHealth) {
Collection<NodeInfo> appNodes = appNodesInfoLoader.load();
for (NodeInfo applicationNode : appNodes) {
- writeNodeInfoToJson(applicationNode, clusterHealth, json);
+ writeNodeInfo(applicationNode, clusterHealth, json);
}
json.endArray();
}
json.name("Search Nodes").beginArray();
Collection<NodeInfo> searchNodes = searchNodesInfoLoader.load();
- searchNodes.forEach(node -> writeNodeInfoToJson(node, clusterHealth, json));
+ searchNodes.forEach(node -> writeNodeInfo(node, clusterHealth, json));
json.endArray();
}
- private void writeNodeInfoToJson(NodeInfo nodeInfo, ClusterHealth clusterHealth, JsonWriter json) {
+ private void writeNodeInfo(NodeInfo nodeInfo, ClusterHealth clusterHealth, JsonWriter json) {
json.beginObject();
json.prop("Name", nodeInfo.getName());
json.prop("Error", nodeInfo.getErrorMessage().orElse(null));
json.name("Health Causes").beginArray().values(h.getCauses()).endArray();
});
- writeSectionsToJson(nodeInfo.getSections(), json);
+ writeSections(nodeInfo.getSections(), json);
json.endObject();
}
}
import org.sonar.server.user.UserSession;
import static java.util.Arrays.stream;
-import static org.sonar.server.telemetry.TelemetryDataJsonWriter.writeTelemetryData;
/**
* Implementation of the {@code info} action for the System WebService.
private final CeHttpClient ceHttpClient;
private final SystemInfoSection[] systemInfoSections;
private final HealthChecker healthChecker;
- private final TelemetryDataLoader statistics;
- public InfoAction(UserSession userSession, CeHttpClient ceHttpClient, HealthChecker healthChecker, TelemetryDataLoader statistics,
+ public InfoAction(UserSession userSession, TelemetryDataLoader telemetry, CeHttpClient ceHttpClient, HealthChecker healthChecker,
SystemInfoSection... systemInfoSections) {
- super(userSession);
+ super(userSession, telemetry);
this.ceHttpClient = ceHttpClient;
this.healthChecker = healthChecker;
- this.statistics = statistics;
this.systemInfoSections = systemInfoSections;
}
private void writeJson(JsonWriter json) {
json.beginObject();
- writeHealthToJson(json);
+ writeHealth(json);
+
List<ProtobufSystemInfo.Section> sections = stream(systemInfoSections)
.map(SystemInfoSection::toProtobuf)
.collect(MoreCollectors.toArrayList());
ceHttpClient.retrieveSystemInfo()
.ifPresent(ce -> sections.addAll(ce.getSectionsList()));
- writeSectionsToJson(sections, json);
- writeStatisticsToJson(json);
+ writeSections(sections, json);
+ writeTelemetry(json);
json.endObject();
}
- private void writeHealthToJson(JsonWriter json) {
+ private void writeHealth(JsonWriter json) {
Health health = healthChecker.checkNode();
- json.prop("Health", health.getStatus().name());
- json.name("Health Causes").beginArray().values(health.getCauses()).endArray();
- }
-
- private void writeStatisticsToJson(JsonWriter json) {
- json.name("Statistics");
- writeTelemetryData(json, statistics.load());
+ writeHealth(health, json);
}
-
}
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;
public class InfoActionTest {
@Rule
- public UserSessionRule userSessionRule = UserSessionRule.standalone().logIn("login")
+ public UserSessionRule userSessionRule = UserSessionRule.standalone()
+ .logIn("login")
.setName("name");
@Rule
public ExpectedException expectedException = ExpectedException.none();
private SystemInfoSection section2 = mock(SystemInfoSection.class);
private CeHttpClient ceHttpClient = mock(CeHttpClientImpl.class, Mockito.RETURNS_MOCKS);
private TestStandaloneHealthChecker healthChecker = new TestStandaloneHealthChecker();
- private TelemetryDataLoader statistics = mock(TelemetryDataLoader.class);
+ private TelemetryDataLoader telemetry = mock(TelemetryDataLoader.class);
- private InfoAction underTest = new InfoAction(userSessionRule, ceHttpClient, healthChecker, statistics, section1, section2);
+ private InfoAction underTest = new InfoAction(userSessionRule, telemetry, ceHttpClient, healthChecker, section1, section2);
private WsActionTester ws = new WsActionTester(underTest);
@Test
setAttribute(attributes2, "two", 2);
when(section2.toProtobuf()).thenReturn(attributes2.build());
when(ceHttpClient.retrieveSystemInfo()).thenReturn(Optional.empty());
- when(statistics.load()).thenReturn(mock(TelemetryData.class));
+ when(telemetry.load()).thenReturn(mock(TelemetryData.class));
TestResponse response = ws.newRequest().execute();
// response does not contain empty "Section Three"
- verify(statistics).load();
assertThat(response.getInput()).isEqualTo("{\"Health\":\"GREEN\",\"Health Causes\":[],\"Section One\":{\"foo\":\"bar\"},\"Section Two\":{\"one\":1,\"two\":2}," +
"\"Statistics\":{\"plugins\":{},\"userCount\":0,\"projectCount\":0,\"lines\":0,\"ncloc\":0,\"projectCountByLanguage\":{},\"nclocByLanguage\":{}}}");
}
public void define() {
RestartAction action1 = new RestartAction(mock(UserSession.class), mock(Configuration.class), mock(Platform.class), mock(ProcessCommandWrapper.class),
mock(RestartFlagHolder.class), mock(WebServer.class));
- InfoAction action2 = new InfoAction(new AnonymousMockUserSession(), ceHttpClient, healthChecker, mock(TelemetryDataLoader.class));
+ InfoAction action2 = new InfoAction(new AnonymousMockUserSession(), mock(TelemetryDataLoader.class), ceHttpClient, healthChecker);
SystemWs ws = new SystemWs(action1, action2);
WebService.Context context = new WebService.Context();