Introduce an abstract class to differentiate static characteristics (dimension, metric key, ...) and dynamic (the actual value) to better show how it is supposed to be used. It will also prevent future duplication reports on data providers
import java.util.HashMap;
import java.util.Map;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class TelemetryDbMigrationStepDurationProvider implements TelemetryDataProvider<Long> {
+public class TelemetryDbMigrationStepDurationProvider extends AbstractTelemetryDataProvider<Long> {
private final Map<String, Long> dbMigrationStepDurations = new HashMap<>();
- @Override
- public String getMetricKey() {
- return "db_migration_step_duration";
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.ADHOC;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.INTEGER;
+ public TelemetryDbMigrationStepDurationProvider() {
+ super("db_migration_step_duration", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.INTEGER);
}
@Override
package org.sonar.server.telemetry;
import java.util.Optional;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class TelemetryDbMigrationStepsProvider implements TelemetryDataProvider<Integer> {
+public class TelemetryDbMigrationStepsProvider extends AbstractTelemetryDataProvider<Integer> {
private Integer dbMigrationCompletedSteps = null;
- @Override
- public String getMetricKey() {
- return "db_migration_completed_steps";
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.ADHOC;
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.INTEGER;
+ public TelemetryDbMigrationStepsProvider() {
+ super("db_migration_completed_steps", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.INTEGER);
}
public void setDbMigrationCompletedSteps(Integer dbMigrationCompletedSteps) {
package org.sonar.server.telemetry;
import java.util.Optional;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class TelemetryDbMigrationSuccessProvider implements TelemetryDataProvider<Boolean> {
+public class TelemetryDbMigrationSuccessProvider extends AbstractTelemetryDataProvider<Boolean> {
private Boolean dbMigrationSuccess = null;
- @Override
- public String getMetricKey() {
- return "db_migration_success";
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.BOOLEAN;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.ADHOC;
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
+ public TelemetryDbMigrationSuccessProvider() {
+ super("db_migration_success", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.BOOLEAN);
}
public void setDbMigrationSuccess(Boolean dbMigrationSuccess) {
package org.sonar.server.telemetry;
import java.util.Optional;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class TelemetryDbMigrationTotalTimeProvider implements TelemetryDataProvider<Long> {
+public class TelemetryDbMigrationTotalTimeProvider extends AbstractTelemetryDataProvider<Long> {
private Long dbMigrationTotalTime = null;
- @Override
- public String getMetricKey() {
- return "db_migration_total_time_ms";
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.ADHOC;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.INTEGER;
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
+ public TelemetryDbMigrationTotalTimeProvider() {
+ super("db_migration_total_time_ms", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.INTEGER);
}
public void setDbMigrationTotalTime(Long dbMigrationTotalTime) {
import java.util.Optional;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
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 static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_AUTH_METHOD;
-public class EmailConfigAuthMethodTelemetryProvider implements TelemetryDataProvider<String> {
+public class EmailConfigAuthMethodTelemetryProvider extends AbstractTelemetryDataProvider<String> {
private final DbClient dbClient;
public EmailConfigAuthMethodTelemetryProvider(DbClient dbClient) {
+ super("email_conf_auth_method", Dimension.INSTALLATION, Granularity.WEEKLY, TelemetryDataType.STRING);
this.dbClient = dbClient;
}
- @Override
- public String getMetricKey() {
- return "email_conf_auth_method";
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.WEEKLY;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.STRING;
- }
-
@Override
public Optional<String> getValue() {
try (DbSession dbSession = dbClient.openSession(false)) {
import org.apache.commons.lang3.StringUtils;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
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 static org.sonar.server.email.EmailSmtpConfiguration.EMAIL_CONFIG_SMTP_HOST;
-public class EmailConfigHostTelemetryProvider implements TelemetryDataProvider<String> {
+public class EmailConfigHostTelemetryProvider extends AbstractTelemetryDataProvider<String> {
private final DbClient dbClient;
public EmailConfigHostTelemetryProvider(DbClient dbClient) {
+ super("email_conf_host", Dimension.INSTALLATION, Granularity.WEEKLY, TelemetryDataType.STRING);
this.dbClient = dbClient;
}
- @Override
- public String getMetricKey() {
- return "email_conf_host";
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.STRING;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.WEEKLY;
- }
-
@Override
public Optional<String> getValue() {
try (DbSession dbSession = dbClient.openSession(false)) {
--- /dev/null
+/*
+ * 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;
+
+public abstract class AbstractTelemetryDataProvider<T> implements TelemetryDataProvider<T> {
+ private final String metricKey;
+ private final Dimension dimension;
+ private final Granularity granularity;
+ private final TelemetryDataType type;
+
+ protected AbstractTelemetryDataProvider(String metricKey, Dimension dimension, Granularity granularity, TelemetryDataType type) {
+ this.metricKey = metricKey;
+ this.dimension = dimension;
+ this.granularity = granularity;
+ this.type = type;
+ }
+
+ @Override
+ public String getMetricKey() {
+ return metricKey;
+ }
+
+ @Override
+ public Dimension getDimension() {
+ return dimension;
+ }
+
+ @Override
+ public Granularity getGranularity() {
+ return granularity;
+ }
+
+ @Override
+ public TelemetryDataType getType() {
+ return type;
+ }
+}
/**
* This interface is used to provide data to the telemetry system. The telemetry system will call the methods of this interface to get the
* data that will be sent to the telemetry server.
- * If you want to add new metric to the telemetry system, you need to create a new implementation of this interface and register it in the
- * Spring context as a bean.
+ * If you want to add a new metric to the telemetry system, you need to create a new implementation of this interface, or for convenience to subclass {@link AbstractTelemetryDataProvider} (recommended),
+ * and register it in the Spring context as a bean.
*
* @param <T> type of the value provided by this instance. Should be either {@link Boolean}, {@link String},
* {@link Integer} or {@link Float}.
+++ /dev/null
-/*
- * 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.common;
-
-import org.sonar.telemetry.core.Dimension;
-import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
-
-/**
- * This class is used to provide daily installation metrics to the telemetry system.
- */
-public abstract class DailyInstallationMetricProvider<T> implements TelemetryDataProvider<T> {
-
- @Override
- public Dimension getDimension() {
- return Dimension.INSTALLATION;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.DAILY;
- }
-
-}
+++ /dev/null
-/*
- * 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.
- */
-@ParametersAreNonnullByDefault
-package org.sonar.telemetry.core.common;
-
-import javax.annotation.ParametersAreNonnullByDefault;
--- /dev/null
+/*
+ * 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;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class AbstractTelemetryDataProviderTest {
+
+ AbstractTelemetryDataProvider<Boolean> customProvider = new AbstractTelemetryDataProvider<>("key", Dimension.INSTALLATION, Granularity.ADHOC, TelemetryDataType.BOOLEAN) {
+ };
+
+
+ @Test
+ void it_should_provide_configured_properties() {
+ assertThat(customProvider.getDimension()).isEqualTo(Dimension.INSTALLATION);
+ assertThat(customProvider.getMetricKey()).isEqualTo("key");
+ assertThat(customProvider.getGranularity()).isEqualTo(Granularity.ADHOC);
+ assertThat(customProvider.getType()).isEqualTo(TelemetryDataType.BOOLEAN);
+ assertThat(customProvider.getValue()).isEmpty();
+ assertThat(customProvider.getValues()).isEmpty();
+ }
+
+}
import org.sonar.db.measure.ProjectMainBranchMeasureDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.property.PropertyQuery;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class ProjectCppAutoconfigTelemetryProvider implements TelemetryDataProvider<String> {
+public class ProjectCppAutoconfigTelemetryProvider extends AbstractTelemetryDataProvider<String> {
private final DbClient dbClient;
public ProjectCppAutoconfigTelemetryProvider(DbClient dbClient) {
+ super("project_cpp_config_type", Dimension.PROJECT, Granularity.WEEKLY, TelemetryDataType.STRING);
this.dbClient = dbClient;
}
- @Override
- public String getMetricKey() {
- return "project_cpp_config_type";
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.PROJECT;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.WEEKLY;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.STRING;
- }
-
@Override
public Map<String, String> getValues() {
Map<String, String> cppConfigTypePerProjectUuid = new HashMap<>();
import java.util.Optional;
import org.sonar.core.fips.FipsDetector;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataType;
-import org.sonar.telemetry.core.common.DailyInstallationMetricProvider;
-public class TelemetryFipsEnabledProvider extends DailyInstallationMetricProvider<Boolean> {
+public class TelemetryFipsEnabledProvider extends AbstractTelemetryDataProvider<Boolean> {
- @Override
- public String getMetricKey() {
- return "is_fips_enabled";
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.BOOLEAN;
+ public TelemetryFipsEnabledProvider() {
+ super("is_fips_enabled", Dimension.INSTALLATION, Granularity.DAILY, TelemetryDataType.BOOLEAN);
}
@Override
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.measure.ProjectLocDistributionDto;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
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.legacy.ProjectLocDistributionDataProvider;
-public class TelemetryNclocProvider implements TelemetryDataProvider<Long> {
+public class TelemetryNclocProvider extends AbstractTelemetryDataProvider<Long> {
public static final String METRIC_KEY = "ncloc_per_language";
private final ProjectLocDistributionDataProvider projectLocDistributionDataProvider;
public TelemetryNclocProvider(DbClient dbClient, ProjectLocDistributionDataProvider projectLocDistributionDataProvider) {
+ super(METRIC_KEY, Dimension.LANGUAGE, Granularity.DAILY, TelemetryDataType.INTEGER);
this.dbClient = dbClient;
this.projectLocDistributionDataProvider = projectLocDistributionDataProvider;
}
- @Override
- public String getMetricKey() {
- return METRIC_KEY;
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.LANGUAGE;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.DAILY;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.INTEGER;
- }
-
@Override
public Map<String, Long> getValues() {
try (DbSession dbSession = dbClient.openSession(false)) {
import java.util.Optional;
import org.sonar.db.DbClient;
import org.sonar.db.property.PropertyDto;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
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 static org.sonar.telemetry.core.Dimension.INSTALLATION;
-import static org.sonar.telemetry.core.Granularity.WEEKLY;
-import static org.sonar.telemetry.core.TelemetryDataType.BOOLEAN;
-
-public class TelemetryPortfolioConfidentialFlagProvider implements TelemetryDataProvider<Boolean> {
+public class TelemetryPortfolioConfidentialFlagProvider extends AbstractTelemetryDataProvider<Boolean> {
private final DbClient dbClient;
public TelemetryPortfolioConfidentialFlagProvider(DbClient dbClient) {
+ super("portfolio_reports_confidential_flag", Dimension.INSTALLATION, Granularity.WEEKLY, TelemetryDataType.BOOLEAN);
this.dbClient = dbClient;
}
- @Override
- public String getMetricKey() {
- return "portfolio_reports_confidential_flag";
- }
-
- @Override
- public Dimension getDimension() {
- return INSTALLATION;
- }
-
- @Override
- public Granularity getGranularity() {
- return WEEKLY;
- }
-
- @Override
- public TelemetryDataType getType() {
- return BOOLEAN;
- }
-
@Override
public Optional<Boolean> getValue() {
PropertyDto property = dbClient.propertiesDao().selectGlobalProperty("sonar.portfolios.confidential.header");
import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserQuery;
import org.sonar.server.util.DigestUtil;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
import org.sonar.telemetry.core.Dimension;
import org.sonar.telemetry.core.Granularity;
-import org.sonar.telemetry.core.TelemetryDataProvider;
import org.sonar.telemetry.core.TelemetryDataType;
-public class TelemetryUserEnabledProvider implements TelemetryDataProvider<Boolean> {
+public class TelemetryUserEnabledProvider extends AbstractTelemetryDataProvider<Boolean> {
private final DbClient dbClient;
public TelemetryUserEnabledProvider(DbClient dbClient) {
+ super("user_enabled", Dimension.USER, Granularity.DAILY, TelemetryDataType.BOOLEAN);
this.dbClient = dbClient;
}
- @Override
- public String getMetricKey() {
- return "user_enabled";
- }
-
- @Override
- public Dimension getDimension() {
- return Dimension.USER;
- }
-
- @Override
- public Granularity getGranularity() {
- return Granularity.DAILY;
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.BOOLEAN;
- }
-
@Override
public Map<String, Boolean> getValues() {
Map<String, Boolean> result = new HashMap<>();
import java.util.Optional;
import org.sonar.api.platform.Server;
+import org.sonar.telemetry.core.AbstractTelemetryDataProvider;
+import org.sonar.telemetry.core.Dimension;
+import org.sonar.telemetry.core.Granularity;
import org.sonar.telemetry.core.TelemetryDataType;
-import org.sonar.telemetry.core.common.DailyInstallationMetricProvider;
-public class TelemetryVersionProvider extends DailyInstallationMetricProvider<String> {
+public class TelemetryVersionProvider extends AbstractTelemetryDataProvider<String> {
private final Server server;
public TelemetryVersionProvider(Server server) {
+ super("version", Dimension.INSTALLATION, Granularity.DAILY, TelemetryDataType.STRING);
this.server = server;
}
- @Override
- public String getMetricKey() {
- return "version";
- }
-
- @Override
- public TelemetryDataType getType() {
- return TelemetryDataType.STRING;
- }
-
@Override
public Optional<String> getValue() {
return Optional.ofNullable(server.getVersion());