diff options
12 files changed, 95 insertions, 233 deletions
diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java index a80d2e7c4be..ed11ebf9183 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/measure/MeasureDaoIT.java @@ -52,6 +52,7 @@ import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; import static org.sonar.db.measure.MeasureTesting.newMeasure; +import static org.sonar.db.qualityprofile.QualityProfileTesting.newQualityProfileDto; class MeasureDaoIT { @@ -568,6 +569,41 @@ class MeasureDaoIT { } @Test + void selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile() { + ProjectData projectData1 = db.components().insertPrivateProject(); + BranchDto branch1 = projectData1.getMainBranchDto(); + BranchDto branch2 = db.components().insertProjectBranch(projectData1.getProjectDto()); + + ProjectData projectData2 = db.components().insertPrivateProject(); + BranchDto branch3 = projectData2.getMainBranchDto(); + + // Insert measures for each branch and for a random component on branch1 + MetricDto metric = db.measures().insertMetric(); + MeasureDto measure1 = newMeasure(branch1, metric, 3); + MeasureDto measure2 = newMeasure(branch2, metric, 4); + MeasureDto measure3 = newMeasure(branch3, metric, 5); + MeasureDto measure4 = newMeasure(db.components().insertFile(branch1), metric, 7); + + underTest.insertOrUpdate(db.getSession(), measure1); + underTest.insertOrUpdate(db.getSession(), measure2); + underTest.insertOrUpdate(db.getSession(), measure3); + underTest.insertOrUpdate(db.getSession(), measure4); + + db.qualityProfiles().associateWithProject(projectData2.getProjectDto(), newQualityProfileDto()); + + List<ProjectMainBranchMeasureDto> measures = + underTest.selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile(db.getSession()); + assertThat(measures).hasSize(1); + assertThat(measures) + .flatExtracting(m -> m.getMetricValues().entrySet().stream() + .map(entry -> tuple(m.getProjectUuid(), entry.getKey(), entry.getValue())) + .toList()) + .containsExactly( + tuple(projectData1.projectUuid(), metric.getKey(), 3.0) + ); + } + + @Test void selectAllForMainBranches() { ProjectData projectData1 = db.components().insertPrivateProject(); BranchDto branch1 = projectData1.getMainBranchDto(); diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java index 3f4003019cf..3befb795478 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/project/ProjectDaoIT.java @@ -19,18 +19,14 @@ */ package org.sonar.db.project; -import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Random; import java.util.Set; -import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.IntStream; import javax.annotation.Nullable; @@ -48,11 +44,7 @@ import org.sonar.db.audit.NoOpAuditPersister; import org.sonar.db.component.BranchDto; import org.sonar.db.component.BranchType; import org.sonar.db.component.ComponentDto; -import org.sonar.db.component.ProjectData; import org.sonar.db.entity.EntityDto; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; -import org.sonar.db.qualityprofile.QProfileDto; import static java.util.Collections.emptySet; import static org.assertj.core.api.Assertions.assertThat; @@ -62,13 +54,9 @@ 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.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY; -import static org.sonar.api.measures.Metric.ValueType.STRING; class ProjectDaoIT { - private final Random random = new SecureRandom(); - private final System2 system2 = new AlwaysIncreasingSystem2(1000L); @RegisterExtension @@ -352,18 +340,6 @@ class ProjectDaoIT { } @Test - void select_project_uuids_associated_to_default_quality_profile_for_specific_language() { - String language = "xoo"; - Set<ProjectData> projects = insertProjects(random.nextInt(10)); - insertDefaultQualityProfile(language); - insertProjectsLiveMeasures(language, projects); - - Set<String> projectUuids = projectDao.selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage(db.getSession(), language); - - assertThat(projectUuids).containsExactlyInAnyOrderElementsOf(extractComponentUuids(projects)); - } - - @Test void update_ncloc_should_update_project() { String projectUuid = db.components().insertPublicProject().projectUuid(); @@ -445,72 +421,6 @@ class ProjectDaoIT { assertThat(projectDao.countProjects(db.getSession())).isEqualTo(10); } - @Test - void selectProjectsByLanguage_whenTwoLanguagesArePassed_selectProjectsWithTheseLanguages() { - Consumer<MetricDto> configureMetric = metric -> metric - .setValueType(STRING.name()) - .setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY); - - MetricDto metric = db.measures().insertMetric(configureMetric); - - ProjectData project1 = db.components().insertPrivateProject(); - ProjectData project2 = db.components().insertPrivateProject(); - ProjectData project3 = db.components().insertPrivateProject(); - ProjectData project4 = db.components().insertPrivateProject(); - - insertLiveMeasure("c", metric).accept(project1); - insertLiveMeasure("cpp", metric).accept(project2); - insertLiveMeasure("java", metric).accept(project3); - insertLiveMeasure("cobol", metric).accept(project4); - - List<ProjectDto> projectDtos = projectDao.selectProjectsByLanguage(db.getSession(), Set.of("cpp", "c")); - - assertThat(projectDtos).extracting(ProjectDto::getUuid) - .containsExactlyInAnyOrder(project1.getProjectDto().getUuid(), project2.getProjectDto().getUuid()); - } - - private void insertDefaultQualityProfile(String language) { - QProfileDto profile = db.qualityProfiles().insert(qp -> qp.setIsBuiltIn(true).setLanguage(language)); - db.qualityProfiles().setAsDefault(profile); - } - - private static Set<String> extractComponentUuids(Collection<ProjectData> components) { - return components - .stream() - .map(ProjectData::projectUuid) - .collect(Collectors.toSet()); - } - - private Set<ProjectData> insertProjects(int number) { - return IntStream - .rangeClosed(0, number) - .mapToObj(x -> db.components().insertPrivateProject()) - .collect(Collectors.toSet()); - } - - private Consumer<LiveMeasureDto> configureLiveMeasure(String language, MetricDto metric, ComponentDto componentDto) { - return liveMeasure -> liveMeasure - .setMetricUuid(metric.getUuid()) - .setComponentUuid(componentDto.uuid()) - .setProjectUuid(componentDto.uuid()) - .setData(language + "=" + random.nextInt(10)); - } - - private Consumer<ProjectData> insertLiveMeasure(String language, MetricDto metric) { - return (projectData) -> db.measures().insertLiveMeasure(projectData.getMainBranchComponent(), metric, - configureLiveMeasure(language, metric, projectData.getMainBranchComponent())); - } - - private void insertProjectsLiveMeasures(String language, Set<ProjectData> projects) { - Consumer<MetricDto> configureMetric = metric -> metric - .setValueType(STRING.name()) - .setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY); - - MetricDto metric = db.measures().insertMetric(configureMetric); - - projects.forEach(insertLiveMeasure(language, metric)); - } - private void assertProject(ProjectDto dto, String name, String kee, String uuid, String desc, @Nullable String tags, boolean isPrivate) { assertProject(dto, name, kee, uuid, desc, tags, isPrivate, false); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java index 7feb6a6795a..ab619fcb46f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java @@ -132,6 +132,10 @@ public class MeasureDao implements Dao { return mapper(dbSession).selectAllForProjectMainBranches(); } + public List<ProjectMainBranchMeasureDto> selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile(DbSession dbSession) { + return mapper(dbSession).selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile(); + } + public List<MeasureDto> selectAllForMainBranches(DbSession dbSession) { return mapper(dbSession).selectAllForMainBranches(); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java index a324666512b..b6baf817e2a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java @@ -51,5 +51,7 @@ public interface MeasureMapper { List<ProjectMainBranchMeasureDto> selectAllForProjectMainBranches(); + List<ProjectMainBranchMeasureDto> selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile(); + List<MeasureDto> selectAllForMainBranches(); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java index 20f41f79227..49f305100e7 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java @@ -20,7 +20,6 @@ package org.sonar.db.project; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; @@ -140,10 +139,6 @@ public class ProjectDao implements Dao { return session.getMapper(ProjectMapper.class); } - public Set<String> selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage(DbSession session, String language) { - return mapper(session).selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage(languageFilters.apply(language)); - } - public void updateNcloc(DbSession dbSession, String projectUuid, long ncloc) { mapper(dbSession).updateNcloc(projectUuid, ncloc); } @@ -163,12 +158,4 @@ public class ProjectDao implements Dao { public int countProjects(DbSession session) { return mapper(session).countProjects(); } - - public List<ProjectDto> selectProjectsByLanguage(DbSession dbSession, Set<String> setOfLanguages) { - Set<String> likeFilters = new HashSet<>(); - for (String language : setOfLanguages) { - likeFilters.addAll(languageFilters.apply(language)); - } - return mapper(dbSession).selectProjectsByLanguage(likeFilters); - } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java index 3ee4d95435d..4717d3e55b1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java @@ -21,7 +21,6 @@ package org.sonar.db.project; import java.util.Collection; import java.util.List; -import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.apache.ibatis.annotations.Param; @@ -68,8 +67,6 @@ public interface ProjectMapper { @CheckForNull ProjectDto selectByBranchUuid(String branchUuid); - Set<String> selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage(@Param("languageFilters") Set<String> languageFilters); - void updateNcloc(@Param("projectUuid") String projectUuid, @Param("ncloc") long ncloc); @CheckForNull @@ -78,6 +75,4 @@ public interface ProjectMapper { int countIndexedProjects(); int countProjects(); - - List<ProjectDto> selectProjectsByLanguage(@Param("languageFilters") Set<String> languageFilters); } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml index 3bd68171aba..118ef27e034 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml @@ -126,6 +126,16 @@ and pb.is_main = ${_true} </select> + <select id="selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile" resultType="org.sonar.db.measure.ProjectMainBranchMeasureDto"> + select p.uuid as projectUuid, m.json_value as jsonValue + from measures m + inner join project_branches pb on pb.uuid = m.component_uuid + inner join projects p on p.uuid = pb.project_uuid + where + pb.is_main = ${_true} + and p.uuid not in (select project_uuid from project_qprofiles) + </select> + <select id="selectAllForMainBranches" resultType="org.sonar.db.measure.MeasureDto"> select <include refid="columns"/> from measures m inner join project_branches pb on pb.uuid = m.component_uuid and pb.is_main = ${_true} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml index 575a4356117..c54aa32323f 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml @@ -127,46 +127,6 @@ p.kee=#{key,jdbcType=VARCHAR} </select> - <select id="selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage" parameterType="map" resultType="string"> - select - p.uuid - from - live_measures lm - inner join - project_branches pb on pb.uuid = lm.component_uuid - inner join - projects p on p.uuid = pb.project_uuid - inner join - metrics m on m.uuid = lm.metric_uuid - where - m.name = 'ncloc_language_distribution' - and pb.is_main = ${_true} - and p.uuid not in (select project_uuid from project_qprofiles) - and - <foreach collection="languageFilters" index="index" item="languageFilter" open="(" separator=" or " close=")"> - lm.text_value like #{languageFilter, jdbcType=VARCHAR} escape '/' - </foreach> - </select> - - <select id="selectProjectsByLanguage" parameterType="map" resultType="Project"> - select distinct - <include refid="projectColumns"/> - from - live_measures lm - inner join - project_branches pb on pb.uuid = lm.project_uuid and pb.is_main = ${_true} - inner join - projects p on p.uuid = pb.project_uuid - inner join - metrics m on m.uuid = lm.metric_uuid - where - m.name = 'ncloc_language_distribution' - and - <foreach collection="languageFilters" index="index" item="languageFilter" open="(" separator=" or " close=")"> - lm.text_value like #{languageFilter, jdbcType=VARCHAR} escape '/' - </foreach> - </select> - <insert id="insert" parameterType="Project"> INSERT INTO projects ( kee, diff --git a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImpl.java b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImpl.java index baf693c63be..ddffddaab99 100644 --- a/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImpl.java +++ b/server/sonar-webserver-pushapi/src/main/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImpl.java @@ -35,6 +35,7 @@ import java.util.stream.Stream; import javax.annotation.Nullable; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.rule.RuleKey; import org.sonar.api.server.ServerSide; import org.sonar.core.util.ParamChange; @@ -42,6 +43,7 @@ import org.sonar.core.util.rule.RuleChange; import org.sonar.core.util.rule.RuleSetChangedEvent; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.measure.ProjectMainBranchMeasureDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.pushevent.PushEventDto; import org.sonar.db.qualityprofile.ActiveRuleDto; @@ -271,10 +273,24 @@ public class QualityProfileChangeEventServiceImpl implements QualityProfileChang } private List<ProjectDto> getDefaultQualityProfileAssociatedProjects(DbSession dbSession, String language) { - Set<String> associatedProjectUuids = dbClient.projectDao().selectProjectUuidsAssociatedToDefaultQualityProfileByLanguage(dbSession, language); + Set<String> associatedProjectUuids = new HashSet<>(); + + List<ProjectMainBranchMeasureDto> measureDtos = + dbClient.measureDao().selectAllForProjectMainBranchesAssociatedToDefaultQualityProfile(dbSession); + for (ProjectMainBranchMeasureDto measureDto : measureDtos) { + String distribution = (String) measureDto.getMetricValues().get(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY); + if (distribution != null && distributionContainsLanguage(distribution, language)) { + associatedProjectUuids.add(measureDto.getProjectUuid()); + } + } + return dbClient.projectDao().selectByUuids(dbSession, associatedProjectUuids); } + private static boolean distributionContainsLanguage(String distribution, String language) { + return distribution.startsWith(language + "=") || distribution.contains(";" + language + "="); + } + private List<ProjectDto> getManuallyAssociatedQualityProfileProjects(DbSession dbSession, List<QProfileDto> profiles) { return profiles .stream() diff --git a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java index cea9b9855cb..8d629900c8f 100644 --- a/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java +++ b/server/sonar-webserver-pushapi/src/test/java/org/sonar/server/pushapi/qualityprofile/QualityProfileChangeEventServiceImplTest.java @@ -20,12 +20,10 @@ package org.sonar.server.pushapi.qualityprofile; import java.nio.charset.StandardCharsets; -import java.security.SecureRandom; import java.util.Collection; import java.util.Collections; import java.util.Deque; import java.util.List; -import java.util.Random; import java.util.Set; import java.util.function.Consumer; import org.junit.Rule; @@ -34,8 +32,6 @@ import org.sonar.api.rule.RuleKey; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; import org.sonar.db.project.ProjectDto; import org.sonar.db.pushevent.PushEventDto; import org.sonar.db.qualityprofile.ActiveRuleDto; @@ -51,15 +47,12 @@ import static java.util.List.of; import static org.apache.commons.lang3.RandomStringUtils.randomAlphanumeric; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY; -import static org.sonar.api.measures.Metric.ValueType.STRING; import static org.sonar.db.rule.RuleTesting.newCustomRule; import static org.sonar.db.rule.RuleTesting.newTemplateRule; import static org.sonar.server.qualityprofile.ActiveRuleChange.Type.ACTIVATED; public class QualityProfileChangeEventServiceImplTest { - private final Random random = new SecureRandom(); - @Rule public DbTester db = DbTester.create(); @@ -114,7 +107,7 @@ public class QualityProfileChangeEventServiceImplTest { QProfileDto defaultQualityProfile = insertDefaultQualityProfile(language); RuleDto rule = insertCustomRule(templateRule, language, "<div>line1\nline2</div>"); ActiveRuleChange activeRuleChange = changeActiveRule(defaultQualityProfile, rule, "paramChangeKey", "paramChangeValue"); - insertQualityProfileLiveMeasure(mainBranch, projectData.getProjectDto(), language, NCLOC_LANGUAGE_DISTRIBUTION_KEY); + db.measures().insertMeasure(mainBranch, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, language + "=100")); db.getSession().commit(); @@ -221,25 +214,4 @@ public class QualityProfileChangeEventServiceImplTest { "\"params\":[{\"key\":\"" + activeRuleParam1.getKey() + "\",\"value\":\"" + activeRuleParam1.getValue() + "\"}]}]," + "\"deactivatedRules\":[\"repo2:ruleKey2\"]"); } - - private void insertQualityProfileLiveMeasure(ComponentDto branch, ProjectDto projectDto, String language, String metricKey) { - MetricDto metric = insertMetric(metricKey); - - Consumer<LiveMeasureDto> configureLiveMeasure = liveMeasure -> liveMeasure - .setMetricUuid(metric.getUuid()) - .setComponentUuid(branch.uuid()) - .setProjectUuid(projectDto.getUuid()) - .setData(language + "=" + random.nextInt(10)); - - db.measures().insertLiveMeasure(branch, metric, configureLiveMeasure); - } - - private MetricDto insertMetric(String metricKey) { - Consumer<MetricDto> configureMetric = metric -> metric - .setUuid("uuid") - .setValueType(STRING.name()) - .setKey(metricKey); - - return db.measures().insertMetric(configureMetric); - } } diff --git a/server/sonar-webserver/src/it/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProviderIT.java b/server/sonar-webserver/src/it/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProviderIT.java index b1e40ad643b..2a2e39c2ac5 100644 --- a/server/sonar-webserver/src/it/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProviderIT.java +++ b/server/sonar-webserver/src/it/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProviderIT.java @@ -20,20 +20,15 @@ package org.sonar.server.platform.telemetry; import java.util.Map; -import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.sonar.api.impl.utils.AlwaysIncreasingSystem2; import org.sonar.api.utils.System2; import org.sonar.db.DbTester; -import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ProjectData; -import org.sonar.db.measure.LiveMeasureDto; -import org.sonar.db.metric.MetricDto; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY; -import static org.sonar.api.measures.Metric.ValueType.STRING; class ProjectCppAutoconfigTelemetryProviderIT { @@ -51,39 +46,26 @@ class ProjectCppAutoconfigTelemetryProviderIT { @Test void getValues_whenNoCppAndCProjects_returnEmptyMap() { - Consumer<MetricDto> configureMetric = metric -> metric - .setValueType(STRING.name()) - .setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY); - - MetricDto metric = db.measures().insertMetric(configureMetric); - ProjectData project1 = db.components().insertPrivateProject(); ProjectData project2 = db.components().insertPrivateProject(); - insertLiveMeasure("java", metric).accept(project1); - insertLiveMeasure("cobol", metric).accept(project2); - + db.measures().insertMeasure(project1, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "java=100")); + db.measures().insertMeasure(project2, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "cobol=100")); assertThat(underTest.getValues()).isEmpty(); } @Test void getValues_when1CppAnd1CProject_returnMapWithSize2AndAutoconfigByDefault() { - Consumer<MetricDto> configureMetric = metric -> metric - .setValueType(STRING.name()) - .setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY); - - MetricDto metric = db.measures().insertMetric(configureMetric); - ProjectData project1 = db.components().insertPrivateProject(); ProjectData project2 = db.components().insertPrivateProject(); ProjectData project3 = db.components().insertPrivateProject(); ProjectData project4 = db.components().insertPrivateProject(); - insertLiveMeasure("c", metric).accept(project1); - insertLiveMeasure("cpp", metric).accept(project2); - insertLiveMeasure("java", metric).accept(project3); - insertLiveMeasure("cobol", metric).accept(project4); + db.measures().insertMeasure(project1, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "c=100;java=2")); + db.measures().insertMeasure(project2, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "java=2;cpp=100")); + db.measures().insertMeasure(project3, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "java=100")); + db.measures().insertMeasure(project4, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "cobol=100")); Map<String, String> actualResult = underTest.getValues(); @@ -95,21 +77,15 @@ class ProjectCppAutoconfigTelemetryProviderIT { @Test void getValues_whenCAndCppProjectsWithDifferentConfig_returnMapWithSize2AndNotAutoconfig() { - Consumer<MetricDto> configureMetric = metric -> metric - .setValueType(STRING.name()) - .setKey(NCLOC_LANGUAGE_DISTRIBUTION_KEY); - - MetricDto metric = db.measures().insertMetric(configureMetric); - ProjectData project1 = db.components().insertPrivateProject(); ProjectData project2 = db.components().insertPrivateProject(); ProjectData project3 = db.components().insertPrivateProject(); ProjectData project4 = db.components().insertPrivateProject(); - insertLiveMeasure("c", metric).accept(project1); - insertLiveMeasure("cpp", metric).accept(project2); - insertLiveMeasure("java", metric).accept(project3); - insertLiveMeasure("cobol", metric).accept(project4); + db.measures().insertMeasure(project1, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "c=100")); + db.measures().insertMeasure(project2, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "cpp=100")); + db.measures().insertMeasure(project3, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "java=100")); + db.measures().insertMeasure(project4, m -> m.addValue(NCLOC_LANGUAGE_DISTRIBUTION_KEY, "cobol=100")); db.properties().insertProperty("sonar.cfamily.build-wrapper-output", "anyvalue", project1.getProjectDto().getUuid()); db.properties().insertProperty("sonar.cfamily.compile-commands", "anyvalue", project2.getProjectDto().getUuid()); @@ -121,17 +97,4 @@ class ProjectCppAutoconfigTelemetryProviderIT { Map.of(project1.getProjectDto().getUuid(), "BW_DEPRECATED", project2.getProjectDto().getUuid(), "COMPDB") ); } - - private Consumer<LiveMeasureDto> configureLiveMeasure(String language, MetricDto metric, ComponentDto componentDto) { - return liveMeasure -> liveMeasure - .setMetricUuid(metric.getUuid()) - .setComponentUuid(componentDto.uuid()) - .setProjectUuid(componentDto.uuid()) - .setData(language + "=" + 100); - } - - private Consumer<ProjectData> insertLiveMeasure(String language, MetricDto metric) { - return projectData -> db.measures().insertLiveMeasure(projectData.getMainBranchComponent(), metric, - configureLiveMeasure(language, metric, projectData.getMainBranchComponent())); - } } diff --git a/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProvider.java b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProvider.java index 51382bbebe9..fb83847c57a 100644 --- a/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProvider.java +++ b/server/sonar-webserver/src/main/java/org/sonar/server/platform/telemetry/ProjectCppAutoconfigTelemetryProvider.java @@ -23,9 +23,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import org.sonar.api.measures.CoreMetrics; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.project.ProjectDto; +import org.sonar.db.measure.ProjectMainBranchMeasureDto; import org.sonar.db.property.PropertyDto; import org.sonar.db.property.PropertyQuery; import org.sonar.telemetry.core.Dimension; @@ -65,20 +66,26 @@ public class ProjectCppAutoconfigTelemetryProvider implements TelemetryDataProvi public Map<String, String> getValues() { Map<String, String> cppConfigTypePerProjectUuid = new HashMap<>(); try (DbSession dbSession = dbClient.openSession(true)) { - // In the future ideally languages should be defined in the codebase as enums, using strings is error-prone - List<ProjectDto> cppProjects = dbClient.projectDao().selectProjectsByLanguage(dbSession, Set.of("cpp", "c")); - for (ProjectDto cppProject : cppProjects) { - CppConfigType cppConfigType = getCppConfigType(cppProject, dbSession); - cppConfigTypePerProjectUuid.put(cppProject.getUuid(), cppConfigType.name()); + List<ProjectMainBranchMeasureDto> measureDtos = dbClient.measureDao().selectAllForProjectMainBranches(dbSession); + for (ProjectMainBranchMeasureDto measureDto : measureDtos) { + String distribution = (String) measureDto.getMetricValues().get(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY); + if (distribution != null && Set.of("cpp", "c").stream().anyMatch(language -> distributionContainsLanguage(distribution, language))) { + CppConfigType cppConfigType = getCppConfigType(measureDto.getProjectUuid(), dbSession); + cppConfigTypePerProjectUuid.put(measureDto.getProjectUuid(), cppConfigType.name()); + } } } return cppConfigTypePerProjectUuid; } - private CppConfigType getCppConfigType(ProjectDto project, DbSession dbSession) { + private static boolean distributionContainsLanguage(String distribution, String language) { + return distribution.startsWith(language + "=") || distribution.contains(";" + language + "="); + } + + private CppConfigType getCppConfigType(String entityUuid, DbSession dbSession) { List<PropertyDto> propertyDtos = dbClient.propertiesDao().selectByQuery(PropertyQuery .builder() - .setEntityUuid(project.getUuid()) + .setEntityUuid(entityUuid) .build(), dbSession); for (PropertyDto propertyDto : propertyDtos) { if (propertyDto.getKey().equals("sonar.cfamily.build-wrapper-output")) { |