diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2017-10-02 13:52:36 +0200 |
---|---|---|
committer | Teryk Bellahsene <teryk@users.noreply.github.com> | 2017-10-03 14:45:02 +0200 |
commit | e55f17e022e888e22f1cc8d00d089dd071fa707c (patch) | |
tree | 4d28ea1eddbc6fecf0a1247182f47d400e452270 | |
parent | 266450099096400d6134cc429a462bb52c198b06 (diff) | |
download | sonarqube-e55f17e022e888e22f1cc8d00d089dd071fa707c.tar.gz sonarqube-e55f17e022e888e22f1cc8d00d089dd071fa707c.zip |
SONAR-9820 Telemetry returns database name and version
7 files changed, 87 insertions, 11 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java index 58b1cda6376..92d31b248ab 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java +++ b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java @@ -33,10 +33,11 @@ public class TelemetryData { private final long ncloc; private final long userCount; private final long projectCount; + private final Database database; private final Map<String, Long> projectCountByLanguage; private final Map<String, Long> nclocByLanguage; - public TelemetryData(Builder builder) { + private TelemetryData(Builder builder) { serverId = builder.serverId; version = builder.version; plugins = builder.plugins; @@ -44,6 +45,7 @@ public class TelemetryData { ncloc = builder.projectMeasuresStatistics.getNcloc(); userCount = builder.userCount; projectCount = builder.projectMeasuresStatistics.getProjectCount(); + database = builder.database; projectCountByLanguage = builder.projectMeasuresStatistics.getProjectCountByLanguage(); nclocByLanguage = builder.projectMeasuresStatistics.getNclocByLanguage(); } @@ -76,6 +78,10 @@ public class TelemetryData { return projectCount; } + public Database getDatabase() { + return database; + } + public Map<String, Long> getProjectCountByLanguage() { return projectCountByLanguage; } @@ -84,7 +90,7 @@ public class TelemetryData { return nclocByLanguage; } - public static Builder builder() { + static Builder builder() { return new Builder(); } @@ -93,6 +99,7 @@ public class TelemetryData { private String version; private long userCount; private Map<String, String> plugins; + private Database database; private ProjectMeasuresStatistics projectMeasuresStatistics; private Builder() { @@ -121,6 +128,11 @@ public class TelemetryData { this.projectMeasuresStatistics = projectMeasuresStatistics; } + Builder setDatabase(Database database) { + this.database = database; + return this; + } + TelemetryData build() { requireNonNull(serverId); requireNonNull(version); @@ -130,4 +142,22 @@ public class TelemetryData { return new TelemetryData(this); } } + + static class Database { + private final String name; + private final String version; + + Database(String name, String version) { + this.name = name; + this.version = version; + } + + public String getName() { + return name; + } + + public String getVersion() { + return version; + } + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java index 569841f7743..723747f2081 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java +++ b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java @@ -34,6 +34,11 @@ public class TelemetryDataJsonWriter { json.beginObject(); json.prop("id", statistics.getServerId()); json.prop("version", statistics.getVersion()); + json.name("database"); + json.beginObject(); + json.prop("name", statistics.getDatabase().getName()); + json.prop("version", statistics.getDatabase().getVersion()); + json.endObject(); json.name("plugins"); json.beginArray(); statistics.getPlugins().forEach((plugin, version) -> { diff --git a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java index 82749856e50..d16bfd1efbb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java @@ -20,6 +20,8 @@ package org.sonar.server.telemetry; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; import java.util.Map; import java.util.function.Function; import org.sonar.api.platform.Server; @@ -27,21 +29,26 @@ import org.sonar.api.server.ServerSide; import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; import org.sonar.core.util.stream.MoreCollectors; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; import org.sonar.server.es.SearchOptions; import org.sonar.server.measure.index.ProjectMeasuresIndex; import org.sonar.server.measure.index.ProjectMeasuresStatistics; +import org.sonar.server.telemetry.TelemetryData.Database; import org.sonar.server.user.index.UserIndex; import org.sonar.server.user.index.UserQuery; @ServerSide public class TelemetryDataLoader { private final Server server; + private final DbClient dbClient; private final PluginRepository pluginRepository; private final UserIndex userIndex; private final ProjectMeasuresIndex projectMeasuresIndex; - public TelemetryDataLoader(Server server, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex) { + public TelemetryDataLoader(Server server, DbClient dbClient, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex) { this.server = server; + this.dbClient = dbClient; this.pluginRepository = pluginRepository; this.userIndex = userIndex; this.projectMeasuresIndex = projectMeasuresIndex; @@ -52,6 +59,7 @@ public class TelemetryDataLoader { data.setServerId(server.getId()); data.setVersion(server.getVersion()); + data.setDatabase(loadDatabaseMetadata()); Function<PluginInfo, String> getVersion = plugin -> plugin.getVersion() == null ? "undefined" : plugin.getVersion().getName(); Map<String, String> plugins = pluginRepository.getPluginInfos().stream().collect(MoreCollectors.uniqueIndex(PluginInfo::getKey, getVersion)); data.setPlugins(plugins); @@ -66,4 +74,13 @@ public class TelemetryDataLoader { String loadServerId() { return server.getId(); } + + private Database loadDatabaseMetadata() { + try (DbSession dbSession = dbClient.openSession(false)) { + DatabaseMetaData metadata = dbSession.getConnection().getMetaData(); + return new Database(metadata.getDatabaseProductName(), metadata.getDatabaseProductVersion()); + } catch (SQLException e) { + throw new IllegalStateException("Fail to get DB metadata", e); + } + } } 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 ab6ef319a94..711e36759b5 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 @@ -30,7 +30,6 @@ import org.sonar.process.systeminfo.SystemInfoSection; import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.health.TestStandaloneHealthChecker; -import org.sonar.server.telemetry.TelemetryData; import org.sonar.server.telemetry.TelemetryDataLoader; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestResponse; @@ -53,7 +52,7 @@ 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 telemetry = mock(TelemetryDataLoader.class); + private TelemetryDataLoader telemetry = mock(TelemetryDataLoader.class, Mockito.RETURNS_MOCKS); private InfoAction underTest = new InfoAction(userSessionRule, telemetry, ceHttpClient, healthChecker, section1, section2); private WsActionTester ws = new WsActionTester(underTest); @@ -97,12 +96,12 @@ public class InfoActionTest { setAttribute(attributes2, "two", 2); when(section2.toProtobuf()).thenReturn(attributes2.build()); when(ceHttpClient.retrieveSystemInfo()).thenReturn(Optional.empty()); - when(telemetry.load()).thenReturn(mock(TelemetryData.class)); TestResponse response = ws.newRequest().execute(); // response does not contain empty "Section Three" 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\":[]}}"); + "\"Statistics\":{\"id\":\"\",\"version\":\"\",\"database\":{\"name\":\"\",\"version\":\"\"},\"plugins\":[],\"userCount\":0,\"projectCount\":0,\"lines\":0,\"ncloc\":0," + + "\"projectCountByLanguage\":[],\"nclocByLanguage\":[]}}"); } private void logInAsSystemAdministrator() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java index 8f763971c49..4d68cd9aac8 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java @@ -22,6 +22,8 @@ package org.sonar.server.telemetry; import com.google.common.collect.ImmutableMap; import java.io.IOException; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; import java.util.List; import java.util.Map; import java.util.stream.IntStream; @@ -38,6 +40,7 @@ import org.sonar.api.utils.log.LoggerLevel; import org.sonar.core.config.TelemetryProperties; import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; +import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; @@ -96,8 +99,8 @@ public class TelemetryDaemonTest { private ProjectMeasuresIndexer projectMeasuresIndexer = new ProjectMeasuresIndexer(db.getDbClient(), es.client()); private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client()); - private TelemetryDaemon underTest = new TelemetryDaemon(new TelemetryDataLoader(server, pluginRepository, new UserIndex(es.client()), new ProjectMeasuresIndex(es.client(), null)), client, - settings.asConfig(), internalProperties, system2); + private TelemetryDaemon underTest = new TelemetryDaemon(new TelemetryDataLoader(server, db.getDbClient(), pluginRepository, new UserIndex(es.client()), + new ProjectMeasuresIndex(es.client(), null)), client, settings.asConfig(), internalProperties, system2); @After public void tearDown() throws Exception { @@ -141,11 +144,26 @@ public class TelemetryDaemonTest { ArgumentCaptor<String> jsonCaptor = ArgumentCaptor.forClass(String.class); verify(client, timeout(2_000).atLeastOnce()).upload(jsonCaptor.capture()); String json = jsonCaptor.getValue(); - assertJson(json).isSimilarTo(getClass().getResource("telemetry-example.json")); - assertJson(getClass().getResource("telemetry-example.json")).isSimilarTo(json); + assertJson(json).ignoreFields("database").isSimilarTo(getClass().getResource("telemetry-example.json")); + assertJson(getClass().getResource("telemetry-example.json")).ignoreFields("database").isSimilarTo(json); + assertDatabaseMetadata(json); assertThat(logger.logs(LoggerLevel.INFO)).contains("Sharing of SonarQube statistics is enabled."); } + private void assertDatabaseMetadata(String json) { + try (DbSession dbSession = db.getDbClient().openSession(false)) { + DatabaseMetaData metadata = dbSession.getConnection().getMetaData(); + assertJson(json).isSimilarTo("{\n" + + " \"database\": {\n" + + " \"name\": \"H2\",\n" + + " \"version\": \"" + metadata.getDatabaseProductVersion() + "\"\n" + + " }\n" + + "}"); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + @Test public void exclude_branches() throws IOException { settings.setProperty("sonar.telemetry.frequencyInSeconds", "1"); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/telemetry/telemetry-example.json b/server/sonar-server/src/test/resources/org/sonar/server/telemetry/telemetry-example.json index 93cf4f1280f..58cb8040805 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/telemetry/telemetry-example.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/telemetry/telemetry-example.json @@ -1,6 +1,10 @@ { "id": "AU-TpxcB-iU5OvuD2FL7", "version": "7.5.4", + "database": { + "name": "PostgreSQL", + "version": "9.6.5" + }, "plugins": [ { "name": "java", diff --git a/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryUploadTest.java b/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryUploadTest.java index dc4d3c0a9ff..82016455508 100644 --- a/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryUploadTest.java +++ b/tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryUploadTest.java @@ -82,6 +82,9 @@ public class TelemetryUploadTest { assertThat(request.getHeader(HttpHeaders.USER_AGENT)).contains("SonarQube"); Map<String, Object> json = jsonToMap(request.getBody().readUtf8()); assertThat(json.get("id")).isEqualTo(serverId()); + Map<String, String> database = (Map<String, String>) json.get("database"); + assertThat(database.get("name")).isNotEmpty(); + assertThat(database.get("version")).isNotEmpty(); assertThat(getInteger(json.get("userCount"))).isEqualTo(1); List<String> plugins = ((List<Map<String, String>>) json.get("plugins")).stream().map(p -> p.get("name")).collect(Collectors.toList()); assertThat(plugins).contains("xoo"); |