]> source.dussan.org Git - sonarqube.git/commitdiff
Added monitoring and telemetry to SonarLint push feature. (#5315)
authorlukasz-jarocki-sonarsource <77498856+lukasz-jarocki-sonarsource@users.noreply.github.com>
Thu, 3 Feb 2022 09:35:15 +0000 (10:35 +0100)
committersonartech <sonartech@sonarsource.com>
Fri, 18 Feb 2022 15:48:03 +0000 (15:48 +0000)
* SONAR-15921 add number of connected sonarlint clients to telemetry

17 files changed:
server/sonar-server-common/src/main/java/org/sonar/server/telemetry/TelemetryData.java
server/sonar-server-common/src/test/java/org/sonar/server/telemetry/TelemetryDataJsonWriterTest.java
server/sonar-webserver-core/build.gradle
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/SystemInfoWriterModule.java
server/sonar-webserver-core/src/main/java/org/sonar/server/platform/monitoring/cluster/ServerPushSection.java [new file with mode: 0644]
server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/SystemInfoWriterModuleTest.java
server/sonar-webserver-core/src/test/java/org/sonar/server/platform/monitoring/ServerPushSectionTest.java [new file with mode: 0644]
server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java
server/sonar-webserver-monitoring/build.gradle
server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/ServerMonitoringMetrics.java
server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/SonarLintConnectedClientsTask.java [new file with mode: 0644]
server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/ServerMonitoringMetricsTest.java
server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/SonarLintConnectedClientsTaskTest.java [new file with mode: 0644]
server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/sonarlint/SonarLintClientsRegistry.java
server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/sonarlint/SonarLintClientsRegistryTest.java
server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java

index 3f6d947a20a2b3cacc0bfc09ec0b8c75036180fe..89d5f72413036db834e27c7082e3b1aedb7093a9 100644 (file)
@@ -54,6 +54,7 @@ public class TelemetryData {
   private final Boolean hasUnanalyzedCpp;
   private final List<String> customSecurityConfigs;
   private final long sonarlintWeeklyUsers;
+  private final long numberOfConnectedSonarLintClients;
 
   private TelemetryData(Builder builder) {
     serverId = builder.serverId;
@@ -79,6 +80,7 @@ public class TelemetryData {
     externalAuthenticationProviders = builder.externalAuthenticationProviders;
     projectCountByScm = builder.projectCountByScm;
     projectCountByCi = builder.projectCountByCi;
+    numberOfConnectedSonarLintClients = builder.numberOfConnectedSonarLintClients;
   }
 
   public String getServerId() {
@@ -101,6 +103,10 @@ public class TelemetryData {
     return sonarlintWeeklyUsers;
   }
 
+  public long sonarLintConnectedClients() {
+    return numberOfConnectedSonarLintClients;
+  }
+
   public long getUserCount() {
     return userCount;
   }
@@ -199,6 +205,7 @@ public class TelemetryData {
     private List<String> externalAuthenticationProviders;
     private Map<String, Long> projectCountByScm;
     private Map<String, Long> projectCountByCi;
+    private long numberOfConnectedSonarLintClients;
 
     private Builder() {
       // enforce static factory method
@@ -309,6 +316,11 @@ public class TelemetryData {
       return this;
     }
 
+    Builder setNumberOfConnectedSonarLintClients(long numberOfConnectedSonarLintClients) {
+      this.numberOfConnectedSonarLintClients = numberOfConnectedSonarLintClients;
+      return this;
+    }
+
     TelemetryData build() {
       requireNonNull(serverId);
       requireNonNull(version);
index 807625a31c1f1bbbd0c08595062fdb81ce327604..aa280713ec127e83a7cdd7d1852ec8c8c0f285a3 100644 (file)
@@ -60,6 +60,7 @@ public class TelemetryDataJsonWriterTest {
     .setExternalAuthenticationProviders(asList("github", "gitlab"))
     .setProjectCountByScm(Collections.emptyMap())
     .setSonarlintWeeklyUsers(10)
+    .setNumberOfConnectedSonarLintClients(5)
     .setProjectCountByCi(Collections.emptyMap())
     .setDatabase(new TelemetryData.Database("H2", "11"))
     .setUsingBranches(true);
index 7b9f8fc6c6b48062984680dceac762a0689cad8c..9aba24d6f0c8a631af4217117d76584174d9a563 100644 (file)
@@ -42,6 +42,7 @@ dependencies {
   compile project(':server:sonar-process')
   compile project(':server:sonar-server-common')
   compile project(':server:sonar-webserver-api')
+  compile project(':server:sonar-webserver-pushapi')
   compile project(':server:sonar-webserver-es')
   compile project(':sonar-core')
   compile project(':sonar-duplications')
index 73ec7490ac5dd8722f9ff76b5e70aa194da22f66..c0602d1315ec436a4b3ece2933254dcaeaed2c42 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.server.platform.monitoring.cluster.CeQueueGlobalSection;
 import org.sonar.server.platform.monitoring.cluster.EsClusterStateSection;
 import org.sonar.server.platform.monitoring.cluster.GlobalInfoLoader;
 import org.sonar.server.platform.monitoring.cluster.GlobalSystemSection;
+import org.sonar.server.platform.monitoring.cluster.ServerPushSection;
 import org.sonar.server.platform.monitoring.cluster.NodeSystemSection;
 import org.sonar.server.platform.monitoring.cluster.ProcessInfoProvider;
 import org.sonar.server.platform.monitoring.cluster.SearchNodesInfoLoaderImpl;
@@ -62,6 +63,7 @@ public class SystemInfoWriterModule extends Module {
       PluginsSection.class,
       SettingsSection.class,
       AlmConfigurationSection.class,
+      ServerPushSection.class,
       BundledSection.class
 
       );
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/monitoring/cluster/ServerPushSection.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/platform/monitoring/cluster/ServerPushSection.java
new file mode 100644 (file)
index 0000000..fe94bf7
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.platform.monitoring.cluster;
+
+import org.sonar.api.server.ServerSide;
+import org.sonar.process.systeminfo.SystemInfoSection;
+import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
+import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
+
+import static org.sonar.process.systeminfo.SystemInfoUtils.setAttribute;
+
+@ServerSide
+public class ServerPushSection implements SystemInfoSection {
+
+  private final SonarLintClientsRegistry sonarLintClientsRegistry;
+
+  public ServerPushSection(SonarLintClientsRegistry sonarLintClientsRegistry) {
+    this.sonarLintClientsRegistry = sonarLintClientsRegistry;
+  }
+
+  @Override
+  public ProtobufSystemInfo.Section toProtobuf() {
+    ProtobufSystemInfo.Section.Builder protobuf = ProtobufSystemInfo.Section.newBuilder();
+    protobuf.setName("Server Push Connections");
+    setAttribute(protobuf, "SonarLint Connected Clients", sonarLintClientsRegistry.countConnectedClients());
+    return protobuf.build();
+  }
+}
index d3813e8150ab04b7a948f0027a4206dd9829951f..ab9ec5daaa623d4b356b99f4723d013a168beddd 100644 (file)
@@ -76,13 +76,13 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
   private final LicenseReader licenseReader;
 
   public TelemetryDataLoaderImpl(Server server, DbClient dbClient, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex,
-                                 PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration, DockerSupport dockerSupport) {
+    PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration, DockerSupport dockerSupport) {
     this(server, dbClient, pluginRepository, userIndex, projectMeasuresIndex, editionProvider, internalProperties, configuration, dockerSupport, null);
   }
 
   public TelemetryDataLoaderImpl(Server server, DbClient dbClient, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex,
-                                 PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration,
-                                 DockerSupport dockerSupport, @Nullable LicenseReader licenseReader) {
+    PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration,
+    DockerSupport dockerSupport, @Nullable LicenseReader licenseReader) {
     this.server = server;
     this.dbClient = dbClient;
     this.pluginRepository = pluginRepository;
index 323c4eb34035eebe8adba33ccf4232bfde29eb25..1d586a9ac43c9fec97a1a69d255e61e5c829678e 100644 (file)
@@ -42,7 +42,7 @@ public class SystemInfoWriterModuleTest {
 
     Collection<ComponentAdapter<?>> adapters = container.getPicoContainer().getComponentAdapters();
     assertThat(adapters)
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 19);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 20);
   }
 
   @Test
@@ -54,7 +54,7 @@ public class SystemInfoWriterModuleTest {
 
     Collection<ComponentAdapter<?>> adapters = container.getPicoContainer().getComponentAdapters();
     assertThat(adapters)
-      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 13);
+      .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 14);
   }
 
 }
diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/monitoring/ServerPushSectionTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/platform/monitoring/ServerPushSectionTest.java
new file mode 100644 (file)
index 0000000..1d3b61d
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.platform.monitoring;
+
+import org.junit.Test;
+import org.sonar.process.systeminfo.protobuf.ProtobufSystemInfo;
+import org.sonar.server.platform.monitoring.cluster.ServerPushSection;
+import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ServerPushSectionTest {
+
+  private final SonarLintClientsRegistry sonarLintClientsRegistry = mock(SonarLintClientsRegistry.class);
+
+  private final ServerPushSection underTest = new ServerPushSection(sonarLintClientsRegistry);
+
+  @Test
+  public void toProtobuf_with5ConnectedSonarLintClients() {
+
+    when(sonarLintClientsRegistry.countConnectedClients()).thenReturn(5L);
+
+    ProtobufSystemInfo.Section section = underTest.toProtobuf();
+
+    assertThat(section.getName()).isEqualTo("Server Push Connections");
+    assertThat(section.getAttributesList())
+      .extracting(ProtobufSystemInfo.Attribute::getKey, ProtobufSystemInfo.Attribute::getLongValue)
+      .containsExactlyInAnyOrder(tuple("SonarLint Connected Clients", 5L));
+  }
+}
index 1d3fac27fe6c9575ee826b0f4e42076443b3cbfc..0ba187b297152c52aca6ec6161aefd68ea56e173 100644 (file)
@@ -41,6 +41,7 @@ import org.sonar.server.measure.index.ProjectMeasuresIndexer;
 import org.sonar.server.platform.DockerSupport;
 import org.sonar.server.property.InternalProperties;
 import org.sonar.server.property.MapInternalProperties;
+import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
 import org.sonar.server.user.index.UserIndex;
 import org.sonar.server.user.index.UserIndexer;
 import org.sonar.updatecenter.common.Version;
@@ -85,7 +86,7 @@ public class TelemetryDataLoaderImplTest {
   private final LicenseReader licenseReader = mock(LicenseReader.class);
 
   private final TelemetryDataLoader communityUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, new UserIndex(es.client(), system2),
-    new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, internalProperties, configuration, dockerSupport, null);
+    new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, internalProperties, configuration, dockerSupport);
   private final TelemetryDataLoader commercialUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, new UserIndex(es.client(), system2),
     new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, internalProperties, configuration, dockerSupport, licenseReader);
 
index 3f84d115f8d7606f86bb845c232a2cd5b0b4bd21..45541df8947528f09518d5fd73c3cd6a60049058 100644 (file)
@@ -3,6 +3,7 @@ description = 'SonarQube :: Monitoring'
 dependencies {
     compile project(path: ':sonar-plugin-api', configuration: 'shadow')
     compile project(':server:sonar-webserver-api')
+    compile project(':server:sonar-webserver-pushapi')
     compile project(':server:sonar-alm-client')
     compile 'io.prometheus:simpleclient'
 
index afa858d45335ae88fbede56c50924091fb0ab713..e01cd37de661cb4452b84ea83705899f1f712ff3 100644 (file)
@@ -46,6 +46,8 @@ public class ServerMonitoringMetrics {
 
   private final Gauge webUptimeMinutes;
 
+  private final Gauge numberOfConnectedSonarLintClients;
+
   public ServerMonitoringMetrics() {
     githubHealthIntegrationStatus = Gauge.build()
       .name("sonarqube_health_integration_github_status")
@@ -120,6 +122,11 @@ public class ServerMonitoringMetrics {
       .help("Number of minutes for how long the SonarQube instance is running")
       .register();
 
+    numberOfConnectedSonarLintClients = Gauge.build()
+      .name("sonarqube_number_of_connected_sonarlint_clients")
+      .help("Number of connected SonarLint clients")
+      .register();
+
   }
 
   public void setGithubStatusToGreen() {
@@ -201,4 +208,8 @@ public class ServerMonitoringMetrics {
   public void setWebUptimeMinutes(long minutes) {
     webUptimeMinutes.set(minutes);
   }
+
+  public void setNumberOfConnectedSonarLintClients(long noOfClients) {
+    numberOfConnectedSonarLintClients.set(noOfClients);
+  }
 }
diff --git a/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/SonarLintConnectedClientsTask.java b/server/sonar-webserver-monitoring/src/main/java/org/sonar/server/monitoring/SonarLintConnectedClientsTask.java
new file mode 100644 (file)
index 0000000..3a98292
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.monitoring;
+
+import org.sonar.api.config.Configuration;
+import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
+
+public class SonarLintConnectedClientsTask implements MonitoringTask {
+
+  private static final String DELAY_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.other.initial.delay";
+  private static final String PERIOD_IN_MILISECONDS_PROPERTY = "sonar.server.monitoring.other.period";
+
+  private final ServerMonitoringMetrics serverMonitoringMetrics;
+  private final SonarLintClientsRegistry sonarLintClientsRegistry;
+  private final Configuration config;
+
+  public SonarLintConnectedClientsTask(ServerMonitoringMetrics serverMonitoringMetrics, SonarLintClientsRegistry sonarLintClientsRegistry,
+    Configuration configuration) {
+    this.serverMonitoringMetrics = serverMonitoringMetrics;
+    this.sonarLintClientsRegistry = sonarLintClientsRegistry;
+    this.config = configuration;
+  }
+
+  @Override
+  public void run() {
+    serverMonitoringMetrics.setNumberOfConnectedSonarLintClients(sonarLintClientsRegistry.countConnectedClients());
+  }
+
+  @Override
+  public long getDelay() {
+    return config.getLong(DELAY_IN_MILISECONDS_PROPERTY).orElse(10_000L);
+  }
+
+  @Override
+  public long getPeriod() {
+    return config.getLong(PERIOD_IN_MILISECONDS_PROPERTY).orElse(10_000L);
+  }
+}
index 83c324313db7e35daedf1974bd2c4442545162fc..338d097d52b0576c4421e22f02595353d2bd51e7 100644 (file)
@@ -119,6 +119,16 @@ public class ServerMonitoringMetricsTest {
       .isEqualTo(10);
   }
 
+  @Test
+  public void setters_setNumberOfConnectedSonarLintClients() {
+    ServerMonitoringMetrics metrics = new ServerMonitoringMetrics();
+
+    metrics.setNumberOfConnectedSonarLintClients(5);
+
+    assertThat(CollectorRegistry.defaultRegistry.getSampleValue("sonarqube_number_of_connected_sonarlint_clients"))
+      .isEqualTo(5);
+  }
+
   @Test
   public void setters_setElasticsearchMetricsWithLabels() {
     ServerMonitoringMetrics metrics = new ServerMonitoringMetrics();
diff --git a/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/SonarLintConnectedClientsTaskTest.java b/server/sonar-webserver-monitoring/src/test/java/org/sonar/server/monitoring/SonarLintConnectedClientsTaskTest.java
new file mode 100644 (file)
index 0000000..a6a0250
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.monitoring;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+import org.junit.Test;
+import org.sonar.api.config.Configuration;
+import org.sonar.server.pushapi.sonarlint.SonarLintClientsRegistry;
+
+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;
+
+public class SonarLintConnectedClientsTaskTest {
+
+  private final ServerMonitoringMetrics metrics = mock(ServerMonitoringMetrics.class);
+  private final SonarLintClientsRegistry sonarLintClientsRegistry = mock(SonarLintClientsRegistry.class);
+  private final SonarLintConnectedClientsTaskTest.DumpMapConfiguration config = new SonarLintConnectedClientsTaskTest.DumpMapConfiguration();
+  private final SonarLintConnectedClientsTask underTest = new SonarLintConnectedClientsTask(metrics, sonarLintClientsRegistry, config);
+
+  @Test
+  public void run_when5ConnectedClients_updateWith5() {
+    when(sonarLintClientsRegistry.countConnectedClients()).thenReturn(5L);
+
+    underTest.run();
+
+    verify(metrics).setNumberOfConnectedSonarLintClients(5L);
+  }
+
+  @Test
+  public void getDelay_returnNumberIfConfigEmpty() {
+    long delay = underTest.getDelay();
+
+    assertThat(delay).isPositive();
+  }
+
+  @Test
+  public void getDelay_returnNumberFromConfig() {
+    config.put("sonar.server.monitoring.other.initial.delay", "100000");
+
+    long delay = underTest.getDelay();
+
+    assertThat(delay).isEqualTo(100_000L);
+  }
+
+  @Test
+  public void getPeriod_returnNumberIfConfigEmpty() {
+    long delay = underTest.getPeriod();
+
+    assertThat(delay).isPositive();
+  }
+
+  @Test
+  public void getPeriod_returnNumberFromConfig() {
+    config.put("sonar.server.monitoring.other.period", "100000");
+
+    long delay = underTest.getPeriod();
+
+    assertThat(delay).isEqualTo(100_000L);
+  }
+
+  private static class DumpMapConfiguration implements Configuration {
+    private final Map<String, String> keyValues = new HashMap<>();
+
+    public Configuration put(String key, String value) {
+      keyValues.put(key, value.trim());
+      return this;
+    }
+
+    @Override
+    public Optional<String> get(String key) {
+      return Optional.ofNullable(keyValues.get(key));
+    }
+
+    @Override
+    public boolean hasKey(String key) {
+      throw new UnsupportedOperationException("hasKey not implemented");
+    }
+
+    @Override
+    public String[] getStringArray(String key) {
+      throw new UnsupportedOperationException("getStringArray not implemented");
+    }
+  }
+
+}
index 44d9fa4917d33a7c86a7a865a5eb427dccce4756..b3319ddc5794614530f5ce1b8b7241c91a5e2d52 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.server.pushapi.sonarlint;
 
-import com.google.common.annotations.VisibleForTesting;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import javax.servlet.AsyncEvent;
@@ -47,9 +46,8 @@ public class SonarLintClientsRegistry {
     LOG.debug("Removing SonarLint client");
   }
 
-  @VisibleForTesting
-  List<SonarLintClient> getAllClients() {
-    return clients;
+  public long countConnectedClients() {
+    return clients.size();
   }
 
   class SonarLintClientEventsListener implements AsyncListener {
index f6f0ccd68f71762b6321a3a55df96d4bb6f9d57c..a70886166eacdd2b68e14b531aaf98729aa13832 100644 (file)
@@ -48,11 +48,11 @@ public class SonarLintClientsRegistryTest {
 
     underTest.registerClient(sonarLintClient);
 
-    assertThat(underTest.getAllClients()).hasSize(1);
+    assertThat(underTest.countConnectedClients()).isEqualTo(1);
 
     underTest.unregisterClient(sonarLintClient);
 
-    assertThat(underTest.getAllClients()).isEmpty();
+    assertThat(underTest.countConnectedClients()).isZero();
   }
 
   @Test
@@ -63,7 +63,7 @@ public class SonarLintClientsRegistryTest {
       underTest.registerClient(sonarLintClient);
     }
 
-    assertThat(underTest.getAllClients()).hasSize(10);
+    assertThat(underTest.countConnectedClients()).isEqualTo(10);
   }
 
 }
index 5937ac9295f43b1bd855eaa5224375074df39ada..f5c1bde9d9bdfc549476424974bb514fefbba64a 100644 (file)
@@ -131,6 +131,7 @@ import org.sonar.server.monitoring.ElasticSearchMetricTask;
 import org.sonar.server.monitoring.MainCollector;
 import org.sonar.server.monitoring.MonitoringWsModule;
 import org.sonar.server.monitoring.ServerMonitoringMetrics;
+import org.sonar.server.monitoring.SonarLintConnectedClientsTask;
 import org.sonar.server.monitoring.WebUptimeTask;
 import org.sonar.server.monitoring.ce.NumberOfTasksInQueueTask;
 import org.sonar.server.monitoring.ce.RecentTasksDurationTask;
@@ -603,6 +604,7 @@ public class PlatformLevel4 extends PlatformLevel {
       ComputeEngineMetricStatusTask.class,
       ElasticSearchMetricTask.class,
       WebUptimeTask.class,
+      SonarLintConnectedClientsTask.class,
 
       MainCollector.class,