]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9721 Extract TelemetryDataLoader from TelemetryDataDaemon
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Fri, 25 Aug 2017 15:27:19 +0000 (17:27 +0200)
committerTeryk Bellahsene <teryk@users.noreply.github.com>
Wed, 30 Aug 2017 14:24:53 +0000 (16:24 +0200)
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryClient.java
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryData.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryDataLoader.java [new file with mode: 0644]
server/sonar-server/src/main/java/org/sonar/server/telemetry/TelemetryModule.java
server/sonar-server/src/test/java/org/sonar/server/telemetry/FakeServer.java
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
server/sonar-server/src/test/java/org/sonar/server/telemetry/TelemetryModuleTest.java

index 1bc8a656b67edcf780a4c9565d882492a05d38a1..51f5e86f461270b8ef5c1765267323a0cbb54391 100644 (file)
@@ -59,7 +59,7 @@ public class TelemetryClient {
     try {
       okHttpClient.newCall(request.build()).execute();
     } catch (IOException e) {
-      LOG.debug("Error when sending opt-out usage statistics: %s", e.getMessage());
+      LOG.debug("Error when sending opt-out usage statistics: {}", e.getMessage());
     }
   }
 
index 24ae7cc22cb589ba70d382f2b9c607a3964b12a5..a32c66e04c63c63f4c5324087f9113d2aab88803 100644 (file)
@@ -29,19 +29,12 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.TimeUnit;
 import org.picocontainer.Startable;
 import org.sonar.api.config.Configuration;
-import org.sonar.api.platform.Server;
 import org.sonar.api.server.ServerSide;
 import org.sonar.api.utils.System2;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.core.platform.PluginRepository;
-import org.sonar.server.es.SearchOptions;
-import org.sonar.server.measure.index.ProjectMeasuresIndex;
-import org.sonar.server.measure.index.ProjectMeasuresStatistics;
 import org.sonar.server.property.InternalProperties;
-import org.sonar.server.user.index.UserIndex;
-import org.sonar.server.user.index.UserQuery;
 
 import static org.sonar.api.measures.CoreMetrics.LINES_KEY;
 import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
@@ -59,27 +52,20 @@ public class TelemetryDaemon implements Startable {
   static final String I_PROP_OPT_OUT = "telemetry.optOut";
   private static final Logger LOG = Loggers.get(TelemetryDaemon.class);
 
+  private final TelemetryDataLoader dataLoader;
   private final TelemetryClient telemetryClient;
   private final Configuration config;
   private final InternalProperties internalProperties;
-  private final Server server;
-  private final PluginRepository pluginRepository;
   private final System2 system2;
-  private final UserIndex userIndex;
-  private final ProjectMeasuresIndex projectMeasuresIndex;
 
   private ScheduledExecutorService executorService;
 
-  public TelemetryDaemon(TelemetryClient telemetryClient, Configuration config, InternalProperties internalProperties, Server server, PluginRepository pluginRepository,
-                         System2 system2, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex) {
+  public TelemetryDaemon(TelemetryDataLoader dataLoader, TelemetryClient telemetryClient, Configuration config, InternalProperties internalProperties, System2 system2) {
+    this.dataLoader = dataLoader;
     this.telemetryClient = telemetryClient;
     this.config = config;
     this.internalProperties = internalProperties;
-    this.server = server;
-    this.pluginRepository = pluginRepository;
     this.system2 = system2;
-    this.userIndex = userIndex;
-    this.projectMeasuresIndex = projectMeasuresIndex;
   }
 
   @Override
@@ -139,28 +125,22 @@ public class TelemetryDaemon implements Startable {
     StringWriter json = new StringWriter();
     try (JsonWriter writer = JsonWriter.of(json)) {
       writer.beginObject();
-      writer.prop("id", server.getId());
+      writer.prop("id", dataLoader.loadServerId());
       writer.endObject();
     }
     telemetryClient.optOut(json.toString());
   }
 
   private void uploadStatistics() throws IOException {
+    TelemetryData statistics = dataLoader.load();
     StringWriter json = new StringWriter();
     try (JsonWriter writer = JsonWriter.of(json)) {
       writer.beginObject();
-      writer.prop("id", server.getId());
-      writer.prop("version", server.getVersion());
+      writer.prop("id", statistics.getServerId());
+      writer.prop("version", statistics.getVersion());
       writer.name("plugins");
-      writer.beginObject();
-      pluginRepository.getPluginInfos().forEach(plugin -> {
-        String version = plugin.getVersion() == null ? "undefined" : plugin.getVersion().getName();
-        writer.prop(plugin.getKey(), version);
-      });
-      writer.endObject();
-      long userCount = userIndex.search(UserQuery.builder().build(), new SearchOptions().setLimit(1)).getTotal();
-      writer.prop("userCount", userCount);
-      ProjectMeasuresStatistics statistics = projectMeasuresIndex.searchTelemetryStatistics();
+      writer.valueObject(statistics.getPlugins());
+      writer.prop("userCount", statistics.getUserCount());
       writer.prop("projectCount", statistics.getProjectCount());
       writer.prop(LINES_KEY, statistics.getLines());
       writer.prop(NCLOC_KEY, statistics.getNcloc());
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
new file mode 100644 (file)
index 0000000..1d9cb63
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import java.util.Map;
+import org.sonar.server.measure.index.ProjectMeasuresStatistics;
+
+import static java.util.Objects.requireNonNull;
+
+public class TelemetryData {
+  private final String serverId;
+  private final String version;
+  private final Map<String, String> plugins;
+  private final long lines;
+  private final long ncloc;
+  private final long userCount;
+  private final long projectCount;
+  private final Map<String, Long> projectCountByLanguage;
+  private final Map<String, Long> nclocByLanguage;
+
+  public TelemetryData(Builder builder) {
+    serverId = builder.serverId;
+    version = builder.version;
+    plugins = builder.plugins;
+    lines = builder.projectMeasuresStatistics.getLines();
+    ncloc = builder.projectMeasuresStatistics.getNcloc();
+    userCount = builder.userCount;
+    projectCount = builder.projectMeasuresStatistics.getProjectCount();
+    projectCountByLanguage = builder.projectMeasuresStatistics.getProjectCountByLanguage();
+    nclocByLanguage = builder.projectMeasuresStatistics.getNclocByLanguage();
+  }
+
+  public String getServerId() {
+    return serverId;
+  }
+
+  public String getVersion() {
+    return version;
+  }
+
+  public Map<String, String> getPlugins() {
+    return plugins;
+  }
+
+  public long getLines() {
+    return lines;
+  }
+
+  public long getNcloc() {
+    return ncloc;
+  }
+
+  public long getUserCount() {
+    return userCount;
+  }
+
+  public long getProjectCount() {
+    return projectCount;
+  }
+
+  public Map<String, Long> getProjectCountByLanguage() {
+    return projectCountByLanguage;
+  }
+
+  public Map<String, Long> getNclocByLanguage() {
+    return nclocByLanguage;
+  }
+
+  static Builder builder() {
+    return new Builder();
+  }
+
+  static class Builder {
+    private String serverId;
+    private String version;
+    private long userCount;
+    private Map<String, String> plugins;
+    private ProjectMeasuresStatistics projectMeasuresStatistics;
+
+    private Builder() {
+      // enforce static factory method
+    }
+
+    Builder setServerId(String serverId) {
+      this.serverId = serverId;
+      return this;
+    }
+
+    Builder setVersion(String version) {
+      this.version = version;
+      return this;
+    }
+
+    void setUserCount(long userCount) {
+      this.userCount = userCount;
+    }
+
+    void setPlugins(Map<String, String> plugins) {
+      this.plugins = plugins;
+    }
+
+    void setProjectMeasuresStatistics(ProjectMeasuresStatistics projectMeasuresStatistics) {
+      this.projectMeasuresStatistics = projectMeasuresStatistics;
+    }
+
+    TelemetryData build() {
+      requireNonNull(serverId);
+      requireNonNull(version);
+      requireNonNull(plugins);
+      requireNonNull(projectMeasuresStatistics);
+
+      return new TelemetryData(this);
+    }
+  }
+}
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
new file mode 100644 (file)
index 0000000..8274985
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+package org.sonar.server.telemetry;
+
+import java.util.Map;
+import java.util.function.Function;
+import org.sonar.api.platform.Server;
+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.server.es.SearchOptions;
+import org.sonar.server.measure.index.ProjectMeasuresIndex;
+import org.sonar.server.measure.index.ProjectMeasuresStatistics;
+import org.sonar.server.user.index.UserIndex;
+import org.sonar.server.user.index.UserQuery;
+
+@ServerSide
+public class TelemetryDataLoader {
+  private final Server server;
+  private final PluginRepository pluginRepository;
+  private final UserIndex userIndex;
+  private final ProjectMeasuresIndex projectMeasuresIndex;
+
+  public TelemetryDataLoader(Server server, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex) {
+    this.server = server;
+    this.pluginRepository = pluginRepository;
+    this.userIndex = userIndex;
+    this.projectMeasuresIndex = projectMeasuresIndex;
+  }
+
+  public TelemetryData load() {
+    TelemetryData.Builder data = TelemetryData.builder();
+
+    data.setServerId(server.getId());
+    data.setVersion(server.getVersion());
+    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);
+    long userCount = userIndex.search(UserQuery.builder().build(), new SearchOptions().setLimit(1)).getTotal();
+    data.setUserCount(userCount);
+    ProjectMeasuresStatistics projectMeasuresStatistics = projectMeasuresIndex.searchTelemetryStatistics();
+    data.setProjectMeasuresStatistics(projectMeasuresStatistics);
+
+    return data.build();
+  }
+
+  String loadServerId() {
+    return server.getId();
+  }
+}
index d9a576458dcdd5b608b4fb38c5d7a6db77a70ad4..bb2e4a9b298faa559128458fca1d2ff7f2b0fdbf 100644 (file)
@@ -25,6 +25,7 @@ public class TelemetryModule extends Module {
   @Override
   protected void configureModule() {
     add(
+      TelemetryDataLoader.class,
       TelemetryDaemon.class,
       TelemetryClient.class);
   }
index a793b0cc0bb09b96b359a5ecc6104312d1dbdbb3..85237c7c3d6f0fea6494e592d60f5e596066d3ca 100644 (file)
@@ -25,10 +25,17 @@ import java.util.Date;
 import javax.annotation.CheckForNull;
 import org.sonar.api.platform.Server;
 
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+
 class FakeServer extends Server {
   private String id;
   private String version;
 
+  public FakeServer() {
+    this.id = randomAlphanumeric(20);
+    this.version = randomAlphanumeric(10);
+  }
+
   @Override
   public String getId() {
     return id;
index 0c5f6c179b3e7cd6ddceed2557193cab3945cf30..16dc742383dc5a79c8623788c2532f57d01eeb72 100644 (file)
@@ -33,6 +33,8 @@ import org.sonar.api.config.Configuration;
 import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.utils.internal.TestSystem2;
+import org.sonar.api.utils.log.LogTester;
+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;
@@ -71,6 +73,8 @@ public class TelemetryDaemonTest {
   public UserSessionRule userSession = UserSessionRule.standalone();
   @Rule
   public EsTester es = new EsTester(new UserIndexDefinition(emptyConfig), new ProjectMeasuresIndexDefinition(emptyConfig));
+  @Rule
+  public LogTester logger = new LogTester().setLevel(LoggerLevel.DEBUG);
 
   private TelemetryClient client = mock(TelemetryClient.class);
   private InternalProperties internalProperties = new MapInternalProperties();
@@ -86,8 +90,8 @@ public class TelemetryDaemonTest {
     settings = new MapSettings(new PropertyDefinitions(TelemetryProperties.all()));
     system2.setNow(System.currentTimeMillis());
 
-    underTest = new TelemetryDaemon(client, settings.asConfig(), internalProperties, server, pluginRepository, system2, new UserIndex(es.client()),
-      new ProjectMeasuresIndex(es.client(), null));
+    underTest = new TelemetryDaemon(new TelemetryDataLoader(server, pluginRepository, new UserIndex(es.client()), new ProjectMeasuresIndex(es.client(), null)), client,
+      settings.asConfig(), internalProperties, system2);
   }
 
   @Test
@@ -121,6 +125,7 @@ public class TelemetryDaemonTest {
     String json = jsonCaptor.getValue();
     assertJson(json).isSimilarTo(getClass().getResource("telemetry-example.json"));
     assertJson(getClass().getResource("telemetry-example.json")).isSimilarTo(json);
+    assertThat(logger.logs(LoggerLevel.INFO)).contains("Sharing of SonarQube statistics is enabled.");
   }
 
   @Test
@@ -194,6 +199,7 @@ public class TelemetryDaemonTest {
 
     verify(client, timeout(1_000).never()).upload(anyString());
     verify(client, timeout(1_000).times(1)).optOut(anyString());
+    assertThat(logger.logs(LoggerLevel.INFO)).contains("Sharing of SonarQube statistics is disabled.");
   }
 
   private PluginInfo newPlugin(String key, String version) {
index 7a3e7df10065cf8abe323ad3736cd0a58832a261..57c07eb666f37fa5fec44ebbb0c12ee731b1acbe 100644 (file)
@@ -29,6 +29,6 @@ public class TelemetryModuleTest {
   public void verify_count_of_added_components() {
     ComponentContainer container = new ComponentContainer();
     new TelemetryModule().configure(container);
-    assertThat(container.size()).isEqualTo(2 + 2);
+    assertThat(container.size()).isEqualTo(3 + 2);
   }
 }