aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorlukasz-jarocki-sonarsource <lukasz.jarocki@sonarsource.com>2024-10-11 12:13:17 +0200
committersonartech <sonartech@sonarsource.com>2024-10-11 20:02:43 +0000
commit38a765efec578eadc53393e65f3b6b892ab83bcf (patch)
tree9b721284a44fdf5bc64a48a278fe0c8105f8c654 /server
parent3f0a34901c55eb1e204fe4028d2773f8484b513f (diff)
downloadsonarqube-38a765efec578eadc53393e65f3b6b892ab83bcf.tar.gz
sonarqube-38a765efec578eadc53393e65f3b6b892ab83bcf.zip
SONAR-23327 Added support for sending telemetry data in compute engine process
Diffstat (limited to 'server')
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReader.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderImpl.java6
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java1
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java92
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java11
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportComputationStepsTest.java2
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java111
-rw-r--r--server/sonar-ce/src/main/java/org/sonar/ce/CeTaskCommonsModule.java4
-rw-r--r--server/sonar-telemetry-core/build.gradle4
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java3
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/MessageSerializer.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/util/MessageSerializer.java)4
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/TelemetryClient.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryClient.java)36
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/AnalysisMetric.java33
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/BaseMessage.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/BaseMessage.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/InstallationMetric.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/InstallationMetric.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/LanguageMetric.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/LanguageMetric.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/Metric.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/Metric.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/ProjectMetric.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/ProjectMetric.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/UserMetric.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/UserMetric.java)2
-rw-r--r--server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/package-info.java (renamed from server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/package-info.java)2
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/TelemetryClientTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientTest.java)14
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/AnalysisMetricTest.java40
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/BaseMessageTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/BaseMessageTest.java)2
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/InstallationMetricTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/InstallationMetricTest.java)2
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/LanguageMetricTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/LanguageMetricTest.java)2
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/ProjectMetricTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/ProjectMetricTest.java)2
-rw-r--r--server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/UserMetricTest.java (renamed from server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/UserMetricTest.java)2
-rw-r--r--server/sonar-telemetry/src/it/java/org/sonar/telemetry/metrics/TelemetryMetricsLoaderIT.java10
-rw-r--r--server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java5
-rw-r--r--server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsLoader.java4
-rw-r--r--server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java10
-rw-r--r--server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientCompressionTest.java1
-rw-r--r--server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java1
-rw-r--r--server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/TelemetryMetricsMapperTest.java10
-rw-r--r--server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/util/MessageSerializerTest.java13
-rw-r--r--server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java2
36 files changed, 380 insertions, 63 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReader.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReader.java
index de85e094a67..5b908c4d4a3 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReader.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReader.java
@@ -72,4 +72,6 @@ public interface BatchReportReader {
CloseableIterator<ScannerReport.AnalysisWarning> readAnalysisWarnings();
CloseableIterator<ScannerReport.Cve> readCves();
+
+ CloseableIterator<ScannerReport.TelemetryEntry> readTelemetryEntries();
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderImpl.java
index df17a5ac89b..740d7a259d7 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderImpl.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderImpl.java
@@ -233,4 +233,10 @@ public class BatchReportReaderImpl implements BatchReportReader {
ensureInitialized();
return delegate.readCves();
}
+
+ @Override
+ public CloseableIterator<ScannerReport.TelemetryEntry> readTelemetryEntries() {
+ ensureInitialized();
+ return delegate.readTelemetryEntries();
+ }
}
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java
index 466be8f175f..00c21bd5357 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java
@@ -41,6 +41,7 @@ public class ReportComputationSteps extends AbstractComputationSteps {
private static final List<Class<? extends ComputationStep>> STEPS = Arrays.asList(
ExtractReportStep.class,
+ SendAnalysisTelemetryStep.class,
PersistScannerContextStep.class,
PersistAnalysisWarningsStep.class,
GenerateAnalysisUuid.class,
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java
new file mode 100644
index 00000000000..62700fad800
--- /dev/null
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStep.java
@@ -0,0 +1,92 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.ce.task.projectanalysis.step;
+
+import java.util.HashSet;
+import java.util.Set;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.platform.Server;
+import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
+import org.sonar.ce.task.step.ComputationStep;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.MessageSerializer;
+import org.sonar.telemetry.core.TelemetryClient;
+import org.sonar.telemetry.core.schema.AnalysisMetric;
+import org.sonar.telemetry.core.schema.BaseMessage;
+import org.sonar.telemetry.core.schema.Metric;
+
+import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_ENABLE;
+
+public class SendAnalysisTelemetryStep implements ComputationStep {
+
+ private final TelemetryClient telemetryClient;
+ private final BatchReportReader batchReportReader;
+ private final Server server;
+ private final UuidFactory uuidFactory;
+ private final Configuration config;
+
+ public SendAnalysisTelemetryStep(TelemetryClient telemetryClient, BatchReportReader batchReportReader,
+ UuidFactory uuidFactory, Server server, Configuration configuration) {
+ this.telemetryClient = telemetryClient;
+ this.batchReportReader = batchReportReader;
+ this.server = server;
+ this.uuidFactory = uuidFactory;
+ this.config = configuration;
+ }
+
+ @Override
+ public void execute(Context context) {
+ if (!config.getBoolean(SONAR_TELEMETRY_ENABLE.getKey()).orElse(false)) {
+ return;
+ }
+ try (CloseableIterator<ScannerReport.TelemetryEntry> it = batchReportReader.readTelemetryEntries()) {
+ Set<Metric> metrics = new HashSet<>();
+ // it was agreed to limit the number of telemetry entries to 1000 per one analysis
+ final int limit = 1000;
+ int count = 0;
+ while (it.hasNext() && count++ < limit) {
+ ScannerReport.TelemetryEntry telemetryEntry = it.next();
+ metrics.add(new AnalysisMetric(telemetryEntry.getKey(), telemetryEntry.getValue()));
+ }
+
+ if (metrics.isEmpty()) {
+ return;
+ }
+ BaseMessage baseMessage = new BaseMessage.Builder()
+ .setMessageUuid(uuidFactory.create())
+ .setInstallationId(server.getId())
+ .setDimension(Dimension.ANALYSIS)
+ .setMetrics(metrics)
+ .build();
+
+ String jsonString = MessageSerializer.serialize(baseMessage);
+ telemetryClient.uploadMetricAsync(jsonString);
+ }
+
+ }
+
+ @Override
+ public String getDescription() {
+ return "This step pushes telemetry data from the Sonar analyzers to Telemetry V2 server in case telemetry is enabled.";
+ }
+} \ No newline at end of file
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java
index b960803b18a..9eda82d4f2c 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/batch/BatchReportReaderRule.java
@@ -63,6 +63,7 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader, After
private List<ScannerReport.AnalysisWarning> analysisWarnings = Collections.emptyList();
private byte[] analysisCache;
private List<ScannerReport.Cve> cves = new ArrayList<>();
+ private List<ScannerReport.TelemetryEntry> telemetryEntries = new ArrayList<>();
@Override
public Statement apply(final Statement statement, Description description) {
@@ -333,6 +334,16 @@ public class BatchReportReaderRule implements TestRule, BatchReportReader, After
return CloseableIterator.from(cves.iterator());
}
+ @Override
+ public CloseableIterator<ScannerReport.TelemetryEntry> readTelemetryEntries() {
+ return CloseableIterator.from(telemetryEntries.iterator());
+ }
+
+ public BatchReportReaderRule putTelemetry(List<ScannerReport.TelemetryEntry> telemetryEntries) {
+ this.telemetryEntries = telemetryEntries;
+ return this;
+ }
+
public BatchReportReaderRule putCves(List<ScannerReport.Cve> cves) {
this.cves = cves;
return this;
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportComputationStepsTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportComputationStepsTest.java
index cdbd274b5f6..e060a69ba47 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportComputationStepsTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportComputationStepsTest.java
@@ -56,6 +56,6 @@ public class ReportComputationStepsTest {
Iterable<ComputationStep> instances = new ReportComputationSteps(computeEngineContainer).instances();
assertThatThrownBy(() -> newArrayList(instances))
.isInstanceOf(IllegalStateException.class)
- .hasMessageContaining("org.sonar.ce.task.projectanalysis.step.PersistScannerContextStep");
+ .hasMessageContaining("org.sonar.ce.task.projectanalysis.step.SendAnalysisTelemetryStep");
}
}
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java
new file mode 100644
index 00000000000..7e0c196c1bb
--- /dev/null
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendAnalysisTelemetryStepTest.java
@@ -0,0 +1,111 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.ce.task.projectanalysis.step;
+
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Set;
+import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.platform.Server;
+import org.sonar.ce.task.projectanalysis.batch.BatchReportReader;
+import org.sonar.ce.task.step.ComputationStep;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.telemetry.core.TelemetryClient;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
+import static org.mockito.Mockito.when;
+
+class SendAnalysisTelemetryStepTest {
+
+ private final TelemetryClient telemetryClient = mock();
+ private final BatchReportReader batchReportReader = mock();
+ private final UuidFactory uuidFactory = mock();
+ private final Server server = mock();
+ private final ComputationStep.Context context = mock();
+ private final Configuration configuration = mock();
+ private final SendAnalysisTelemetryStep underTest = new SendAnalysisTelemetryStep(telemetryClient, batchReportReader, uuidFactory,
+ server, configuration);
+
+ {
+ when(uuidFactory.create()).thenReturn("uuid");
+ when(server.getId()).thenReturn("serverId");
+ when(configuration.getBoolean("sonar.telemetry.enable")).thenReturn(Optional.of(true));
+ }
+
+ @Test
+ void execute_whenNoMetrics_dontSendAnything() {
+ when(batchReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.emptyCloseableIterator());
+
+ underTest.execute(context);
+
+ verifyNoInteractions(telemetryClient);
+ }
+
+ @Test
+ void execute_whenTwoMetrics_callTelemetryClientOnce() {
+ Set<ScannerReport.TelemetryEntry> telemetryEntries = Set.of(
+ ScannerReport.TelemetryEntry.newBuilder().setKey("key1").setValue("value1").build(),
+ ScannerReport.TelemetryEntry.newBuilder().setKey("key2").setValue("value2").build());
+ when(batchReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(telemetryEntries.iterator()));
+
+ underTest.execute(context);
+
+ verify(telemetryClient, times(1)).uploadMetricAsync(anyString());
+ }
+
+ @Test
+ void execute_whenMetricsPresentAndTelemetryNotEnabled_dontCallTelemetryClient() {
+ when(configuration.getBoolean("sonar.telemetry.enable")).thenReturn(Optional.of(false));
+ Set<ScannerReport.TelemetryEntry> telemetryEntries = Set.of(
+ ScannerReport.TelemetryEntry.newBuilder().setKey("key1").setValue("value1").build(),
+ ScannerReport.TelemetryEntry.newBuilder().setKey("key2").setValue("value2").build());
+ when(batchReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(telemetryEntries.iterator()));
+
+ underTest.execute(context);
+
+ verifyNoInteractions(telemetryClient);
+ }
+
+ @Test
+ void execute_when2000entries_sendOnly1000entries() {
+ Set<ScannerReport.TelemetryEntry> telemetryEntries = new HashSet<>();
+ for (int i = 0; i < 2000; i++) {
+ telemetryEntries.add(ScannerReport.TelemetryEntry.newBuilder().setKey(String.valueOf(i)).setValue("value" + i).build());
+ }
+ when(batchReportReader.readTelemetryEntries()).thenReturn(CloseableIterator.from(telemetryEntries.iterator()));
+
+ underTest.execute(context);
+
+ ArgumentCaptor<String> argumentCaptor = ArgumentCaptor.forClass(String.class);
+ verify(telemetryClient, times(1)).uploadMetricAsync(argumentCaptor.capture());
+
+ String capturedArgument = argumentCaptor.getValue();
+ assertEquals(1000 + 1, capturedArgument.split("key").length);
+ }
+}
diff --git a/server/sonar-ce/src/main/java/org/sonar/ce/CeTaskCommonsModule.java b/server/sonar-ce/src/main/java/org/sonar/ce/CeTaskCommonsModule.java
index 7a8a110c856..396a50eb5fd 100644
--- a/server/sonar-ce/src/main/java/org/sonar/ce/CeTaskCommonsModule.java
+++ b/server/sonar-ce/src/main/java/org/sonar/ce/CeTaskCommonsModule.java
@@ -23,6 +23,7 @@ import org.sonar.ce.task.projectanalysis.purge.IndexPurgeListener;
import org.sonar.ce.task.projectanalysis.purge.ProjectCleaner;
import org.sonar.core.platform.Module;
import org.sonar.db.purge.period.DefaultPeriodCleaner;
+import org.sonar.telemetry.core.TelemetryClient;
/**
* Globally available components in CE for tasks to use.
@@ -33,6 +34,7 @@ public class CeTaskCommonsModule extends Module {
add(
DefaultPeriodCleaner.class,
ProjectCleaner.class,
- IndexPurgeListener.class);
+ IndexPurgeListener.class,
+ TelemetryClient.class);
}
}
diff --git a/server/sonar-telemetry-core/build.gradle b/server/sonar-telemetry-core/build.gradle
index 47330b97821..7ae81051fd7 100644
--- a/server/sonar-telemetry-core/build.gradle
+++ b/server/sonar-telemetry-core/build.gradle
@@ -9,12 +9,16 @@ sonar {
dependencies {
compileOnlyApi 'com.github.spotbugs:spotbugs-annotations'
+ implementation project(':sonar-core')
+ implementation project(':server:sonar-process')
+
implementation 'com.fasterxml.jackson.core:jackson-databind'
testImplementation(platform("org.junit:junit-bom"))
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.junit.jupiter:junit-jupiter-api'
testImplementation 'org.junit.jupiter:junit-jupiter-params'
+ testImplementation 'org.mockito:mockito-core'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
diff --git a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java
index 96f9ce5b5fd..e3362120f22 100644
--- a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/Dimension.java
@@ -30,7 +30,8 @@ public enum Dimension {
INSTALLATION("installation"),
USER("user"),
PROJECT("project"),
- LANGUAGE("language");
+ LANGUAGE("language"),
+ ANALYSIS("analysis");
private final String value;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/util/MessageSerializer.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/MessageSerializer.java
index a55c771552c..fef42ad9077 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/util/MessageSerializer.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/MessageSerializer.java
@@ -17,12 +17,12 @@
* 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.telemetry.metrics.util;
+package org.sonar.telemetry.core;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.io.UncheckedIOException;
-import org.sonar.telemetry.metrics.schema.BaseMessage;
+import org.sonar.telemetry.core.schema.BaseMessage;
public class MessageSerializer {
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryClient.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/TelemetryClient.java
index c1a0a94ec7d..d17a103182f 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryClient.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/TelemetryClient.java
@@ -17,7 +17,7 @@
* 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.telemetry;
+package org.sonar.telemetry.core;
import java.io.IOException;
import okhttp3.Call;
@@ -32,13 +32,13 @@ import okio.Okio;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.Startable;
+import org.sonar.api.ce.ComputeEngineSide;
import org.sonar.api.config.Configuration;
import org.sonar.api.server.ServerSide;
-import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_COMPRESSION;
-import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
-import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
+import static org.sonar.process.ProcessProperties.Property;
+@ComputeEngineSide
@ServerSide
public class TelemetryClient implements Startable {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
@@ -55,17 +55,17 @@ public class TelemetryClient implements Startable {
this.okHttpClient = okHttpClient;
}
- void upload(String json) throws IOException {
+ public void upload(String json) throws IOException {
Request request = buildHttpRequest(serverUrl, json);
execute(okHttpClient.newCall(request));
}
- void uploadMetric(String json) throws IOException {
+ public void uploadMetric(String json) throws IOException {
Request request = buildHttpRequest(metricsServerUrl, json);
execute(okHttpClient.newCall(request));
}
- void optOut(String json) {
+ public void optOut(String json) {
Request.Builder request = new Request.Builder();
request.url(serverUrl);
RequestBody body = RequestBody.create(JSON, json);
@@ -121,15 +121,27 @@ public class TelemetryClient implements Startable {
@Override
public void start() {
- this.serverUrl = config.get(SONAR_TELEMETRY_URL.getKey())
- .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_URL)));
- this.metricsServerUrl = config.get(SONAR_TELEMETRY_METRICS_URL.getKey())
- .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", SONAR_TELEMETRY_METRICS_URL)));
- this.compression = config.getBoolean(SONAR_TELEMETRY_COMPRESSION.getKey()).orElse(true);
+ this.serverUrl = config.get(Property.SONAR_TELEMETRY_URL.getKey())
+ .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", Property.SONAR_TELEMETRY_URL)));
+ this.metricsServerUrl = config.get(Property.SONAR_TELEMETRY_METRICS_URL.getKey())
+ .orElseThrow(() -> new IllegalStateException(String.format("Setting '%s' must be provided.", Property.SONAR_TELEMETRY_METRICS_URL)));
+ this.compression = config.getBoolean(Property.SONAR_TELEMETRY_COMPRESSION.getKey()).orElse(true);
}
@Override
public void stop() {
// Nothing to do
}
+
+ public void uploadMetricAsync(String jsonString) {
+ Thread thread = new Thread(() -> {
+ try {
+ uploadMetric(jsonString);
+ } catch (IOException e) {
+ LOG.debug("Sending telemetry messages has failed", e);
+ }
+ });
+ thread.setDaemon(true);
+ thread.start();
+ }
}
diff --git a/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/AnalysisMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/AnalysisMetric.java
new file mode 100644
index 00000000000..66372e8ddbb
--- /dev/null
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/AnalysisMetric.java
@@ -0,0 +1,33 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.telemetry.core.schema;
+
+import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.TelemetryDataType;
+
+public class AnalysisMetric extends Metric {
+
+ public AnalysisMetric(String key, String value) {
+ this.key = key;
+ this.value = value;
+ this.type = TelemetryDataType.STRING;
+ this.granularity = Granularity.ADHOC;
+ }
+}
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/BaseMessage.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/BaseMessage.java
index 451480a8a90..11d57b49cdb 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/BaseMessage.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/BaseMessage.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.Objects;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/InstallationMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/InstallationMetric.java
index 68dc2e83590..583711d23a8 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/InstallationMetric.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/InstallationMetric.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import javax.annotation.Nullable;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/LanguageMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/LanguageMetric.java
index 236c31d7d38..0f1974b1427 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/LanguageMetric.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/LanguageMetric.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/Metric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/Metric.java
index ad5c17f5194..dfe8b7fdcfb 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/Metric.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/Metric.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/ProjectMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/ProjectMetric.java
index fc9ff8e4cd4..83eb95b491e 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/ProjectMetric.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/ProjectMetric.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/UserMetric.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/UserMetric.java
index 2af08ca023e..a9e49e0cca5 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/UserMetric.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/UserMetric.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/package-info.java b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/package-info.java
index d1b9bb184e6..4656410152f 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/schema/package-info.java
+++ b/server/sonar-telemetry-core/src/main/java/org/sonar/telemetry/core/schema/package-info.java
@@ -18,6 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
@ParametersAreNonnullByDefault
-package org.sonar.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/TelemetryClientTest.java
index ffb94d77fac..3e3c7a026eb 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/TelemetryClientTest.java
@@ -17,7 +17,7 @@
* 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.telemetry;
+package org.sonar.telemetry.core;
import java.io.IOException;
import okhttp3.MediaType;
@@ -27,12 +27,10 @@ import okio.Buffer;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
import org.sonar.api.config.internal.MapSettings;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_COMPRESSION;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_URL;
@@ -43,7 +41,7 @@ class TelemetryClientTest {
private static final String TELEMETRY_URL = "https://telemetry.com/url";
private static final String METRICS_TELEMETRY_URL = "https://telemetry.com/url/metrics";
- private final OkHttpClient okHttpClient = mock(OkHttpClient.class, RETURNS_DEEP_STUBS);
+ private final OkHttpClient okHttpClient = Mockito.mock(OkHttpClient.class, Mockito.RETURNS_DEEP_STUBS);
private final MapSettings settings = new MapSettings();
private final TelemetryClient underTest = new TelemetryClient(okHttpClient, settings.asConfig());
@@ -62,7 +60,7 @@ class TelemetryClientTest {
underTest.upload(JSON);
- verify(okHttpClient).newCall(requestCaptor.capture());
+ Mockito.verify(okHttpClient).newCall(requestCaptor.capture());
Request request = requestCaptor.getValue();
assertThat(request.method()).isEqualTo("POST");
assertThat(request.body().contentType()).isEqualTo(MediaType.parse("application/json; charset=utf-8"));
@@ -80,7 +78,7 @@ class TelemetryClientTest {
underTest.uploadMetric(JSON);
- verify(okHttpClient).newCall(requestCaptor.capture());
+ Mockito.verify(okHttpClient).newCall(requestCaptor.capture());
Request request = requestCaptor.getValue();
assertThat(request.method()).isEqualTo("POST");
assertThat(request.body().contentType()).isEqualTo(MediaType.parse("application/json; charset=utf-8"));
@@ -97,7 +95,7 @@ class TelemetryClientTest {
underTest.optOut(JSON);
- verify(okHttpClient).newCall(requestCaptor.capture());
+ Mockito.verify(okHttpClient).newCall(requestCaptor.capture());
Request request = requestCaptor.getValue();
assertThat(request.method()).isEqualTo("DELETE");
assertThat(request.body().contentType()).isEqualTo(MediaType.parse("application/json; charset=utf-8"));
diff --git a/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/AnalysisMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/AnalysisMetricTest.java
new file mode 100644
index 00000000000..13e0ee017fb
--- /dev/null
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/AnalysisMetricTest.java
@@ -0,0 +1,40 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2024 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.telemetry.core.schema;
+
+import org.junit.jupiter.api.Test;
+import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.TelemetryDataType;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class AnalysisMetricTest {
+
+ @Test
+ void getters() {
+ AnalysisMetric metric = new AnalysisMetric("memory", "100");
+
+ assertThat(metric.getKey()).isEqualTo("memory");
+ assertThat(metric.getValue()).isEqualTo("100");
+ assertThat(metric.getGranularity()).isEqualTo(Granularity.ADHOC);
+ assertThat(metric.getType()).isEqualTo(TelemetryDataType.STRING);
+ }
+}
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/BaseMessageTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/BaseMessageTest.java
index e702018f37e..0710eb8dc34 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/BaseMessageTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/BaseMessageTest.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import java.util.Set;
import java.util.stream.Collectors;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/InstallationMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/InstallationMetricTest.java
index b3ecd01b7a0..7d0b11c406a 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/InstallationMetricTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/InstallationMetricTest.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import org.junit.jupiter.api.Test;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/LanguageMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/LanguageMetricTest.java
index 832ec3d8f03..1b10608ccdc 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/LanguageMetricTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/LanguageMetricTest.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import org.junit.jupiter.api.Test;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/ProjectMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/ProjectMetricTest.java
index 7eb23fcfcf1..636b1fb2c0f 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/ProjectMetricTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/ProjectMetricTest.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import org.junit.jupiter.api.Test;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/UserMetricTest.java b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/UserMetricTest.java
index 04466d0909f..dca676a8efe 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/schema/UserMetricTest.java
+++ b/server/sonar-telemetry-core/src/test/java/org/sonar/telemetry/core/schema/UserMetricTest.java
@@ -17,7 +17,7 @@
* 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.telemetry.metrics.schema;
+package org.sonar.telemetry.core.schema;
import org.junit.jupiter.api.Test;
import org.sonar.telemetry.core.Granularity;
diff --git a/server/sonar-telemetry/src/it/java/org/sonar/telemetry/metrics/TelemetryMetricsLoaderIT.java b/server/sonar-telemetry/src/it/java/org/sonar/telemetry/metrics/TelemetryMetricsLoaderIT.java
index 67e2ea872e8..7587e7c3111 100644
--- a/server/sonar-telemetry/src/it/java/org/sonar/telemetry/metrics/TelemetryMetricsLoaderIT.java
+++ b/server/sonar-telemetry/src/it/java/org/sonar/telemetry/metrics/TelemetryMetricsLoaderIT.java
@@ -40,11 +40,11 @@ import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-import org.sonar.telemetry.metrics.schema.BaseMessage;
-import org.sonar.telemetry.metrics.schema.InstallationMetric;
-import org.sonar.telemetry.metrics.schema.LanguageMetric;
-import org.sonar.telemetry.metrics.schema.ProjectMetric;
-import org.sonar.telemetry.metrics.schema.UserMetric;
+import org.sonar.telemetry.core.schema.BaseMessage;
+import org.sonar.telemetry.core.schema.InstallationMetric;
+import org.sonar.telemetry.core.schema.LanguageMetric;
+import org.sonar.telemetry.core.schema.ProjectMetric;
+import org.sonar.telemetry.core.schema.UserMetric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java
index 4f2c42689a0..821b0bbede8 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java
+++ b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/TelemetryDaemon.java
@@ -38,12 +38,13 @@ import org.sonar.db.DbSession;
import org.sonar.server.property.InternalProperties;
import org.sonar.server.util.AbstractStoppableScheduledExecutorServiceImpl;
import org.sonar.server.util.GlobalLockManager;
+import org.sonar.telemetry.core.TelemetryClient;
import org.sonar.telemetry.legacy.TelemetryData;
import org.sonar.telemetry.legacy.TelemetryDataJsonWriter;
import org.sonar.telemetry.legacy.TelemetryDataLoader;
import org.sonar.telemetry.metrics.TelemetryMetricsLoader;
-import org.sonar.telemetry.metrics.schema.BaseMessage;
-import org.sonar.telemetry.metrics.util.MessageSerializer;
+import org.sonar.telemetry.core.schema.BaseMessage;
+import org.sonar.telemetry.core.MessageSerializer;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_ENABLE;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_FREQUENCY_IN_SECONDS;
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsLoader.java b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsLoader.java
index aeb5f3c3074..7909baaaa98 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsLoader.java
+++ b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsLoader.java
@@ -35,8 +35,8 @@ import org.sonar.db.DbSession;
import org.sonar.db.telemetry.TelemetryMetricsSentDto;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.TelemetryDataProvider;
-import org.sonar.telemetry.metrics.schema.BaseMessage;
-import org.sonar.telemetry.metrics.schema.Metric;
+import org.sonar.telemetry.core.schema.BaseMessage;
+import org.sonar.telemetry.core.schema.Metric;
import org.sonar.telemetry.metrics.util.SentMetricsStorage;
public class TelemetryMetricsLoader {
diff --git a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java
index d282608d9c2..b005743172c 100644
--- a/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java
+++ b/server/sonar-telemetry/src/main/java/org/sonar/telemetry/metrics/TelemetryMetricsMapper.java
@@ -25,11 +25,11 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataProvider;
-import org.sonar.telemetry.metrics.schema.InstallationMetric;
-import org.sonar.telemetry.metrics.schema.LanguageMetric;
-import org.sonar.telemetry.metrics.schema.Metric;
-import org.sonar.telemetry.metrics.schema.ProjectMetric;
-import org.sonar.telemetry.metrics.schema.UserMetric;
+import org.sonar.telemetry.core.schema.InstallationMetric;
+import org.sonar.telemetry.core.schema.LanguageMetric;
+import org.sonar.telemetry.core.schema.Metric;
+import org.sonar.telemetry.core.schema.ProjectMetric;
+import org.sonar.telemetry.core.schema.UserMetric;
public class TelemetryMetricsMapper {
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientCompressionTest.java b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientCompressionTest.java
index 6ac5d708553..6297d2e8cea 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientCompressionTest.java
+++ b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryClientCompressionTest.java
@@ -31,6 +31,7 @@ import okio.Okio;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.telemetry.core.TelemetryClient;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.process.ProcessProperties.Property.SONAR_TELEMETRY_METRICS_URL;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java
index bcee58e5c6f..0ae19fc5b24 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java
+++ b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/TelemetryDaemonTest.java
@@ -35,6 +35,7 @@ import org.sonar.server.property.InternalProperties;
import org.sonar.server.property.MapInternalProperties;
import org.sonar.server.util.GlobalLockManager;
import org.sonar.server.util.GlobalLockManagerImpl;
+import org.sonar.telemetry.core.TelemetryClient;
import org.sonar.telemetry.legacy.TelemetryData;
import org.sonar.telemetry.legacy.TelemetryDataJsonWriter;
import org.sonar.telemetry.legacy.TelemetryDataLoader;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/TelemetryMetricsMapperTest.java b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/TelemetryMetricsMapperTest.java
index d822623d167..d311a0e88a7 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/TelemetryMetricsMapperTest.java
+++ b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/TelemetryMetricsMapperTest.java
@@ -28,11 +28,11 @@ import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-import org.sonar.telemetry.metrics.schema.InstallationMetric;
-import org.sonar.telemetry.metrics.schema.LanguageMetric;
-import org.sonar.telemetry.metrics.schema.Metric;
-import org.sonar.telemetry.metrics.schema.ProjectMetric;
-import org.sonar.telemetry.metrics.schema.UserMetric;
+import org.sonar.telemetry.core.schema.InstallationMetric;
+import org.sonar.telemetry.core.schema.LanguageMetric;
+import org.sonar.telemetry.core.schema.Metric;
+import org.sonar.telemetry.core.schema.ProjectMetric;
+import org.sonar.telemetry.core.schema.UserMetric;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
diff --git a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/util/MessageSerializerTest.java b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/util/MessageSerializerTest.java
index 57aa2e858e0..b3563e54368 100644
--- a/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/util/MessageSerializerTest.java
+++ b/server/sonar-telemetry/src/test/java/org/sonar/telemetry/metrics/util/MessageSerializerTest.java
@@ -27,13 +27,14 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
+import org.sonar.telemetry.core.MessageSerializer;
import org.sonar.telemetry.core.TelemetryDataType;
-import org.sonar.telemetry.metrics.schema.BaseMessage;
-import org.sonar.telemetry.metrics.schema.InstallationMetric;
-import org.sonar.telemetry.metrics.schema.LanguageMetric;
-import org.sonar.telemetry.metrics.schema.Metric;
-import org.sonar.telemetry.metrics.schema.ProjectMetric;
-import org.sonar.telemetry.metrics.schema.UserMetric;
+import org.sonar.telemetry.core.schema.BaseMessage;
+import org.sonar.telemetry.core.schema.InstallationMetric;
+import org.sonar.telemetry.core.schema.LanguageMetric;
+import org.sonar.telemetry.core.schema.Metric;
+import org.sonar.telemetry.core.schema.ProjectMetric;
+import org.sonar.telemetry.core.schema.UserMetric;
import static org.sonar.test.JsonAssert.assertJson;
diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index 95e617507d1..a947a254e31 100644
--- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -291,7 +291,7 @@ import org.sonar.server.webhook.WebhookQGChangeEventListener;
import org.sonar.server.webhook.ws.WebhooksWsModule;
import org.sonar.server.ws.WebServiceEngine;
import org.sonar.server.ws.ws.WebServicesWsModule;
-import org.sonar.telemetry.TelemetryClient;
+import org.sonar.telemetry.core.TelemetryClient;
import org.sonar.telemetry.TelemetryDaemon;
import org.sonar.telemetry.legacy.CloudUsageDataProvider;
import org.sonar.telemetry.legacy.ProjectLocDistributionDataProvider;