import org.sonar.db.component.ComponentWithModuleUuidDto;
import org.sonar.db.component.FilePathWithHashDto;
import org.sonar.db.component.KeyWithUuidDto;
-import org.sonar.db.component.PrAndBranchCountByProjectDto;
+import org.sonar.db.component.PrBranchAnalyzedLanguageCountByProjectDto;
import org.sonar.db.component.ProjectLinkMapper;
import org.sonar.db.component.ResourceDto;
import org.sonar.db.component.ScrapAnalysisPropertyDto;
confBuilder.loadAlias("ProjectBadgeToken", ProjectBadgeTokenDto.class);
confBuilder.loadAlias("AnalysisPropertyValuePerProject", AnalysisPropertyValuePerProject.class);
confBuilder.loadAlias("ProjectAlmKeyAndProject", ProjectAlmKeyAndProject.class);
- confBuilder.loadAlias("PrAndBranchCountByProjectDto", PrAndBranchCountByProjectDto.class);
+ confBuilder.loadAlias("PrAndBranchCountByProjectDto", PrBranchAnalyzedLanguageCountByProjectDto.class);
confBuilder.loadAlias("ProjectMapping", ProjectMappingDto.class);
confBuilder.loadAlias("ProjectMeasure", ProjectMeasureDto.class);
confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class);
return mapper(dbSession).selectByProjectUuid(project.getUuid());
}
- public List<PrAndBranchCountByProjectDto> countPrAndBranchByProjectUuid(DbSession dbSession){
- return mapper(dbSession).countPrAndBranchByProjectUuid();
+ public List<PrBranchAnalyzedLanguageCountByProjectDto> countPrBranchAnalyzedLanguageByProjectUuid(DbSession dbSession){
+ return mapper(dbSession).countPrBranchAnalyzedLanguageByProjectUuid();
}
public List<BranchDto> selectByUuids(DbSession session, Collection<String> uuids) {
Collection<BranchDto> selectByProjectUuid(@Param("projectUuid") String projectUuid);
- List<PrAndBranchCountByProjectDto> countPrAndBranchByProjectUuid();
+ List<PrBranchAnalyzedLanguageCountByProjectDto> countPrBranchAnalyzedLanguageByProjectUuid();
List<BranchDto> selectByBranchKeys(@Param("branchKeyByProjectUuid") Map<String, String> branchKeyByProjectUuid);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2022 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.db.component;
-
-public class PrAndBranchCountByProjectDto {
-
- private String projectUuid = null;
- private Long pullRequest = null;
- private Long branch = null;
-
- public String getProjectUuid() {
- return projectUuid;
- }
-
- public void setProjectUuid(String projectUuid) {
- this.projectUuid = projectUuid;
- }
-
- public Long getPullRequest() {
- return pullRequest;
- }
-
- public void setPullRequest(Long pullRequest) {
- this.pullRequest = pullRequest;
- }
-
- public Long getBranch() {
- return branch;
- }
-
- public void setBranch(Long branch) {
- this.branch = branch;
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.db.component;
+
+public class PrBranchAnalyzedLanguageCountByProjectDto {
+
+ private String projectUuid = null;
+ private Long pullRequest = null;
+ private Long branch = null;
+ private Long unanalyzedCCount = null;
+ private Long unanalyzedCppCount = null;
+
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+ public void setProjectUuid(String projectUuid) {
+ this.projectUuid = projectUuid;
+ }
+
+ public Long getPullRequest() {
+ return pullRequest;
+ }
+
+ public void setPullRequest(Long pullRequest) {
+ this.pullRequest = pullRequest;
+ }
+
+ public Long getBranch() {
+ return branch;
+ }
+
+ public void setBranch(Long branch) {
+ this.branch = branch;
+ }
+
+ public Long getUnanalyzedCCount() {
+ return unanalyzedCCount;
+ }
+
+ public void setUnanalyzedCCount(Long unanalyzedCCount) {
+ this.unanalyzedCCount = unanalyzedCCount;
+ }
+
+ public Long getUnanalyzedCppCount() {
+ return unanalyzedCppCount;
+ }
+
+ public void setUnanalyzedCppCount(Long unanalyzedCppCount) {
+ this.unanalyzedCppCount = unanalyzedCppCount;
+ }
+}
pb.project_uuid = #{projectUuid, jdbcType=VARCHAR}
</select>
- <select id="countPrAndBranchByProjectUuid" resultType="org.sonar.db.component.PrAndBranchCountByProjectDto">
- select project_uuid as projectUuid,
+ <select id="countPrBranchAnalyzedLanguageByProjectUuid" resultType="org.sonar.db.component.PrBranchAnalyzedLanguageCountByProjectDto">
+ select pb.project_uuid as projectUuid,
sum(case when pb.branch_type = 'PULL_REQUEST' then 1 else 0 end) as pullRequest,
- sum(case when pb.branch_type = 'BRANCH' then 1 else 0 end) as branch
- from project_branches pb
+ sum(case when pb.branch_type = 'BRANCH' then 1 else 0 end) as branch,
+ (
+ select count(1) as counter from live_measures lm
+ inner join metrics m on m.uuid = lm.metric_uuid and m.name = 'unanalyzed_c'
+ where lm.project_uuid = pb.project_uuid) as unanalyzedCCount,
+ (
+ select count(1) as counter from live_measures lm
+ inner join metrics m on m.uuid = lm.metric_uuid and m.name = 'unanalyzed_cpp'
+ where lm.project_uuid = pb.project_uuid) as unanalyzedCppCount
+ from project_branches pb
group by pb.project_uuid
</select>
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.metric.MetricDto;
import org.sonar.db.project.ProjectDto;
import org.sonar.db.protobuf.DbProjectBranches;
ComponentDto project3 = db.components().insertPrivateProject();
db.components().insertProjectBranch(project3, b -> b.setBranchType(BRANCH).setKey("p3-branch-1"));
- assertThat(underTest.countPrAndBranchByProjectUuid(db.getSession()))
- .extracting(PrAndBranchCountByProjectDto::getProjectUuid, PrAndBranchCountByProjectDto::getBranch, PrAndBranchCountByProjectDto::getPullRequest)
+ MetricDto unanalyzedC = db.measures().insertMetric(m -> m.setKey("unanalyzed_c"));
+ MetricDto unanalyzedCpp = db.measures().insertMetric(m -> m.setKey("unanalyzed_cpp"));
+ db.measures().insertLiveMeasure(project1, unanalyzedC);
+ db.measures().insertLiveMeasure(project1, unanalyzedCpp);
+ db.measures().insertLiveMeasure(project2, unanalyzedCpp);
+ db.measures().insertLiveMeasure(project3, unanalyzedC);
+
+ assertThat(underTest.countPrBranchAnalyzedLanguageByProjectUuid(db.getSession()))
+ .extracting(PrBranchAnalyzedLanguageCountByProjectDto::getProjectUuid, PrBranchAnalyzedLanguageCountByProjectDto::getBranch, PrBranchAnalyzedLanguageCountByProjectDto::getPullRequest,
+ PrBranchAnalyzedLanguageCountByProjectDto::getUnanalyzedCCount, PrBranchAnalyzedLanguageCountByProjectDto::getUnanalyzedCppCount)
.containsExactlyInAnyOrder(
- tuple(project1.uuid(), 3L, 3L),
- tuple(project2.uuid(), 1L, 1L),
- tuple(project3.uuid(), 2L, 0L)
+ tuple(project1.uuid(), 3L, 3L, 1L, 1L),
+ tuple(project2.uuid(), 1L, 1L, 0L, 1L),
+ tuple(project3.uuid(), 2L, 0L, 1L, 0L)
);
}
private final Long installationDate;
private final String installationVersion;
private final boolean inDocker;
- private final Boolean hasUnanalyzedC;
- private final Boolean hasUnanalyzedCpp;
private final List<String> customSecurityConfigs;
private final List<UserTelemetryDto> users;
private final List<Project> projects;
installationDate = builder.installationDate;
installationVersion = builder.installationVersion;
inDocker = builder.inDocker;
- hasUnanalyzedC = builder.hasUnanalyzedC;
- hasUnanalyzedCpp = builder.hasUnanalyzedCpp;
customSecurityConfigs = builder.customSecurityConfigs == null ? emptyList() : builder.customSecurityConfigs;
users = builder.users;
projects = builder.projects;
return inDocker;
}
- public Optional<Boolean> hasUnanalyzedC() {
- return Optional.ofNullable(hasUnanalyzedC);
- }
-
- public Optional<Boolean> hasUnanalyzedCpp() {
- return Optional.ofNullable(hasUnanalyzedCpp);
- }
-
public List<String> getCustomSecurityConfigs() {
return customSecurityConfigs;
}
private Long installationDate;
private String installationVersion;
private boolean inDocker = false;
- private Boolean hasUnanalyzedC;
- private Boolean hasUnanalyzedCpp;
private List<String> customSecurityConfigs;
private List<UserTelemetryDto> users;
private List<Project> projects;
return this;
}
- Builder setHasUnanalyzedC(@Nullable Boolean hasUnanalyzedC) {
- this.hasUnanalyzedC = hasUnanalyzedC;
- return this;
- }
-
- Builder setHasUnanalyzedCpp(@Nullable Boolean hasUnanalyzedCpp) {
- this.hasUnanalyzedCpp = hasUnanalyzedCpp;
- return this;
- }
-
Builder setCustomSecurityConfigs(List<String> customSecurityConfigs) {
this.customSecurityConfigs = customSecurityConfigs;
return this;
private final String projectUuid;
private final Long branchCount;
private final Long pullRequestCount;
+ private final Boolean hasUnanalyzedC;
+ private final Boolean hasUnanalyzedCpp;
private final String scm;
private final String ci;
private final String devopsPlatform;
- ProjectStatistics(String projectUuid, Long branchCount, Long pullRequestCount, @Nullable String scm, @Nullable String ci, @Nullable String devopsPlatform) {
+ ProjectStatistics(String projectUuid, Long branchCount, Long pullRequestCount, @Nullable Boolean hasUnanalyzedC, @Nullable Boolean hasUnanalyzedCpp,
+ @Nullable String scm, @Nullable String ci, @Nullable String devopsPlatform) {
this.projectUuid = projectUuid;
this.branchCount = branchCount;
this.pullRequestCount = pullRequestCount;
+ this.hasUnanalyzedC = hasUnanalyzedC;
+ this.hasUnanalyzedCpp = hasUnanalyzedCpp;
this.scm = scm;
this.ci = ci;
this.devopsPlatform = devopsPlatform;
public String getDevopsPlatform() {
return devopsPlatform;
}
+
+ public Optional<Boolean> hasUnanalyzedC() {
+ return Optional.ofNullable(hasUnanalyzedC);
+ }
+
+ public Optional<Boolean> hasUnanalyzedCpp() {
+ return Optional.ofNullable(hasUnanalyzedCpp);
+ }
}
}
json.endArray();
}
- statistics.hasUnanalyzedC().ifPresent(hasUnanalyzedC -> json.prop("hasUnanalyzedC", hasUnanalyzedC));
- statistics.hasUnanalyzedCpp().ifPresent(hasUnanalyzedCpp -> json.prop("hasUnanalyzedCpp", hasUnanalyzedCpp));
-
if (statistics.getInstallationDate() != null) {
json.prop("installationDate", toUtc(statistics.getInstallationDate()));
}
json.prop("scm", project.getScm());
json.prop("ci", project.getCi());
json.prop("devopsPlatform", project.getDevopsPlatform());
+ project.hasUnanalyzedC().ifPresent(hasUnanalyzedC -> json.prop("hasUnanalyzedC", hasUnanalyzedC));
+ project.hasUnanalyzedCpp().ifPresent(hasUnanalyzedCpp -> json.prop("hasUnanalyzedCpp", hasUnanalyzedCpp));
json.endObject();
});
json.endArray();
"}");
}
- @Test
- public void writes_has_unanalyzed_languages() {
- TelemetryData data = SOME_TELEMETRY_DATA
- .setHasUnanalyzedC(true)
- .setHasUnanalyzedCpp(false)
- .build();
-
- String json = writeTelemetryData(data);
-
- assertJson(json).isSimilarTo("{" +
- " \"hasUnanalyzedC\":true," +
- " \"hasUnanalyzedCpp\":false," +
- "}");
- }
-
@Test
public void writes_security_custom_config() {
TelemetryData data = SOME_TELEMETRY_DATA
}
@Test
- public void writes_all_projects_stats() {
+ public void writes_all_projects_stats_with_analyzed_languages() {
TelemetryData data = SOME_TELEMETRY_DATA
- .setProjectStatistics(getProjectStats())
+ .setProjectStatistics(getProjectStats(true))
.build();
String json = writeTelemetryData(data);
" \"pullRequestCount\": 2," +
" \"scm\": \"scm-0\"," +
" \"ci\": \"ci-0\"," +
- " \"devopsPlatform\": \"devops-0\"" +
+ " \"devopsPlatform\": \"devops-0\"," +
+ " \"hasUnanalyzedC\": true," +
+ " \"hasUnanalyzedCpp\": false" +
" }," +
" {" +
" \"projectUuid\": \"uuid-1\"," +
" \"pullRequestCount\": 4," +
" \"scm\": \"scm-1\"," +
" \"ci\": \"ci-1\"," +
- " \"devopsPlatform\": \"devops-1\"" +
+ " \"devopsPlatform\": \"devops-1\"," +
+ " \"hasUnanalyzedC\": false," +
+ " \"hasUnanalyzedCpp\": true" +
" }," +
" {" +
" \"projectUuid\": \"uuid-2\"," +
" \"pullRequestCount\": 6," +
" \"scm\": \"scm-2\"," +
" \"ci\": \"ci-2\"," +
- " \"devopsPlatform\": \"devops-2\"" +
+ " \"devopsPlatform\": \"devops-2\"," +
+ " \"hasUnanalyzedC\": true," +
+ " \"hasUnanalyzedCpp\": false" +
" }" +
" ]" +
"}");
}
+ @Test
+ public void writes_all_projects_stats_with_unanalyzed_languages() {
+ TelemetryData data = SOME_TELEMETRY_DATA
+ .setProjectStatistics(getProjectStats(false))
+ .build();
+
+ String json = writeTelemetryData(data);
+ assertThat(json).doesNotContain("hasUnanalyzedC", "hasUnanalyzedCpp");
+ }
+
@NotNull
private static List<UserTelemetryDto> getUsers() {
return IntStream.range(0, 3)
return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.Project("uuid-" + i, 1L, "lang-" + i, (i + 1L) * 2L)).collect(Collectors.toList());
}
- private List<TelemetryData.ProjectStatistics> getProjectStats() {
- return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.ProjectStatistics("uuid-" + i, (i + 1L) * 2L, (i + 1L) * 2L, "scm-" + i, "ci-" + i, "devops-" + i))
+ private List<TelemetryData.ProjectStatistics> getProjectStats(boolean hasUnanalyzedLanguages) {
+ return IntStream.range(0, 3).mapToObj(i -> new TelemetryData.ProjectStatistics("uuid-" + i, (i + 1L) * 2L, (i + 1L) * 2L, hasUnanalyzedLanguages ? i % 2 == 0 : null, hasUnanalyzedLanguages ? i % 2 != 0 : null, "scm-" + i, "ci-" + i, "devops-" + i))
.collect(Collectors.toList());
}
import org.sonar.db.alm.setting.ALM;
import org.sonar.db.alm.setting.ProjectAlmKeyAndProject;
import org.sonar.db.component.AnalysisPropertyValuePerProject;
-import org.sonar.db.component.PrAndBranchCountByProjectDto;
+import org.sonar.db.component.PrBranchAnalyzedLanguageCountByProjectDto;
import org.sonar.db.measure.ProjectMeasureDto;
import org.sonar.server.platform.DockerSupport;
import org.sonar.server.property.InternalProperties;
import static org.sonar.core.platform.EditionProvider.Edition.COMMUNITY;
import static org.sonar.core.platform.EditionProvider.Edition.DATACENTER;
import static org.sonar.core.platform.EditionProvider.Edition.ENTERPRISE;
-import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_CPP_KEY;
-import static org.sonar.server.metric.UnanalyzedLanguageMetrics.UNANALYZED_C_KEY;
@ServerSide
public class TelemetryDataLoaderImpl implements TelemetryDataLoader {
data.setPlugins(plugins);
try (DbSession dbSession = dbClient.openSession(false)) {
data.setDatabase(loadDatabaseMetadata(dbSession));
- long numberOfUnanalyzedCMeasures = dbClient.liveMeasureDao().countProjectsHavingMeasure(dbSession, UNANALYZED_C_KEY);
- long numberOfUnanalyzedCppMeasures = dbClient.liveMeasureDao().countProjectsHavingMeasure(dbSession, UNANALYZED_CPP_KEY);
- editionProvider.get()
- .filter(edition -> edition.equals(COMMUNITY))
- .ifPresent(edition -> {
- data.setHasUnanalyzedC(numberOfUnanalyzedCMeasures > 0);
- data.setHasUnanalyzedCpp(numberOfUnanalyzedCppMeasures > 0);
- });
Map<String, String> scmByProject = getAnalysisPropertyByProject(dbSession, SONAR_ANALYSIS_DETECTEDSCM);
Map<String, String> ciByProject = getAnalysisPropertyByProject(dbSession, SONAR_ANALYSIS_DETECTEDCI);
Map<String, ProjectAlmKeyAndProject> almAndUrlByProject = getAlmAndUrlByProject(dbSession);
List<String> projectUuids = dbClient.projectDao().selectAllProjectUuids(dbSession);
- Map<String, PrAndBranchCountByProjectDto> prAndBranchCountByProjects = dbClient.branchDao().countPrAndBranchByProjectUuid(dbSession)
- .stream().collect(Collectors.toMap(PrAndBranchCountByProjectDto::getProjectUuid, Function.identity()));
+ Map<String, PrBranchAnalyzedLanguageCountByProjectDto> prAndBranchCountByProjects = dbClient.branchDao().countPrBranchAnalyzedLanguageByProjectUuid(dbSession)
+ .stream().collect(Collectors.toMap(PrBranchAnalyzedLanguageCountByProjectDto::getProjectUuid, Function.identity()));
+ boolean isCommunityEdition = editionProvider.get().filter(edition -> edition.equals(COMMUNITY)).isPresent();
List<TelemetryData.ProjectStatistics> projectStatistics = new ArrayList<>();
for (String projectUuid : projectUuids) {
- Long branchCount = Optional.ofNullable(prAndBranchCountByProjects.get(projectUuid)).map(PrAndBranchCountByProjectDto::getBranch).orElse(0L);
- Long pullRequestCount = Optional.ofNullable(prAndBranchCountByProjects.get(projectUuid)).map(PrAndBranchCountByProjectDto::getPullRequest).orElse(0L);
+ Optional<PrBranchAnalyzedLanguageCountByProjectDto> counts = ofNullable(prAndBranchCountByProjects.get(projectUuid));
+
+ Long branchCount = counts.map(PrBranchAnalyzedLanguageCountByProjectDto::getBranch).orElse(0L);
+ Long pullRequestCount = counts.map(PrBranchAnalyzedLanguageCountByProjectDto::getPullRequest).orElse(0L);
+
+ Boolean hasUnanalyzedCMeasures = null;
+ Boolean hasUnanalyzedCppMeasures = null;
+ if (isCommunityEdition) {
+ hasUnanalyzedCMeasures = counts.map(PrBranchAnalyzedLanguageCountByProjectDto::getUnanalyzedCCount).orElse(0L) > 0;
+ hasUnanalyzedCppMeasures = counts.map(PrBranchAnalyzedLanguageCountByProjectDto::getUnanalyzedCppCount).orElse(0L) > 0;
+ }
+
String scm = Optional.ofNullable(scmByProject.get(projectUuid)).orElse(UNDETECTED);
String ci = Optional.ofNullable(ciByProject.get(projectUuid)).orElse(UNDETECTED);
String devopsPlatform = null;
}
devopsPlatform = Optional.ofNullable(devopsPlatform).orElse(UNDETECTED);
- projectStatistics.add(new TelemetryData.ProjectStatistics(projectUuid, branchCount, pullRequestCount, scm, ci, devopsPlatform));
+ projectStatistics.add(
+ new TelemetryData.ProjectStatistics(projectUuid, branchCount, pullRequestCount, hasUnanalyzedCMeasures, hasUnanalyzedCppMeasures, scm, ci, devopsPlatform));
}
data.setProjectStatistics(projectStatistics);
TelemetryData data = communityUnderTest.load();
- assertThat(data.hasUnanalyzedC().get()).isTrue();
- assertThat(data.hasUnanalyzedCpp().get()).isTrue();
+ assertThat(data.getProjectStatistics())
+ .extracting(TelemetryData.ProjectStatistics::hasUnanalyzedC, TelemetryData.ProjectStatistics::hasUnanalyzedCpp)
+ .containsExactlyInAnyOrder(tuple(Optional.of(true), Optional.of(true)), tuple(Optional.of(true), Optional.of(false)));
}
@Test
TelemetryData data = communityUnderTest.load();
- assertThat(data.hasUnanalyzedC()).isEmpty();
- assertThat(data.hasUnanalyzedCpp()).isEmpty();
- }
-
- @Test
- public void unanalyzed_languages_flags_are_set_to_false_when_no_unanalyzed_languages_and_edition_is_community() {
- when(editionProvider.get()).thenReturn(Optional.of(COMMUNITY));
-
- TelemetryData data = communityUnderTest.load();
-
- assertThat(data.hasUnanalyzedC().get()).isFalse();
- assertThat(data.hasUnanalyzedCpp().get()).isFalse();
+ assertThat(data.getProjectStatistics())
+ .extracting(TelemetryData.ProjectStatistics::hasUnanalyzedC, TelemetryData.ProjectStatistics::hasUnanalyzedCpp)
+ .containsExactlyInAnyOrder(tuple(Optional.empty(), Optional.empty()), tuple(Optional.empty(), Optional.empty()));
}
@Test