import java.sql.SQLException;
import java.util.Map;
import java.util.function.Function;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.sonar.api.platform.Server;
import org.sonar.api.server.ServerSide;
import org.sonar.core.platform.PlatformEditionProvider;
import org.sonar.server.user.index.UserIndex;
import org.sonar.server.user.index.UserQuery;
+import static java.util.Optional.ofNullable;
+
@ServerSide
public class TelemetryDataLoader {
private final Server server;
private final ProjectMeasuresIndex projectMeasuresIndex;
private final PlatformEditionProvider editionProvider;
private final DefaultOrganizationProvider defaultOrganizationProvider;
+ @CheckForNull
+ private final LicenseReader licenseReader;
public TelemetryDataLoader(Server server, DbClient dbClient, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex,
PlatformEditionProvider editionProvider, DefaultOrganizationProvider defaultOrganizationProvider) {
+ this(server, dbClient, pluginRepository, userIndex, projectMeasuresIndex, editionProvider, defaultOrganizationProvider, null);
+ }
+
+ public TelemetryDataLoader(Server server, DbClient dbClient, PluginRepository pluginRepository, UserIndex userIndex, ProjectMeasuresIndex projectMeasuresIndex,
+ PlatformEditionProvider editionProvider, DefaultOrganizationProvider defaultOrganizationProvider, @Nullable LicenseReader licenseReader) {
this.server = server;
this.dbClient = dbClient;
this.pluginRepository = pluginRepository;
this.projectMeasuresIndex = projectMeasuresIndex;
this.editionProvider = editionProvider;
this.defaultOrganizationProvider = defaultOrganizationProvider;
+ this.licenseReader = licenseReader;
}
public TelemetryData load() {
data.setServerId(server.getId());
data.setVersion(server.getVersion());
data.setEdition(editionProvider.get());
+ 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);
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
-import org.sonar.api.config.Configuration;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.api.utils.log.LogTester;
import static java.util.Arrays.asList;
import static java.util.Collections.emptySet;
+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.mockito.ArgumentMatchers.anyString;
private static final long ONE_HOUR = 60 * 60 * 1_000L;
private static final long ONE_DAY = 24 * ONE_HOUR;
- private static final Configuration emptyConfig = new MapSettings().asConfig();
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
private UserIndexer userIndexer = new UserIndexer(db.getDbClient(), es.client());
private PlatformEditionProvider editionProvider = mock(PlatformEditionProvider.class);
- private final TelemetryDataLoader dataLoader = new TelemetryDataLoader(server, db.getDbClient(), pluginRepository, new UserIndex(es.client(), system2),
- new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, new DefaultOrganizationProviderImpl(db.getDbClient()));
- private TelemetryDaemon underTest = new TelemetryDaemon(dataLoader, client, settings.asConfig(), internalProperties, system2);
+ private final TelemetryDataLoader communityDataLoader = new TelemetryDataLoader(server, db.getDbClient(), pluginRepository, new UserIndex(es.client(), system2),
+ new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, new DefaultOrganizationProviderImpl(db.getDbClient()), null);
+ private TelemetryDaemon communityUnderTest = new TelemetryDaemon(communityDataLoader, client, settings.asConfig(), internalProperties, system2);
+
+ private final LicenseReader licenseReader = mock(LicenseReader.class);
+ private final TelemetryDataLoader commercialDataLoader = new TelemetryDataLoader(server, db.getDbClient(), pluginRepository, new UserIndex(es.client(), system2),
+ new ProjectMeasuresIndex(es.client(), null, system2), editionProvider, new DefaultOrganizationProviderImpl(db.getDbClient()), licenseReader);
+ private TelemetryDaemon commercialUnderTest = new TelemetryDaemon(commercialDataLoader, client, settings.asConfig(), internalProperties, system2);
@After
public void tearDown() {
- underTest.stop();
+ communityUnderTest.stop();
}
@Test
db.measures().insertLiveMeasure(project2, nclocDistrib, m -> m.setValue(null).setData("java=300;kotlin=2500"));
projectMeasuresIndexer.indexOnStartup(emptySet());
- underTest.start();
+ communityUnderTest.start();
ArgumentCaptor<String> jsonCaptor = captureJson();
String json = jsonCaptor.getValue();
db.measures().insertLiveMeasure(shortBranch, ncloc, m -> m.setValue(30d));
projectMeasuresIndexer.indexOnStartup(emptySet());
- underTest.start();
+ communityUnderTest.start();
ArgumentCaptor<String> jsonCaptor = captureJson();
assertJson(jsonCaptor.getValue()).isSimilarTo("{\n" +
public void send_data_via_client_at_startup_after_initial_delay() throws IOException {
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
- underTest.start();
+ communityUnderTest.start();
verify(client, timeout(2_000).atLeastOnce()).upload(anyString());
}
+ @Test
+ public void data_contains_no_license_type_on_community_edition() throws IOException {
+ initTelemetrySettingsToDefaultValues();
+ settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
+
+ communityUnderTest.start();
+
+ ArgumentCaptor<String> jsonCaptor = captureJson();
+ assertThat(jsonCaptor.getValue()).doesNotContain("licenseType");
+ }
+
+ @Test
+ public void data_contains_no_license_type_on_commercial_edition_if_no_license() throws IOException {
+ initTelemetrySettingsToDefaultValues();
+ settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
+ when(licenseReader.read()).thenReturn(Optional.empty());
+
+ commercialUnderTest.start();
+
+ ArgumentCaptor<String> jsonCaptor = captureJson();
+ assertThat(jsonCaptor.getValue()).doesNotContain("licenseType");
+ }
+
+ @Test
+ public void data_has_license_type_on_commercial_edition_if_no_license() throws IOException {
+ String licenseType = randomAlphabetic(12);
+ initTelemetrySettingsToDefaultValues();
+ settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
+ LicenseReader.License license = mock(LicenseReader.License.class);
+ when(license.getType()).thenReturn(licenseType);
+ when(licenseReader.read()).thenReturn(Optional.of(license));
+
+ commercialUnderTest.start();
+
+ ArgumentCaptor<String> jsonCaptor = captureJson();
+ assertJson(jsonCaptor.getValue()).isSimilarTo("{\n" +
+ " \"licenseType\": \"" + licenseType + "\"\n" +
+ "}\n");
+ }
+
@Test
public void check_if_should_send_data_periodically() throws IOException {
initTelemetrySettingsToDefaultValues();
long sevenDaysAgo = now - (ONE_DAY * 7L);
internalProperties.write("telemetry.lastPing", String.valueOf(sixDaysAgo));
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
- underTest.start();
+ communityUnderTest.start();
verify(client, after(2_000).never()).upload(anyString());
internalProperties.write("telemetry.lastPing", String.valueOf(sevenDaysAgo));
String version = randomAlphanumeric(10);
server.setId(id);
server.setVersion(version);
- underTest.start();
+ communityUnderTest.start();
ArgumentCaptor<String> json = captureJson();
assertThat(json.getValue()).contains(id, version);
long sixDaysAgo = now - (ONE_DAY * 6L);
internalProperties.write("telemetry.lastPing", String.valueOf(sixDaysAgo));
- underTest.start();
+ communityUnderTest.start();
verify(client, after(2_000).never()).upload(anyString());
}
internalProperties.write("telemetry.lastPing", String.valueOf(sevenDaysAgo));
reset(internalProperties);
- underTest.start();
+ communityUnderTest.start();
verify(internalProperties, timeout(4_000)).write("telemetry.lastPing", String.valueOf(today));
verify(client).upload(anyString());
initTelemetrySettingsToDefaultValues();
settings.setProperty("sonar.telemetry.frequencyInSeconds", "1");
settings.setProperty("sonar.telemetry.enable", "false");
- underTest.start();
- underTest.start();
+ communityUnderTest.start();
+ communityUnderTest.start();
verify(client, after(2_000).never()).upload(anyString());
verify(client, timeout(2_000).times(1)).optOut(anyString());