aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-webserver-core/src
diff options
context:
space:
mode:
authoralain <108417558+alain-kermis-sonarsource@users.noreply.github.com>2022-12-19 16:48:47 +0100
committersonartech <sonartech@sonarsource.com>2022-12-19 20:02:46 +0000
commit4bdd63589597f5b32f04f02a3a32fe3e6e2927d4 (patch)
tree2baaee45d0096fa5eeda7ccc3bf29a5ab0ee99d0 /server/sonar-webserver-core/src
parent590d662a839a255957e72624001e18ba3338a6b5 (diff)
downloadsonarqube-4bdd63589597f5b32f04f02a3a32fe3e6e2927d4.tar.gz
sonarqube-4bdd63589597f5b32f04f02a3a32fe3e6e2927d4.zip
SONAR-17735 Telemetry improvements
Diffstat (limited to 'server/sonar-webserver-core/src')
-rw-r--r--server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java18
-rw-r--r--server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java17
-rw-r--r--server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java32
-rw-r--r--server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java42
4 files changed, 65 insertions, 44 deletions
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
index 1a5c0296c75..106e97d0fd7 100644
--- a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
+++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDaemon.java
@@ -50,6 +50,7 @@ public class TelemetryDaemon implements Startable {
private static final String LOCK_NAME = "TelemetryStat";
private static final Logger LOG = Loggers.get(TelemetryDaemon.class);
private static final String LOCK_DELAY_SEC = "sonar.telemetry.lock.delay";
+ static final String I_PROP_MESSAGE_SEQUENCE = "telemetry.messageSeq";
private final TelemetryDataLoader dataLoader;
private final TelemetryDataJsonWriter dataJsonWriter;
@@ -125,7 +126,7 @@ public class TelemetryDaemon implements Startable {
long now = system2.now();
if (shouldUploadStatistics(now)) {
uploadStatistics();
- internalProperties.write(I_PROP_LAST_PING, String.valueOf(now));
+ updateTelemetryProps(now);
}
} catch (Exception e) {
LOG.debug("Error while checking SonarQube statistics: {}", e);
@@ -134,6 +135,19 @@ public class TelemetryDaemon implements Startable {
};
}
+ private void updateTelemetryProps(long now) {
+ internalProperties.write(I_PROP_LAST_PING, String.valueOf(now));
+
+ Optional<String> currentSequence = internalProperties.read(I_PROP_MESSAGE_SEQUENCE);
+ if (currentSequence.isEmpty()) {
+ internalProperties.write(I_PROP_MESSAGE_SEQUENCE, String.valueOf(1));
+ return;
+ }
+
+ long current = Long.parseLong(currentSequence.get());
+ internalProperties.write(I_PROP_MESSAGE_SEQUENCE, String.valueOf(current + 1));
+ }
+
private void optOut() {
StringWriter json = new StringWriter();
try (JsonWriter writer = JsonWriter.of(json)) {
@@ -155,7 +169,7 @@ public class TelemetryDaemon implements Startable {
private boolean shouldUploadStatistics(long now) {
Optional<Long> lastPing = internalProperties.read(I_PROP_LAST_PING).map(Long::valueOf);
- return !lastPing.isPresent() || now - lastPing.get() >= ONE_DAY;
+ return lastPing.isEmpty() || now - lastPing.get() >= ONE_DAY;
}
private int frequency() {
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java
index 21f524078b1..147d0a7c39a 100644
--- a/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java
+++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/telemetry/TelemetryDataLoaderImpl.java
@@ -29,8 +29,6 @@ import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
import javax.inject.Inject;
import org.sonar.api.config.Configuration;
import org.sonar.api.platform.Server;
@@ -59,6 +57,7 @@ import static org.sonar.core.config.CorePropertyDefinitions.SONAR_ANALYSIS_DETEC
import static org.sonar.core.platform.EditionProvider.Edition.COMMUNITY;
import static org.sonar.core.platform.EditionProvider.Edition.DATACENTER;
import static org.sonar.core.platform.EditionProvider.Edition.ENTERPRISE;
+import static org.sonar.server.telemetry.TelemetryDaemon.I_PROP_MESSAGE_SEQUENCE;
@ServerSide
public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
@@ -79,14 +78,11 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
private final Configuration configuration;
private final InternalProperties internalProperties;
private final DockerSupport dockerSupport;
- @CheckForNull
- private final LicenseReader licenseReader;
-
@Inject
public TelemetryDataLoaderImpl(Server server, DbClient dbClient, PluginRepository pluginRepository,
PlatformEditionProvider editionProvider, InternalProperties internalProperties, Configuration configuration,
- DockerSupport dockerSupport, @Nullable LicenseReader licenseReader) {
+ DockerSupport dockerSupport) {
this.server = server;
this.dbClient = dbClient;
this.pluginRepository = pluginRepository;
@@ -94,7 +90,6 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
this.internalProperties = internalProperties;
this.configuration = configuration;
this.dockerSupport = dockerSupport;
- this.licenseReader = licenseReader;
}
private static Database loadDatabaseMetadata(DbSession dbSession) {
@@ -110,12 +105,10 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
public TelemetryData load() {
TelemetryData.Builder data = TelemetryData.builder();
+ data.setMessageSequenceNumber(retrieveCurrentMessageSequenceNumber() + 1);
data.setServerId(server.getId());
data.setVersion(server.getVersion());
data.setEdition(editionProvider.get().orElse(null));
- ofNullable(licenseReader)
- .flatMap(reader -> licenseReader.read())
- .ifPresent(license -> data.setLicenseType(license.getType()));
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);
@@ -140,6 +133,10 @@ public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
.build();
}
+ private Long retrieveCurrentMessageSequenceNumber() {
+ return internalProperties.read(I_PROP_MESSAGE_SEQUENCE).map(Long::parseLong).orElse(0L);
+ }
+
private void resolveProjectStatistics(TelemetryData.Builder data, DbSession dbSession) {
List<String> projectUuids = dbClient.projectDao().selectAllProjectUuids(dbSession);
Map<String, String> scmByProject = getAnalysisPropertyByProject(dbSession, SONAR_ANALYSIS_DETECTEDSCM);
diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
index ba4186af014..330bcaa0614 100644
--- a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
+++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDaemonTest.java
@@ -62,6 +62,7 @@ public class TelemetryDaemonTest {
private static final TelemetryData SOME_TELEMETRY_DATA = TelemetryData.builder()
.setServerId("foo")
.setVersion("bar")
+ .setMessageSequenceNumber(1L)
.setPlugins(Collections.emptyMap())
.setDatabase(new TelemetryData.Database("H2", "11"))
.build();
@@ -153,6 +154,7 @@ public class TelemetryDaemonTest {
long oneDayAgo = today - ONE_DAY - ONE_HOUR;
internalProperties.write("telemetry.lastPing", String.valueOf(oneDayAgo));
reset(internalProperties);
+ when(dataLoader.load()).thenReturn(SOME_TELEMETRY_DATA);
mockDataJsonWriterDoingSomething();
underTest.start();
@@ -177,6 +179,36 @@ public class TelemetryDaemonTest {
assertThat(logger.logs(LoggerLevel.INFO)).contains("Sharing of SonarQube statistics is disabled.");
}
+ @Test
+ public void write_sequence_as_one_if_not_previously_present() {
+ initTelemetrySettingsToDefaultValues();
+ when(lockManager.tryLock(any(), anyInt())).thenReturn(true);
+ settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
+ mockDataJsonWriterDoingSomething();
+
+ underTest.start();
+
+ verify(internalProperties, timeout(4_000)).write("telemetry.messageSeq", "1");
+ }
+
+ @Test
+ public void write_sequence_correctly_incremented() {
+ initTelemetrySettingsToDefaultValues();
+ when(lockManager.tryLock(any(), anyInt())).thenReturn(true);
+ settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
+ internalProperties.write("telemetry.messageSeq", "10");
+ mockDataJsonWriterDoingSomething();
+
+ underTest.start();
+
+ verify(internalProperties, timeout(4_000)).write("telemetry.messageSeq", "10");
+
+ // force another ping
+ internalProperties.write("telemetry.lastPing", String.valueOf(system2.now() - ONE_DAY));
+
+ verify(internalProperties, timeout(4_000)).write("telemetry.messageSeq", "11");
+ }
+
private void initTelemetrySettingsToDefaultValues() {
settings.setProperty(SONAR_TELEMETRY_ENABLE.getKey(), SONAR_TELEMETRY_ENABLE.getDefaultValue());
settings.setProperty(SONAR_TELEMETRY_URL.getKey(), SONAR_TELEMETRY_URL.getDefaultValue());
diff --git a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java
index 1e384cdeba6..34ceb0b210c 100644
--- a/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java
+++ b/server/sonar-webserver-core/src/test/java/org/sonar/server/telemetry/TelemetryDataLoaderImplTest.java
@@ -55,7 +55,6 @@ import org.sonar.server.property.MapInternalProperties;
import org.sonar.updatecenter.common.Version;
import static java.util.Arrays.asList;
-import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
@@ -91,12 +90,11 @@ public class TelemetryDataLoaderImplTest {
private final PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
private final DockerSupport dockerSupport = mock(DockerSupport.class);
private final InternalProperties internalProperties = spy(new MapInternalProperties());
- private final LicenseReader licenseReader = mock(LicenseReader.class);
private final TelemetryDataLoader communityUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, dockerSupport, null);
+ internalProperties, configuration, dockerSupport);
private final TelemetryDataLoader commercialUnderTest = new TelemetryDataLoaderImpl(server, db.getDbClient(), pluginRepository, editionProvider,
- internalProperties, configuration, dockerSupport, licenseReader);
+ internalProperties, configuration, dockerSupport);
@Test
public void send_telemetry_data() {
@@ -157,6 +155,7 @@ public class TelemetryDataLoaderImplTest {
assertThat(data.getServerId()).isEqualTo(serverId);
assertThat(data.getVersion()).isEqualTo(version);
assertThat(data.getEdition()).contains(DEVELOPER);
+ assertThat(data.getMessageSequenceNumber()).isOne();
assertDatabaseMetadata(data.getDatabase());
assertThat(data.getPlugins()).containsOnly(
entry("java", "4.12.0.11033"), entry("scmgit", "1.2"), entry("other", "undefined"));
@@ -247,22 +246,6 @@ public class TelemetryDataLoaderImplTest {
}
@Test
- public void data_contains_no_license_type_on_community_edition() {
- TelemetryData data = communityUnderTest.load();
-
- assertThat(data.getLicenseType()).isEmpty();
- }
-
- @Test
- public void data_contains_no_license_type_on_commercial_edition_if_no_license() {
- when(licenseReader.read()).thenReturn(Optional.empty());
-
- TelemetryData data = commercialUnderTest.load();
-
- assertThat(data.getLicenseType()).isEmpty();
- }
-
- @Test
public void data_contains_weekly_count_sonarlint_users() {
db.users().insertUser(c -> c.setLastSonarlintConnectionDate(NOW - 100_000L));
db.users().insertUser(c -> c.setLastSonarlintConnectionDate(NOW));
@@ -276,18 +259,6 @@ public class TelemetryDataLoaderImplTest {
}
@Test
- public void data_has_license_type_on_commercial_edition_if_no_license() {
- String licenseType = randomAlphabetic(12);
- LicenseReader.License license = mock(LicenseReader.License.class);
- when(license.getType()).thenReturn(licenseType);
- when(licenseReader.read()).thenReturn(Optional.of(license));
-
- TelemetryData data = commercialUnderTest.load();
-
- assertThat(data.getLicenseType()).contains(licenseType);
- }
-
- @Test
public void send_server_id_and_version() {
String id = randomAlphanumeric(40);
String version = randomAlphanumeric(10);
@@ -317,6 +288,13 @@ public class TelemetryDataLoaderImplTest {
}
@Test
+ public void send_correct_sequence_number() {
+ internalProperties.write(TelemetryDaemon.I_PROP_MESSAGE_SEQUENCE, "10");
+ TelemetryData data = communityUnderTest.load();
+ assertThat(data.getMessageSequenceNumber()).isEqualTo(11L);
+ }
+
+ @Test
public void do_not_send_server_installation_details_if_missing_property() {
TelemetryData data = communityUnderTest.load();
assertThat(data.getInstallationDate()).isNull();