aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2017-10-02 13:52:36 +0200
committerTeryk Bellahsene <teryk@users.noreply.github.com>2017-10-03 14:45:02 +0200
commite55f17e022e888e22f1cc8d00d089dd071fa707c (patch)
tree4d28ea1eddbc6fecf0a1247182f47d400e452270
parent266450099096400d6134cc429a462bb52c198b06 (diff)
downloadsonarqube-e55f17e022e888e22f1cc8d00d089dd071fa707c.tar.gz
sonarqube-e55f17e022e888e22f1cc8d00d089dd071fa707c.zip
SONAR-9820 Telemetry returns database name and version
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java34
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataJsonWriter.java5
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java19
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/platform/ws/InfoActionTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java26
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/telemetry/telemetry-example.json4
-rw-r--r--tests/src/test/java/org/sonarqube/tests/telemetry/TelemetryUploadTest.java3
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");