From 231d183396ca7187b2b45c50927aa8a3bc8dac56 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Wed, 20 Sep 2017 20:48:51 +0200 Subject: [PATCH] SONAR-9802 add telemetry to api/system/info on cluster mode --- .../server/platform/ws/BaseInfoWsAction.java | 28 +++++++++++++++---- .../server/platform/ws/ClusterInfoAction.java | 22 ++++++++------- .../sonar/server/platform/ws/InfoAction.java | 25 ++++++----------- .../server/platform/ws/InfoActionTest.java | 11 ++++---- .../server/platform/ws/SystemWsTest.java | 2 +- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/BaseInfoWsAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/BaseInfoWsAction.java index d6f821f2d17..1af23c72a53 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/BaseInfoWsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/BaseInfoWsAction.java @@ -26,8 +26,12 @@ import org.sonar.api.server.ws.WebService; 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 = { @@ -37,9 +41,11 @@ public abstract class BaseInfoWsAction implements SystemWsAction { "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 @@ -62,22 +68,22 @@ public abstract class BaseInfoWsAction implements SystemWsAction { protected abstract void doHandle(Request request, Response response); - protected void writeSectionsToJson(Collection sections, JsonWriter json) { + protected void writeSections(Collection 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()); @@ -98,4 +104,14 @@ public abstract class BaseInfoWsAction implements SystemWsAction { 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()); + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ClusterInfoAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ClusterInfoAction.java index 6f5e7d9bde4..f0208f2a84d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ClusterInfoAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/ClusterInfoAction.java @@ -29,6 +29,7 @@ import org.sonar.server.platform.monitoring.cluster.AppNodesInfoLoader; 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 { @@ -39,8 +40,9 @@ 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; @@ -53,18 +55,18 @@ public class ClusterInfoAction extends BaseInfoWsAction { 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) { @@ -72,7 +74,7 @@ public class ClusterInfoAction extends BaseInfoWsAction { Collection appNodes = appNodesInfoLoader.load(); for (NodeInfo applicationNode : appNodes) { - writeNodeInfoToJson(applicationNode, clusterHealth, json); + writeNodeInfo(applicationNode, clusterHealth, json); } json.endArray(); } @@ -81,11 +83,11 @@ public class ClusterInfoAction extends BaseInfoWsAction { json.name("Search Nodes").beginArray(); Collection 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)); @@ -97,7 +99,7 @@ public class ClusterInfoAction extends BaseInfoWsAction { json.name("Health Causes").beginArray().values(h.getCauses()).endArray(); }); - writeSectionsToJson(nodeInfo.getSections(), json); + writeSections(nodeInfo.getSections(), json); json.endObject(); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java index 0011675154c..7bcc238d740 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/platform/ws/InfoAction.java @@ -33,7 +33,6 @@ import org.sonar.server.telemetry.TelemetryDataLoader; 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. @@ -43,14 +42,12 @@ public class InfoAction extends BaseInfoWsAction { 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; } @@ -64,28 +61,22 @@ public class InfoAction extends BaseInfoWsAction { private void writeJson(JsonWriter json) { json.beginObject(); - writeHealthToJson(json); + writeHealth(json); + List 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); } - } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java index 9e92b6205c7..6efbac1161f 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java @@ -38,13 +38,13 @@ import org.sonar.server.ws.WsActionTester; 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(); @@ -53,9 +53,9 @@ public class InfoActionTest { 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 @@ -97,11 +97,10 @@ public class InfoActionTest { 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\":{}}}"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java index 179c09bd863..22e6ad20114 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/platform/ws/SystemWsTest.java @@ -46,7 +46,7 @@ public class SystemWsTest { 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(); -- 2.39.5