aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorlukasz-jarocki-sonarsource <lukasz.jarocki@sonarsource.com>2023-11-03 14:54:02 +0100
committersonartech <sonartech@sonarsource.com>2023-11-08 20:02:52 +0000
commita4718d6858cc6e44080641cb1da4e8f5c9ee0762 (patch)
treed5bb8099dd7b17b949ede5653fd88bece45612b4 /server
parent5e1db2ab6fb799e34d8c83191253f1f9b02da58e (diff)
downloadsonarqube-a4718d6858cc6e44080641cb1da4e8f5c9ee0762.tar.gz
sonarqube-a4718d6858cc6e44080641cb1da4e8f5c9ee0762.zip
SONAR-20892 Updated api/measures endpoints to return renamed metric
Diffstat (limited to 'server')
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java10
-rw-r--r--server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java3
-rw-r--r--server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/metric/RemovedMetricConverter.java64
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/metric/RemovedMetricConverterTest.java60
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java2
-rw-r--r--server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java6
-rw-r--r--server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java8
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java35
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java46
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java18
-rw-r--r--server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java38
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java2
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java31
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java6
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentResponseCommon.java80
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java46
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java1
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java3
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java2
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MetricDtoToWsMetric.java12
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java53
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java19
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java19
-rw-r--r--server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java10
-rw-r--r--server/sonar-webserver-webapi/src/main/resources/org/sonar/server/measure/ws/component_tree-example.json22
-rw-r--r--server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java4
27 files changed, 518 insertions, 92 deletions
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java
index 2eeab2ff2c3..389f862adbe 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/issue/IssueCounter.java
@@ -39,6 +39,7 @@ import static org.sonar.api.issue.Issue.RESOLUTION_WONT_FIX;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_REOPENED;
+import static org.sonar.api.measures.CoreMetrics.ACCEPTED_ISSUES_KEY;
import static org.sonar.api.measures.CoreMetrics.BLOCKER_VIOLATIONS_KEY;
import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
import static org.sonar.api.measures.CoreMetrics.CODE_SMELLS_KEY;
@@ -63,7 +64,6 @@ import static org.sonar.api.measures.CoreMetrics.REOPENED_ISSUES_KEY;
import static org.sonar.api.measures.CoreMetrics.SECURITY_HOTSPOTS_KEY;
import static org.sonar.api.measures.CoreMetrics.VIOLATIONS_KEY;
import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
-import static org.sonar.api.measures.CoreMetrics.WONT_FIX_ISSUES_KEY;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.rule.Severity.CRITICAL;
import static org.sonar.api.rule.Severity.INFO;
@@ -169,7 +169,7 @@ public class IssueCounter extends IssueVisitor {
addMeasure(component, REOPENED_ISSUES_KEY, currentCounters.counter().reopened);
addMeasure(component, CONFIRMED_ISSUES_KEY, currentCounters.counter().confirmed);
addMeasure(component, FALSE_POSITIVE_ISSUES_KEY, currentCounters.counter().falsePositives);
- addMeasure(component, WONT_FIX_ISSUES_KEY, currentCounters.counter().wontFix);
+ addMeasure(component, ACCEPTED_ISSUES_KEY, currentCounters.counter().accepted);
}
private void addMeasuresByType(Component component) {
@@ -221,7 +221,7 @@ public class IssueCounter extends IssueVisitor {
private int reopened = 0;
private int confirmed = 0;
private int falsePositives = 0;
- private int wontFix = 0;
+ private int accepted = 0;
private final Multiset<String> severityBag = HashMultiset.create();
private final EnumMultiset<RuleType> typeBag = EnumMultiset.create(RuleType.class);
@@ -231,7 +231,7 @@ public class IssueCounter extends IssueVisitor {
reopened += counter.reopened;
confirmed += counter.confirmed;
falsePositives += counter.falsePositives;
- wontFix += counter.wontFix;
+ accepted += counter.accepted;
severityBag.addAll(counter.severityBag);
typeBag.addAll(counter.typeBag);
}
@@ -250,7 +250,7 @@ public class IssueCounter extends IssueVisitor {
} else if (RESOLUTION_FALSE_POSITIVE.equals(issue.resolution())) {
falsePositives++;
} else if (RESOLUTION_WONT_FIX.equals(issue.resolution())) {
- wontFix++;
+ accepted++;
}
switch (issue.status()) {
case STATUS_OPEN:
diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
index 0d67496f255..3b922906b8a 100644
--- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
+++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistLiveMeasuresStep.java
@@ -43,6 +43,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.measure.LiveMeasureDto;
+import static org.sonar.api.measures.CoreMetrics.ACCEPTED_ISSUES_KEY;
import static org.sonar.api.measures.CoreMetrics.BLOCKER_VIOLATIONS_KEY;
import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
import static org.sonar.api.measures.CoreMetrics.CLASSES_KEY;
@@ -108,7 +109,7 @@ public class PersistLiveMeasuresStep implements ComputationStep {
MAJOR_VIOLATIONS_KEY, MINOR_VIOLATIONS_KEY, NCLOC_KEY, NCLOC_DATA_KEY, NCLOC_LANGUAGE_DISTRIBUTION_KEY, OPEN_ISSUES_KEY, RELIABILITY_RATING_KEY,
RELIABILITY_REMEDIATION_EFFORT_KEY, REOPENED_ISSUES_KEY, SECURITY_HOTSPOTS_KEY, SECURITY_HOTSPOTS_REVIEWED_KEY, SECURITY_HOTSPOTS_REVIEWED_STATUS_KEY,
SECURITY_HOTSPOTS_TO_REVIEW_STATUS_KEY, SECURITY_RATING_KEY, SECURITY_REMEDIATION_EFFORT_KEY, SECURITY_REVIEW_RATING_KEY, SQALE_DEBT_RATIO_KEY, TECHNICAL_DEBT_KEY,
- SQALE_RATING_KEY, STATEMENTS_KEY, VIOLATIONS_KEY, VULNERABILITIES_KEY, WONT_FIX_ISSUES_KEY
+ SQALE_RATING_KEY, STATEMENTS_KEY, VIOLATIONS_KEY, VULNERABILITIES_KEY, ACCEPTED_ISSUES_KEY
);
private final DbClient dbClient;
private final MetricRepository metricRepository;
diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
index e7aa43128dc..a6d26b3b7c2 100644
--- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
+++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/IssueCounterTest.java
@@ -50,6 +50,8 @@ import static org.sonar.api.issue.Issue.STATUS_CLOSED;
import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
import static org.sonar.api.issue.Issue.STATUS_OPEN;
import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
+import static org.sonar.api.measures.CoreMetrics.ACCEPTED_ISSUES;
+import static org.sonar.api.measures.CoreMetrics.ACCEPTED_ISSUES_KEY;
import static org.sonar.api.measures.CoreMetrics.BLOCKER_VIOLATIONS;
import static org.sonar.api.measures.CoreMetrics.BLOCKER_VIOLATIONS_KEY;
import static org.sonar.api.measures.CoreMetrics.BUGS;
@@ -133,7 +135,7 @@ public class IssueCounterTest {
.add(NEW_MINOR_VIOLATIONS)
.add(NEW_INFO_VIOLATIONS)
.add(FALSE_POSITIVE_ISSUES)
- .add(WONT_FIX_ISSUES)
+ .add(ACCEPTED_ISSUES)
.add(CODE_SMELLS)
.add(BUGS)
.add(VULNERABILITIES)
@@ -200,10 +202,10 @@ public class IssueCounterTest {
underTest.beforeComponent(PROJECT);
underTest.afterComponent(PROJECT);
- assertMeasures(FILE1, entry(VIOLATIONS_KEY, 1), entry(FALSE_POSITIVE_ISSUES_KEY, 1), entry(WONT_FIX_ISSUES_KEY, 1));
- assertMeasures(FILE2, entry(VIOLATIONS_KEY, 2), entry(FALSE_POSITIVE_ISSUES_KEY, 0), entry(WONT_FIX_ISSUES_KEY, 1));
+ assertMeasures(FILE1, entry(VIOLATIONS_KEY, 1), entry(FALSE_POSITIVE_ISSUES_KEY, 1), entry(ACCEPTED_ISSUES_KEY, 1));
+ assertMeasures(FILE2, entry(VIOLATIONS_KEY, 2), entry(FALSE_POSITIVE_ISSUES_KEY, 0), entry(ACCEPTED_ISSUES_KEY, 1));
assertMeasures(FILE3, entry(VIOLATIONS_KEY, 0));
- assertMeasures(PROJECT, entry(VIOLATIONS_KEY, 3), entry(FALSE_POSITIVE_ISSUES_KEY, 1), entry(WONT_FIX_ISSUES_KEY, 2));
+ assertMeasures(PROJECT, entry(VIOLATIONS_KEY, 3), entry(FALSE_POSITIVE_ISSUES_KEY, 1), entry(ACCEPTED_ISSUES_KEY, 2));
}
@Test
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/metric/RemovedMetricConverter.java b/server/sonar-db-dao/src/main/java/org/sonar/db/metric/RemovedMetricConverter.java
new file mode 100644
index 00000000000..07c46eecfb7
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/metric/RemovedMetricConverter.java
@@ -0,0 +1,64 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.metric;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.measures.CoreMetrics;
+
+/*
+* This class has been introduced to contain the usage of deprecated and renamed metric 'WONT_FIX' in one place.
+* It should be removed in SQ 11.0.
+*/
+public class RemovedMetricConverter {
+ public static final String REMOVED_METRIC = CoreMetrics.WONT_FIX_ISSUES_KEY;
+ public static final String REMOVED_METRIC_SHORT_NAME = CoreMetrics.WONT_FIX_ISSUES.getName();
+ public static final String REMOVED_METRIC_DESCRIPTION = CoreMetrics.WONT_FIX_ISSUES.getDescription();
+ public static final String DEPRECATED_METRIC_REPLACEMENT = CoreMetrics.ACCEPTED_ISSUES_KEY;
+
+ private RemovedMetricConverter() {
+ // static methods only
+ }
+
+ public static List<String> withRemovedMetricAlias(Collection<String> metrics) {
+ if (metrics.contains(REMOVED_METRIC)) {
+ Set<String> newMetrics = new HashSet<>(metrics);
+ newMetrics.remove(REMOVED_METRIC);
+ newMetrics.add(DEPRECATED_METRIC_REPLACEMENT);
+ return newMetrics.stream().toList();
+ } else {
+ return new ArrayList<>(metrics);
+ }
+ }
+
+ @CheckForNull
+ public static String includeRenamedMetrics(@Nullable String metric) {
+ if (REMOVED_METRIC.equals(metric)) {
+ return DEPRECATED_METRIC_REPLACEMENT;
+ } else {
+ return metric;
+ }
+ }
+}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/metric/RemovedMetricConverterTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/metric/RemovedMetricConverterTest.java
new file mode 100644
index 00000000000..f29df8268ff
--- /dev/null
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/metric/RemovedMetricConverterTest.java
@@ -0,0 +1,60 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.metric;
+
+import java.util.List;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class RemovedMetricConverterTest {
+
+ @Test
+ public void withRemovedMetricAlias_whenListContainsWontFix_shouldReturnListWithAccepted() {
+ List<String> coreMetrics = List.of("wont_fix_issues", "blocker_violations", "critical_violations");
+
+ List<String> upToDateMetrics = RemovedMetricConverter.withRemovedMetricAlias(coreMetrics);
+
+ assertThat(upToDateMetrics).containsExactlyInAnyOrder("accepted_issues", "blocker_violations", "critical_violations");
+ }
+
+ @Test
+ public void withRemovedMetricAlias_whenListContainsAccepted_shouldReturnListWithAccepted() {
+ List<String> coreMetrics = List.of("accepted_issues", "blocker_violations", "critical_violations");
+
+ List<String> upToDateMetrics = RemovedMetricConverter.withRemovedMetricAlias(coreMetrics);
+
+ assertThat(upToDateMetrics).containsExactlyInAnyOrder("accepted_issues", "blocker_violations", "critical_violations");
+ }
+
+ @Test
+ public void includeRenamedMetrics_whenWontFixIssuesPassed_shouldReturnAccepted() {
+ String upToDateMetric = RemovedMetricConverter.includeRenamedMetrics("wont_fix_issues");
+
+ assertThat(upToDateMetric).isEqualTo("accepted_issues");
+ }
+
+ @Test
+ public void includeRenamedMetrics_whenAcceptedIssuesPassed_shouldReturnAccepted() {
+ String upToDateMetric = RemovedMetricConverter.includeRenamedMetrics("accepted_issues");
+
+ assertThat(upToDateMetric).isEqualTo("accepted_issues");
+ }
+} \ No newline at end of file
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java
index 5f35d1caadf..ea025607fd4 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v104/RenameWontFixIssuesMetric.java
@@ -27,7 +27,7 @@ import org.sonar.server.platform.db.migration.step.Upsert;
public class RenameWontFixIssuesMetric extends DataChange {
private static final String UPDATE_QUERY = """
- update metrics set name='accepted_issues', description='Accepted issues' where name='wont_fix_issues'
+ update metrics set name='accepted_issues', description='Accepted issues', short_name='Accepted issues' where name='wont_fix_issues'
""";
public RenameWontFixIssuesMetric(Database db) {
diff --git a/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java b/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java
index bf19912492a..35bfa6854a8 100644
--- a/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java
+++ b/server/sonar-webserver-core/src/it/java/org/sonar/server/startup/RegisterMetricsIT.java
@@ -136,10 +136,12 @@ public class RegisterMetricsIT {
}
@Test
- public void insert_core_metrics() {
+ public void insert_core_metrics_without_removed_metric() {
register.start();
- assertThat(dbTester.countRowsOfTable("metrics")).isEqualTo(CoreMetrics.getMetrics().size());
+ // Metric CoreMetrics.WONT_FIX_ISSUES was renamed to CoreMetrics.ACCEPTED_ISSUES in 10.3.
+ // We don't want to insert it anymore
+ assertThat(dbTester.countRowsOfTable("metrics")).isEqualTo(CoreMetrics.getMetrics().size() - 1);
}
@Test
diff --git a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java
index 238c97dd8f6..8afa7232280 100644
--- a/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java
+++ b/server/sonar-webserver-core/src/main/java/org/sonar/server/startup/RegisterMetrics.java
@@ -20,6 +20,7 @@
package org.sonar.server.startup;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.FluentIterable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -35,10 +36,11 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.metric.MetricToDto;
+import org.springframework.beans.factory.annotation.Autowired;
import static com.google.common.collect.FluentIterable.concat;
import static com.google.common.collect.Lists.newArrayList;
-import org.springframework.beans.factory.annotation.Autowired;
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC;
public class RegisterMetrics implements Startable {
@@ -65,7 +67,9 @@ public class RegisterMetrics implements Startable {
@Override
public void start() {
- register(concat(CoreMetrics.getMetrics(), getPluginMetrics()));
+ FluentIterable<Metric> metricsToRegister = concat(CoreMetrics.getMetrics(), getPluginMetrics())
+ .filter(m -> !REMOVED_METRIC.equals(m.getKey()));
+ register(metricsToRegister);
}
@Override
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java
index c9520642092..bee0bba79ce 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentActionIT.java
@@ -46,6 +46,7 @@ import static java.lang.Double.parseDouble;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME;
@@ -356,6 +357,26 @@ public class ComponentActionIT {
}
@Test
+ public void shouldReturnRenamedMetric() {
+ ProjectData projectData = db.components().insertPrivateProject(p -> p.setKey("MY_PROJECT")
+ .setName("My Project"));
+ userSession.addProjectPermission(USER, projectData.getProjectDto())
+ .registerBranches(projectData.getMainBranchDto());
+ ComponentDto mainBranch = projectData.getMainBranchComponent();
+ SnapshotDto analysis = db.components().insertSnapshot(mainBranch, s -> s.setPeriodDate(parseDateTime("2016-01-11T10:49:50+0100").getTime())
+ .setPeriodMode("previous_version")
+ .setPeriodParam("1.0-SNAPSHOT"));
+
+ MetricDto accepted_issues = insertAcceptedIssuesMetric();
+ db.measures().insertLiveMeasure(mainBranch, accepted_issues, m -> m.setValue(10d));
+
+ db.commit();
+
+ ComponentWsResponse response = newRequest(projectData.projectKey(), "wont_fix_issues");
+ assertThat(response.getMetrics().getMetrics(0).getKey()).isEqualTo("wont_fix_issues");
+ }
+
+ @Test
public void json_example() {
ProjectData projectData = db.components().insertPrivateProject();
ComponentDto mainBranch = projectData.getMainBranchComponent();
@@ -417,6 +438,20 @@ public class ComponentActionIT {
assertJson(response).isSimilarTo(getClass().getResource("component-example.json"));
}
+ private MetricDto insertAcceptedIssuesMetric() {
+ MetricDto acceptedIssues = db.measures().insertMetric(m -> m.setKey("accepted_issues")
+ .setShortName("Accepted Issues")
+ .setDescription("Accepted issues")
+ .setDomain("Issues")
+ .setValueType("INT")
+ .setDirection(-1)
+ .setQualitative(false)
+ .setHidden(false));
+ db.commit();
+ return acceptedIssues;
+ }
+
+
private ComponentWsResponse newRequest(String componentKey, String metricKeys) {
return ws.newRequest()
.setParam(PARAM_COMPONENT, componentKey)
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java
index 8b885bf3c12..05a1513f222 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/ComponentTreeActionIT.java
@@ -162,11 +162,16 @@ public class ComponentTreeActionIT {
db.measures().insertLiveMeasure(dir, newViolations, m -> m.setValue(25.0d));
db.measures().insertLiveMeasure(mainBranch, newViolations, m -> m.setValue(255.0d));
+ MetricDto accepted_issues = insertAcceptedIssuesMetric();
+ db.measures().insertLiveMeasure(file1, accepted_issues, m -> m.setValue(10d));
+ db.measures().insertLiveMeasure(dir, accepted_issues, m -> m.setValue(10d));
+ db.measures().insertLiveMeasure(mainBranch, accepted_issues, m -> m.setValue(10d));
+
db.commit();
String response = ws.newRequest()
.setParam(PARAM_COMPONENT, mainBranch.getKey())
- .setParam(PARAM_METRIC_KEYS, "ncloc, complexity, new_violations")
+ .setParam(PARAM_METRIC_KEYS, "ncloc, complexity, new_violations, accepted_issues")
.setParam(PARAM_ADDITIONAL_FIELDS, "metrics,period")
.execute()
.getInput();
@@ -180,6 +185,31 @@ public class ComponentTreeActionIT {
}
@Test
+ public void shouldReturnRenamedMetric() {
+ ProjectData projectData = db.components().insertPrivateProject(p -> p.setKey("MY_PROJECT")
+ .setName("My Project"));
+ addProjectPermission(projectData);
+ ComponentDto mainBranch = projectData.getMainBranchComponent();
+ SnapshotDto analysis = db.components().insertSnapshot(mainBranch, s -> s.setPeriodDate(parseDateTime("2016-01-11T10:49:50+0100").getTime())
+ .setPeriodMode("previous_version")
+ .setPeriodParam("1.0-SNAPSHOT"));
+
+ MetricDto accepted_issues = insertAcceptedIssuesMetric();
+ db.measures().insertLiveMeasure(mainBranch, accepted_issues, m -> m.setValue(10d));
+
+ db.commit();
+
+ ComponentTreeWsResponse response = ws.newRequest()
+ .setParam(PARAM_COMPONENT, mainBranch.getKey())
+ .setParam(PARAM_METRIC_KEYS, "wont_fix_issues")
+ .setParam(PARAM_ADDITIONAL_FIELDS, "metrics")
+ .executeProtobuf(ComponentTreeWsResponse.class);
+
+ assertThat(response.getMetrics().getMetrics(0).getKey()).isEqualTo("wont_fix_issues");
+ assertThat(response.getBaseComponent().getMeasures(0).getMetric()).isEqualTo("wont_fix_issues");
+ }
+
+ @Test
public void empty_response() {
ProjectData projectData = db.components().insertPrivateProject();
ComponentDto mainBranch = projectData.getMainBranchComponent();
@@ -1077,6 +1107,20 @@ public class ComponentTreeActionIT {
return metric;
}
+ private MetricDto insertAcceptedIssuesMetric() {
+ MetricDto metric = dbClient.metricDao().insert(dbSession, newMetricDto()
+ .setKey("accepted_issues")
+ .setShortName("Accepted Issues")
+ .setDescription("Accepted issues")
+ .setDomain("Issues")
+ .setValueType(INT.name())
+ .setDirection(-1)
+ .setQualitative(false)
+ .setHidden(false));
+ db.commit();
+ return metric;
+ }
+
private MetricDto insertNclocMetric() {
MetricDto metric = dbClient.metricDao().insert(dbSession, newMetricDto()
.setKey("ncloc")
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java
index b854fe6b1a7..c81945d50ed 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchActionIT.java
@@ -118,6 +118,24 @@ public class SearchActionIT {
}
@Test
+ public void search_shouldReturnAcceptedIssuesMetric_whenIsCalledWithDeprecatedWontFixIssuesMetric() {
+ ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
+ userSession.addProjectPermission(UserRole.USER, project);
+ MetricDto acceptedIssues = db.measures().insertMetric(m -> m.setValueType(INT.name())
+ .setKey("accepted_issues")
+ .setShortName("Accepted Issues"));
+ db.measures().insertLiveMeasure(project, acceptedIssues, m -> m.setValue(10d));
+
+ SearchWsResponse result = call(singletonList(project.getKey()), singletonList("wont_fix_issues"));
+
+ List<Measure> measures = result.getMeasuresList();
+ assertThat(measures).hasSize(1);
+ Measure measure = measures.get(0);
+ assertThat(measure.getMetric()).isEqualTo("wont_fix_issues");
+ assertThat(measure.getValue()).isEqualTo("10");
+ }
+
+ @Test
public void return_best_value() {
ComponentDto project = db.components().insertPrivateProject().getMainBranchComponent();
userSession.addProjectPermission(UserRole.USER, project);
diff --git a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java
index 885f0452411..aeec043073f 100644
--- a/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java
+++ b/server/sonar-webserver-webapi/src/it/java/org/sonar/server/measure/ws/SearchHistoryActionIT.java
@@ -90,6 +90,7 @@ public class SearchHistoryActionIT {
private MetricDto nclocMetric;
private MetricDto newViolationMetric;
private MetricDto stringMetric;
+ private MetricDto acceptedIssuesMetric;
@Before
public void setUp() {
@@ -101,6 +102,7 @@ public class SearchHistoryActionIT {
complexityMetric = insertComplexityMetric();
newViolationMetric = insertNewViolationMetric();
stringMetric = insertStringMetric();
+ acceptedIssuesMetric = insertAcceptedIssuesMetric();
}
@Test
@@ -145,18 +147,36 @@ public class SearchHistoryActionIT {
@Test
public void return_metrics() {
dbClient.measureDao().insert(dbSession, newMeasureDto(complexityMetric, project.mainBranchUuid(), analysis).setValue(42.0d));
+ dbClient.measureDao().insert(dbSession, newMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d));
db.commit();
SearchHistoryRequest request = SearchHistoryRequest.builder()
.setComponent(project.projectKey())
- .setMetrics(asList(complexityMetric.getKey(), nclocMetric.getKey(), newViolationMetric.getKey()))
+ .setMetrics(asList(complexityMetric.getKey(), nclocMetric.getKey(), newViolationMetric.getKey(), acceptedIssuesMetric.getKey()))
.build();
SearchHistoryResponse result = call(request);
- assertThat(result.getMeasuresList()).hasSize(3)
+ assertThat(result.getMeasuresList()).hasSize(4)
.extracting(HistoryMeasure::getMetric)
- .containsExactly(complexityMetric.getKey(), nclocMetric.getKey(), newViolationMetric.getKey());
+ .containsExactlyInAnyOrder(complexityMetric.getKey(), nclocMetric.getKey(), newViolationMetric.getKey(), acceptedIssuesMetric.getKey());
+ }
+
+ @Test
+ public void return_renamed_and_deprecated_metric() {
+ dbClient.measureDao().insert(dbSession, newMeasureDto(acceptedIssuesMetric, project.mainBranchUuid(), analysis).setValue(10.0d));
+ db.commit();
+
+ SearchHistoryRequest request = SearchHistoryRequest.builder()
+ .setComponent(project.projectKey())
+ .setMetrics(singletonList("wont_fix_issues"))
+ .build();
+
+ SearchHistoryResponse result = call(request);
+
+ assertThat(result.getMeasuresList()).hasSize(1)
+ .extracting(HistoryMeasure::getMetric)
+ .containsExactlyInAnyOrder("wont_fix_issues");
}
@Test
@@ -557,4 +577,16 @@ public class SearchHistoryActionIT {
db.commit();
return metric;
}
+
+ private MetricDto insertAcceptedIssuesMetric() {
+ MetricDto metric = dbClient.metricDao().insert(dbSession, newMetricDtoWithoutOptimization()
+ .setKey("accepted_issues")
+ .setShortName("Accepted Issues")
+ .setValueType("INT"))
+ .setDirection(-1)
+ .setQualitative(true)
+ .setHidden(false);
+ db.commit();
+ return metric;
+ }
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
index 8b807b8ded6..93315bef077 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImpl.java
@@ -78,7 +78,7 @@ public class MeasureUpdateFormulaFactoryImpl implements MeasureUpdateFormulaFact
new MeasureUpdateFormula(CoreMetrics.FALSE_POSITIVE_ISSUES, false, new AddChildren(),
(context, issues) -> context.setValue(issues.countByResolution(Issue.RESOLUTION_FALSE_POSITIVE, false))),
- new MeasureUpdateFormula(CoreMetrics.WONT_FIX_ISSUES, false, new AddChildren(),
+ new MeasureUpdateFormula(CoreMetrics.ACCEPTED_ISSUES, false, new AddChildren(),
(context, issues) -> context.setValue(issues.countByResolution(Issue.RESOLUTION_WONT_FIX, false))),
new MeasureUpdateFormula(CoreMetrics.OPEN_ISSUES, false, new AddChildren(),
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
index 4ab014e88af..939c4d4d2f2 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
@@ -55,6 +55,7 @@ import static java.lang.String.format;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
+import static org.sonar.db.metric.RemovedMetricConverter.withRemovedMetricAlias;
import static org.sonar.server.component.ws.MeasuresWsParameters.ACTION_COMPONENT;
import static org.sonar.server.component.ws.MeasuresWsParameters.ADDITIONAL_METRICS;
import static org.sonar.server.component.ws.MeasuresWsParameters.ADDITIONAL_PERIOD;
@@ -65,9 +66,9 @@ import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_METRIC_KE
import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_PULL_REQUEST;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
+import static org.sonar.server.measure.ws.ComponentResponseCommon.addMetricToResponseIncludingRenamedMetric;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter;
-import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriod.snapshotToWsPeriods;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
@@ -95,14 +96,17 @@ public class ComponentAction implements MeasuresWsAction {
.setResponseExample(getClass().getResource("component-example.json"))
.setSince("5.4")
.setChangelog(
+ new Change("10.3", "The metric 'wont_fix_issues' is now deprecated in the response. Consume 'accepted_issues' instead."),
+ new Change("10.3", "The use of 'wont_fix_issues' value in 'metricKeys' param is now deprecated. Use 'accepted_issues' instead."),
+ new Change("10.3", "Added new accepted value for the 'metricKeys' param: 'accepted_issues'."),
new Change("10.1", String.format("The use of module keys in parameter '%s' is removed", PARAM_COMPONENT)),
new Change("10.0", format("The use of the following metrics in 'metricKeys' parameter is not deprecated anymore: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("10.0", "the response field periods under measures field is removed."),
new Change("10.0", "the option `periods` of 'additionalFields' request field is removed."),
new Change("9.3", "When the new code period is set to 'reference branch', the response field 'date' under the 'period' field has been removed"),
new Change("9.3", format("The use of the following metrics in 'metricKeys' parameter is deprecated: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("8.8", "deprecated response field 'id' has been removed"),
new Change("8.8", "deprecated response field 'refId' has been removed."),
new Change("8.1", "the response field periods under measures field is deprecated. Use period instead."),
@@ -145,13 +149,13 @@ public class ComponentAction implements MeasuresWsAction {
checkPermissions(component);
SnapshotDto analysis = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, component.branchUuid()).orElse(null);
- List<MetricDto> metrics = searchMetrics(dbSession, new HashSet<>(request.getMetricKeys()));
+ List<MetricDto> metrics = searchMetrics(dbSession, new HashSet<>(withRemovedMetricAlias(request.getMetricKeys())));
List<LiveMeasureDto> measures = searchMeasures(dbSession, component, metrics);
Map<MetricDto, LiveMeasureDto> measuresByMetric = getMeasuresByMetric(measures, metrics);
Optional<Measures.Period> period = snapshotToWsPeriods(analysis);
Optional<RefComponent> reference = getReference(dbSession, component);
- return buildResponse(dbSession, request, component, reference, measuresByMetric, metrics, period);
+ return buildResponse(dbSession, request, component, reference, measuresByMetric, metrics, period, request.getMetricKeys());
}
}
@@ -229,30 +233,33 @@ public class ComponentAction implements MeasuresWsAction {
}
private ComponentWsResponse buildResponse(DbSession dbSession, ComponentRequest request, ComponentDto component, Optional<RefComponent> reference,
- Map<MetricDto, LiveMeasureDto> measuresByMetric, Collection<MetricDto> metrics, Optional<Measures.Period> period) {
+ Map<MetricDto, LiveMeasureDto> measuresByMetric, Collection<MetricDto> metrics, Optional<Measures.Period> period,
+ Collection<String> requestedMetrics) {
ComponentWsResponse.Builder response = ComponentWsResponse.newBuilder();
if (reference.isPresent()) {
BranchDto refBranch = reference.get().getRefBranch();
ComponentDto refComponent = reference.get().getComponent();
response.setComponent(componentDtoToWsComponent(component, measuresByMetric, singletonMap(refComponent.uuid(), refComponent),
- refBranch.isMain() ? null : refBranch.getBranchKey(), null));
+ refBranch.isMain() ? null : refBranch.getBranchKey(), null, requestedMetrics));
} else {
boolean isMainBranch = dbClient.branchDao().selectByUuid(dbSession, component.branchUuid()).map(BranchDto::isMain).orElse(true);
- response.setComponent(componentDtoToWsComponent(component, measuresByMetric, emptyMap(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
+ response.setComponent(componentDtoToWsComponent(component, measuresByMetric, emptyMap(), isMainBranch ? null : request.getBranch(),
+ request.getPullRequest(), requestedMetrics));
}
- setAdditionalFields(request, metrics, period, response);
+ setAdditionalFields(request, metrics, period, response, requestedMetrics);
return response.build();
}
- private static void setAdditionalFields(ComponentRequest request, Collection<MetricDto> metrics, Optional<Measures.Period> period, ComponentWsResponse.Builder response) {
+ private static void setAdditionalFields(ComponentRequest request, Collection<MetricDto> metrics, Optional<Measures.Period> period,
+ ComponentWsResponse.Builder response, Collection<String> requestedMetrics) {
List<String> additionalFields = request.getAdditionalFields();
if (additionalFields != null) {
if (additionalFields.contains(ADDITIONAL_METRICS)) {
- for (MetricDto metric : metrics) {
- response.getMetricsBuilder().addMetrics(metricDtoToWsMetric(metric));
+ for (MetricDto metricDto : metrics) {
+ addMetricToResponseIncludingRenamedMetric(metric -> response.getMetricsBuilder().addMetrics(metric), requestedMetrics, metricDto);
}
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java
index 55760a0070c..4f31a2f3e92 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.measure.ws;
+import java.util.Collection;
import java.util.Map;
import javax.annotation.Nullable;
import org.sonar.db.component.ComponentDto;
@@ -28,6 +29,7 @@ import org.sonarqube.ws.Measures;
import org.sonarqube.ws.Measures.Component;
import static java.util.Optional.ofNullable;
+import static org.sonar.server.measure.ws.ComponentResponseCommon.addMeasureIncludingRenamedMetric;
class ComponentDtoToWsComponent {
private ComponentDtoToWsComponent() {
@@ -36,7 +38,7 @@ class ComponentDtoToWsComponent {
static Component.Builder componentDtoToWsComponent(ComponentDto component, Map<MetricDto, LiveMeasureDto> measuresByMetric,
Map<String, ComponentDto> referenceComponentsByUuid, @Nullable String branch,
- @Nullable String pullRequest) {
+ @Nullable String pullRequest, Collection<String> requestedMetrics) {
Component.Builder wsComponent = componentDtoToWsComponent(component, branch, pullRequest);
ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyComponentUuid());
@@ -47,7 +49,7 @@ class ComponentDtoToWsComponent {
Measures.Measure.Builder measureBuilder = Measures.Measure.newBuilder();
for (Map.Entry<MetricDto, LiveMeasureDto> entry : measuresByMetric.entrySet()) {
MeasureDtoToWsMeasure.updateMeasureBuilder(measureBuilder, entry.getKey(), entry.getValue());
- wsComponent.addMeasures(measureBuilder);
+ addMeasureIncludingRenamedMetric(requestedMetrics, wsComponent, measureBuilder);
measureBuilder.clear();
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentResponseCommon.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentResponseCommon.java
new file mode 100644
index 00000000000..2fa908b6813
--- /dev/null
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentResponseCommon.java
@@ -0,0 +1,80 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.server.measure.ws;
+
+import java.util.Collection;
+import java.util.function.Consumer;
+import org.sonar.db.metric.MetricDto;
+import org.sonar.db.metric.RemovedMetricConverter;
+import org.sonarqube.ws.Measures;
+
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC;
+import static org.sonar.db.metric.RemovedMetricConverter.DEPRECATED_METRIC_REPLACEMENT;
+import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
+import static org.sonar.server.measure.ws.MetricDtoToWsMetric.wontFixToAcceptedWsMetric;
+
+public class ComponentResponseCommon {
+
+ private ComponentResponseCommon() {
+ // static methods only
+ }
+
+ static void addMetricToResponseIncludingRenamedMetric(Consumer<org.sonarqube.ws.Common.Metric> responseBuilder, Collection<String> requestedMetrics,
+ MetricDto metricDto) {
+ if (metricDto.getKey().equals(DEPRECATED_METRIC_REPLACEMENT)) {
+ if (requestedMetrics.contains(DEPRECATED_METRIC_REPLACEMENT)) {
+ responseBuilder.accept(metricDtoToWsMetric(metricDto));
+ }
+ if (requestedMetrics.contains(REMOVED_METRIC)) {
+ responseBuilder.accept(wontFixToAcceptedWsMetric(metricDto));
+ }
+ } else {
+ responseBuilder.accept(metricDtoToWsMetric(metricDto));
+ }
+ }
+
+ public static void addMetricToSearchHistoryResponseIncludingRenamedMetric(Measures.SearchHistoryResponse.Builder response,
+ Collection<String> requestedMetrics, Measures.SearchHistoryResponse.HistoryMeasure.Builder measure) {
+ if (measure.getMetric().equals(DEPRECATED_METRIC_REPLACEMENT)) {
+ if (requestedMetrics.contains(DEPRECATED_METRIC_REPLACEMENT)) {
+ response.addMeasures(measure.build());
+ }
+ if (requestedMetrics.contains(RemovedMetricConverter.REMOVED_METRIC)) {
+ response.addMeasures(measure.setMetric(RemovedMetricConverter.REMOVED_METRIC).build());
+ }
+ } else {
+ response.addMeasures(measure.build());
+ }
+ }
+
+ static void addMeasureIncludingRenamedMetric(Collection<String> requestedMetrics, Measures.Component.Builder componentBuilder,
+ Measures.Measure.Builder measureBuilder) {
+ if (measureBuilder.getMetric().equals(DEPRECATED_METRIC_REPLACEMENT)) {
+ if (requestedMetrics.contains(DEPRECATED_METRIC_REPLACEMENT)) {
+ componentBuilder.addMeasures(measureBuilder.build());
+ }
+ if (requestedMetrics.contains(REMOVED_METRIC)) {
+ componentBuilder.addMeasures(measureBuilder.setMetric(REMOVED_METRIC).build());
+ }
+ } else {
+ componentBuilder.addMeasures(measureBuilder.build());
+ }
+ }
+}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
index 3e089a836a9..d5006a14c02 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
@@ -76,11 +76,14 @@ import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
+import static java.util.Optional.ofNullable;
import static org.sonar.api.measures.Metric.ValueType.DATA;
import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
import static org.sonar.api.utils.Paging.offset;
import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN;
import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES;
+import static org.sonar.db.metric.RemovedMetricConverter.includeRenamedMetrics;
+import static org.sonar.db.metric.RemovedMetricConverter.withRemovedMetricAlias;
import static org.sonar.server.component.ws.MeasuresWsParameters.ACTION_COMPONENT_TREE;
import static org.sonar.server.component.ws.MeasuresWsParameters.ADDITIONAL_METRICS;
import static org.sonar.server.component.ws.MeasuresWsParameters.ADDITIONAL_PERIOD;
@@ -96,16 +99,17 @@ import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_QUALIFIER
import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_STRATEGY;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
+import static org.sonar.server.measure.ws.ComponentResponseCommon.addMeasureIncludingRenamedMetric;
+import static org.sonar.server.measure.ws.ComponentResponseCommon.addMetricToResponseIncludingRenamedMetric;
import static org.sonar.server.measure.ws.MeasureDtoToWsMeasure.updateMeasureBuilder;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter;
-import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriod.snapshotToWsPeriods;
import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PULL_REQUEST_EXAMPLE_001;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
/**
@@ -177,13 +181,16 @@ public class ComponentTreeAction implements MeasuresWsAction {
.setHandler(this)
.addPagingParams(100, MAX_SIZE)
.setChangelog(
+ new Change("10.3", "The metric 'wont_fix_issues' is now deprecated in the response. Consume 'accepted_issues' instead."),
+ new Change("10.3", "The use of 'wont_fix_issues' value in 'metricKeys' and 'metricSort' params is now deprecated. Use 'accepted_issues' instead."),
+ new Change("10.3", "Added new accepted value for the 'metricKeys' and 'metricSort' param: 'accepted_issues'."),
new Change("10.1", String.format("The use of 'BRC' as value for parameter '%s' is removed", ComponentsWsParameters.PARAM_QUALIFIERS)),
new Change("10.0", format("The use of the following metrics in 'metricKeys' parameter is not deprecated anymore: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("10.0", "the response field periods under measures field is removed."),
new Change("10.0", "the option `periods` of 'additionalFields' request field is removed."),
new Change("9.3", format("The use of the following metrics in 'metricKeys' parameter is deprecated: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("8.8", "parameter 'component' is now required"),
new Change("8.8", "deprecated parameter 'baseComponentId' has been removed"),
new Change("8.8", "deprecated parameter 'baseComponentKey' has been removed."),
@@ -279,10 +286,12 @@ public class ComponentTreeAction implements MeasuresWsAction {
Paging.forPageIndex(
request.getPage())
.withPageSize(request.getPageSize())
- .andTotal(data.getComponentCount()));
+ .andTotal(data.getComponentCount()),
+ request.getMetricKeys());
}
- private static ComponentTreeWsResponse buildResponse(ComponentTreeRequest request, ComponentTreeData data, Paging paging) {
+ private static ComponentTreeWsResponse buildResponse(ComponentTreeRequest request, ComponentTreeData data, Paging paging,
+ List<String> requestedMetrics) {
ComponentTreeWsResponse.Builder response = ComponentTreeWsResponse.newBuilder();
response.getPagingBuilder()
.setPageIndex(paging.pageIndex())
@@ -295,7 +304,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
toWsComponent(
data.getBaseComponent(),
data.getMeasuresByComponentUuidAndMetric().row(data.getBaseComponent().uuid()),
- data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
+ data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest(), requestedMetrics));
for (ComponentDto componentDto : data.getComponents()) {
if (componentDto.getCopyComponentUuid() != null) {
@@ -303,23 +312,22 @@ public class ComponentTreeAction implements MeasuresWsAction {
response.addComponents(toWsComponent(
componentDto,
data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
- data.getReferenceComponentsByUuid(), refBranch, null));
+ data.getReferenceComponentsByUuid(), refBranch, null, requestedMetrics));
} else {
response.addComponents(toWsComponent(
componentDto,
data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
- data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
+ data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest(), requestedMetrics));
}
}
if (areMetricsInResponse(request)) {
- Measures.Metrics.Builder metricsBuilder = response.getMetricsBuilder();
for (MetricDto metricDto : data.getMetrics()) {
- metricsBuilder.addMetrics(metricDtoToWsMetric(metricDto));
+ addMetricToResponseIncludingRenamedMetric(metric -> response.getMetricsBuilder().addMetrics(metric), requestedMetrics, metricDto);
}
}
- List<String> additionalFields = Optional.ofNullable(request.getAdditionalFields()).orElse(Collections.emptyList());
+ List<String> additionalFields = ofNullable(request.getAdditionalFields()).orElse(Collections.emptyList());
if (additionalFields.contains(ADDITIONAL_PERIOD) && data.getPeriod() != null) {
response.setPeriod(data.getPeriod());
@@ -359,7 +367,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
.setAdditionalFields(request.paramAsStrings(PARAM_ADDITIONAL_FIELDS))
.setSort(request.paramAsStrings(Param.SORT))
.setAsc(request.paramAsBoolean(Param.ASCENDING))
- .setMetricSort(request.param(PARAM_METRIC_SORT))
+ .setMetricSort(includeRenamedMetrics(request.param(PARAM_METRIC_SORT)))
.setMetricSortFilter(request.mandatoryParam(PARAM_METRIC_SORT_FILTER))
.setMetricPeriodSort(request.paramAsInt(PARAM_METRIC_PERIOD_SORT))
.setPage(request.mandatoryParamAsInt(Param.PAGE))
@@ -367,7 +375,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
.setQuery(request.param(Param.TEXT_QUERY));
String metricSortValue = componentTreeRequest.getMetricSort();
checkRequest(!componentTreeRequest.getMetricKeys().isEmpty(), "The '%s' parameter must contain at least one metric key", PARAM_METRIC_KEYS);
- List<String> sorts = Optional.ofNullable(componentTreeRequest.getSort()).orElse(emptyList());
+ List<String> sorts = ofNullable(componentTreeRequest.getSort()).orElse(emptyList());
checkRequest(metricSortValue == null ^ sorts.contains(METRIC_SORT) ^ sorts.contains(METRIC_PERIOD_SORT),
"To sort by a metric, the '%s' parameter must contain '%s' or '%s', and a metric key must be provided in the '%s' parameter",
Param.SORT, METRIC_SORT, METRIC_PERIOD_SORT, PARAM_METRIC_SORT);
@@ -382,7 +390,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
}
private static Measures.Component.Builder toWsComponent(ComponentDto component, Map<MetricDto, ComponentTreeData.Measure> measures,
- Map<String, ComponentDto> referenceComponentsByUuid, @Nullable String branch, @Nullable String pullRequest) {
+ Map<String, ComponentDto> referenceComponentsByUuid, @Nullable String branch, @Nullable String pullRequest, List<String> requestedMetrics) {
Measures.Component.Builder wsComponent = componentDtoToWsComponent(component, branch, pullRequest);
ComponentDto referenceComponent = referenceComponentsByUuid.get(component.getCopyComponentUuid());
if (referenceComponent != null) {
@@ -395,7 +403,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
ComponentTreeData.Measure measure = entry.getValue();
boolean onNewCode = entry.getKey().getKey().startsWith("new_");
updateMeasureBuilder(measureBuilder, entry.getKey(), measure.getValue(), measure.getData(), onNewCode);
- wsComponent.addMeasures(measureBuilder);
+ addMeasureIncludingRenamedMetric(requestedMetrics, wsComponent, measureBuilder);
measureBuilder.clear();
}
return wsComponent;
@@ -429,9 +437,9 @@ public class ComponentTreeAction implements MeasuresWsAction {
ComponentTreeQuery componentTreeQuery = toComponentTreeQuery(wsRequest, baseComponent);
List<ComponentDto> components = searchComponents(dbSession, componentTreeQuery);
- List<MetricDto> metrics = searchMetrics(dbSession, new HashSet<>(wsRequest.getMetricKeys()));
- Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric =
- searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery, components, metrics);
+ List<MetricDto> metrics = searchMetrics(dbSession, new HashSet<>(withRemovedMetricAlias(ofNullable(wsRequest.getMetricKeys()).orElse(List.of()))));
+ Table<String, MetricDto, ComponentTreeData.Measure> measuresByComponentUuidAndMetric = searchMeasuresByComponentUuidAndMetric(dbSession, baseComponent, componentTreeQuery,
+ components, metrics);
components = filterComponents(components, measuresByComponentUuidAndMetric, metrics, wsRequest);
components = filterAuthorizedComponents(components);
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java
index 7ddd4bafb9f..36ee695d456 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeData.java
@@ -75,7 +75,6 @@ class ComponentTreeData {
return components;
}
- @CheckForNull
int getComponentCount() {
return componentCount;
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java
index 0e0e4e0d50f..992968529b6 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeRequest.java
@@ -36,7 +36,7 @@ class ComponentTreeRequest {
private String metricSort;
private Integer metricPeriodSort;
private String metricSortFilter;
- private List<String> metricKeys;
+ private List<String> metricKeys = List.of();
private Integer page;
private Integer pageSize;
@@ -139,7 +139,6 @@ class ComponentTreeRequest {
return this;
}
- @CheckForNull
public List<String> getMetricKeys() {
return metricKeys;
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
index 747b4079739..3c5e643e350 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MeasuresWsModule.java
@@ -33,7 +33,7 @@ public class MeasuresWsModule extends Module {
}
- public static String getDeprecatedMetrics() {
+ public static String getDeprecatedMetricsInSonarQube93() {
return String.join(", ", "releasability_effort", "security_rating_effort", "reliability_rating_effort", "security_review_rating_effort",
"maintainability_rating_effort", "last_change_on_maintainability_rating", "last_change_on_releasability_rating", "last_change_on_reliability_rating",
"last_change_on_security_rating", "last_change_on_security_review_rating");
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MetricDtoToWsMetric.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MetricDtoToWsMetric.java
index 1511b81a6e1..9fafb5306a7 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MetricDtoToWsMetric.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/MetricDtoToWsMetric.java
@@ -23,6 +23,9 @@ import org.sonar.db.metric.MetricDto;
import org.sonarqube.ws.Common.Metric;
import static java.util.Optional.ofNullable;
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC;
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC_DESCRIPTION;
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC_SHORT_NAME;
import static org.sonar.server.measure.ws.MeasureValueFormatter.formatNumericalValue;
class MetricDtoToWsMetric {
@@ -48,4 +51,13 @@ class MetricDtoToWsMetric {
return metric.build();
}
+
+ static Metric wontFixToAcceptedWsMetric(MetricDto metricDto) {
+ return metricDtoToWsMetric(metricDto)
+ .toBuilder()
+ .setKey(REMOVED_METRIC)
+ .setDescription(REMOVED_METRIC_DESCRIPTION)
+ .setName(REMOVED_METRIC_SHORT_NAME)
+ .build();
+ }
}
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java
index 740c38ef822..23ac6a65ce2 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchAction.java
@@ -20,6 +20,7 @@
package org.sonar.server.measure.ws;
import com.google.common.collect.ImmutableSet;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
@@ -37,6 +38,7 @@ import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.measure.LiveMeasureDto;
import org.sonar.db.metric.MetricDto;
+import org.sonar.db.metric.RemovedMetricConverter;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Measures.Measure;
import org.sonarqube.ws.Measures.SearchWsResponse;
@@ -50,6 +52,8 @@ import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.SUBVIEW;
import static org.sonar.api.resources.Qualifiers.VIEW;
+import static org.sonar.db.metric.RemovedMetricConverter.REMOVED_METRIC;
+import static org.sonar.db.metric.RemovedMetricConverter.DEPRECATED_METRIC_REPLACEMENT;
import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_METRIC_KEYS;
import static org.sonar.server.component.ws.MeasuresWsParameters.PARAM_PROJECT_KEYS;
import static org.sonar.server.exceptions.BadRequestException.checkRequest;
@@ -77,17 +81,20 @@ public class SearchAction implements MeasuresWsAction {
WebService.NewAction action = context.createAction("search")
.setInternal(true)
.setDescription("Search for project measures ordered by project names.<br>" +
- "At most %d projects can be provided.<br>" +
- "Returns the projects with the 'Browse' permission.",
+ "At most %d projects can be provided.<br>" +
+ "Returns the projects with the 'Browse' permission.",
MAX_NB_PROJECTS)
.setSince("6.2")
.setResponseExample(getClass().getResource("search-example.json"))
.setHandler(this)
.setChangelog(
+ new Change("10.3", "The metric 'wont_fix_issues' is now deprecated in the response. Consume 'accepted_issues' instead."),
+ new Change("10.3", "The use of 'wont_fix_issues' value in 'metricKeys' param is now deprecated. Use 'accepted_issues' instead."),
+ new Change("10.3", "Added new accepted value for the 'metricKeys' param: 'accepted_issues'."),
new Change("10.0", format("The use of the following metrics in 'metricKeys' parameter is not deprecated anymore: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("9.3", format("The use of the following metrics in 'metricKeys' parameter is deprecated: %s",
- MeasuresWsModule.getDeprecatedMetrics())));
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())));
createMetricKeysParameter(action);
@@ -151,10 +158,11 @@ public class SearchAction implements MeasuresWsAction {
}
private List<MetricDto> searchMetrics() {
- List<MetricDto> dbMetrics = dbClient.metricDao().selectByKeys(dbSession, request.getMetricKeys());
+ Collection<String> metricKeysParamValue = RemovedMetricConverter.withRemovedMetricAlias(request.getMetricKeys());
+ List<MetricDto> dbMetrics = dbClient.metricDao().selectByKeys(dbSession, metricKeysParamValue);
List<String> metricKeys = dbMetrics.stream().map(MetricDto::getKey).toList();
- checkRequest(request.getMetricKeys().size() == dbMetrics.size(), "The following metrics are not found: %s",
- String.join(", ", difference(request.getMetricKeys(), metricKeys)));
+ checkRequest(metricKeysParamValue.size() == dbMetrics.size(), "The following metrics are not found: %s",
+ String.join(", ", difference(metricKeysParamValue, metricKeys)));
return dbMetrics;
}
@@ -190,17 +198,32 @@ public class SearchAction implements MeasuresWsAction {
Function<Measure, String> byComponentName = wsMeasure -> componentNamesByKey.get(wsMeasure.getComponent());
Measure.Builder measureBuilder = Measure.newBuilder();
- return measures.stream()
- .map(dbMeasure -> {
- updateMeasureBuilder(measureBuilder, dbMeasureToDbMetric.apply(dbMeasure), dbMeasure);
- measureBuilder.setComponent(componentsByUuid.get(dbMeasure.getComponentUuid()).getKey());
- Measure measure = measureBuilder.build();
- measureBuilder.clear();
- return measure;
- })
+ List<Measure> allMeasures = new ArrayList<>();
+ for (LiveMeasureDto measure : measures) {
+ updateMeasureBuilder(measureBuilder, dbMeasureToDbMetric.apply(measure), measure);
+ measureBuilder.setComponent(componentsByUuid.get(measure.getComponentUuid()).getKey());
+ Measure measureMsg = measureBuilder.build();
+ addMeasureIncludingRenamedMetric(measureMsg, allMeasures, measureBuilder);
+
+ measureBuilder.clear();
+ }
+ return allMeasures.stream()
.sorted(comparing(byMetricKey).thenComparing(byComponentName))
.toList();
}
+
+ private void addMeasureIncludingRenamedMetric(Measure measureMsg, List<Measure> allMeasures, Measure.Builder measureBuilder) {
+ if (measureBuilder.getMetric().equals(DEPRECATED_METRIC_REPLACEMENT)) {
+ if (request.getMetricKeys().contains(DEPRECATED_METRIC_REPLACEMENT)) {
+ allMeasures.add(measureMsg);
+ }
+ if (request.getMetricKeys().contains(REMOVED_METRIC)) {
+ allMeasures.add(measureBuilder.setMetric(REMOVED_METRIC).build());
+ }
+ } else {
+ allMeasures.add(measureMsg);
+ }
+ }
}
private static class SearchRequest {
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java
index c3adcaf99b8..197430a0d96 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java
@@ -21,6 +21,7 @@ package org.sonar.server.measure.ws;
import com.google.common.collect.Sets;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
@@ -46,6 +47,7 @@ import org.sonar.db.component.SnapshotQuery.SORT_ORDER;
import org.sonar.db.measure.MeasureDto;
import org.sonar.db.measure.PastMeasureQuery;
import org.sonar.db.metric.MetricDto;
+import org.sonar.db.metric.RemovedMetricConverter;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.user.UserSession;
import org.sonar.server.ws.KeyExamples;
@@ -93,10 +95,13 @@ public class SearchHistoryAction implements MeasuresWsAction {
.setResponseExample(getClass().getResource("search_history-example.json"))
.setSince("6.3")
.setChangelog(
+ new Change("10.3", "The metric 'wont_fix_issues' is now deprecated in the response. Consume 'accepted_issues' instead."),
+ new Change("10.3", "The use of 'wont_fix_issues' value in 'metricKeys' param is now deprecated. Use 'accepted_issues' instead."),
+ new Change("10.3", "Added new accepted value for the 'metricKeys' param: 'accepted_issues'."),
new Change("10.0", format("The use of the following metrics in 'metricKeys' parameter is not deprecated anymore: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("9.3", format("The use of the following metrics in 'metrics' parameter is deprecated: %s",
- MeasuresWsModule.getDeprecatedMetrics())),
+ MeasuresWsModule.getDeprecatedMetricsInSonarQube93())),
new Change("7.6", format("The use of module keys in parameter '%s' is deprecated", PARAM_COMPONENT)))
.setHandler(this);
@@ -165,7 +170,8 @@ public class SearchHistoryAction implements MeasuresWsAction {
SearchHistoryResult result = new SearchHistoryResult(request.page, request.pageSize)
.setComponent(component)
.setAnalyses(searchAnalyses(dbSession, request, component))
- .setMetrics(searchMetrics(dbSession, request));
+ .setMetrics(searchMetrics(dbSession, request))
+ .setRequestedMetrics(request.getMetrics());
return result.setMeasures(searchMeasures(dbSession, request, result));
}
};
@@ -203,9 +209,10 @@ public class SearchHistoryAction implements MeasuresWsAction {
}
private List<MetricDto> searchMetrics(DbSession dbSession, SearchHistoryRequest request) {
- List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, request.getMetrics());
- if (request.getMetrics().size() > metrics.size()) {
- Set<String> requestedMetrics = request.getMetrics().stream().collect(Collectors.toSet());
+ List<String> upToDateRequestedMetrics = RemovedMetricConverter.withRemovedMetricAlias(request.getMetrics());
+ List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, upToDateRequestedMetrics);
+ if (upToDateRequestedMetrics.size() > metrics.size()) {
+ Set<String> requestedMetrics = new HashSet<>(upToDateRequestedMetrics);
Set<String> foundMetrics = metrics.stream().map(MetricDto::getKey).collect(Collectors.toSet());
Set<String> unfoundMetrics = Sets.difference(requestedMetrics, foundMetrics).immutableCopy();
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java
index a5764f6459e..02454a86537 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResponseFactory.java
@@ -35,6 +35,7 @@ import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryMeasure;
import org.sonarqube.ws.Measures.SearchHistoryResponse.HistoryValue;
import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.server.measure.ws.ComponentResponseCommon.addMetricToSearchHistoryResponseIncludingRenamedMetric;
import static org.sonar.server.measure.ws.MeasureValueFormatter.formatMeasureValue;
class SearchHistoryResponseFactory {
@@ -67,23 +68,17 @@ class SearchHistoryResponseFactory {
result.getMeasures().forEach(m -> measuresByMetricByAnalysis.put(metricsByUuid.get(m.getMetricUuid()), analysesByUuid.get(m.getAnalysisUuid()), m));
return response -> {
- result.getMetrics().stream()
- .map(clearMetric())
- .map(addMetric())
- .map(metric -> addValues(measuresByMetricByAnalysis.row(metric)).apply(metric))
- .forEach(metric -> response.addMeasures(measure));
+ for (MetricDto metric : result.getMetrics()) {
+ measure.setMetric(metric.getKey());
+ addValues(measuresByMetricByAnalysis.row(metric)).apply(metric);
+ addMetricToSearchHistoryResponseIncludingRenamedMetric(response, result.getRequestedMetrics(), measure);
+ measure.clear();
+ }
return response;
};
}
- private UnaryOperator<MetricDto> addMetric() {
- return metric -> {
- measure.setMetric(metric.getKey());
- return metric;
- };
- }
-
private UnaryOperator<MetricDto> addValues(Map<SnapshotDto, MeasureDto> measuresByAnalysis) {
return metric -> {
result.getAnalyses().stream()
diff --git a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java
index bc42f1d9477..8d5f99cdde3 100644
--- a/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java
+++ b/server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/SearchHistoryResult.java
@@ -46,6 +46,7 @@ public class SearchHistoryResult {
private List<MeasureDto> measures;
private Common.Paging paging;
private ComponentDto component;
+ private List<String> requestedMetrics;
public SearchHistoryResult(int page, int pageSize) {
this.page = page;
@@ -138,4 +139,13 @@ public class SearchHistoryResult {
Common.Paging getPaging() {
return requireNonNull(paging);
}
+
+ public SearchHistoryResult setRequestedMetrics(List<String> requestedMetrics) {
+ this.requestedMetrics = requestedMetrics;
+ return this;
+ }
+
+ public List<String> getRequestedMetrics() {
+ return requestedMetrics;
+ }
}
diff --git a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/measure/ws/component_tree-example.json b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/measure/ws/component_tree-example.json
index 72d1c1669f8..6eaba1b4eb2 100644
--- a/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/measure/ws/component_tree-example.json
+++ b/server/sonar-webserver-webapi/src/main/resources/org/sonar/server/measure/ws/component_tree-example.json
@@ -16,6 +16,10 @@
}
},
{
+ "metric": "accepted_issues",
+ "value": "10"
+ },
+ {
"metric": "complexity",
"value": "42"
},
@@ -44,6 +48,10 @@
"value": "12"
},
{
+ "metric": "accepted_issues",
+ "value": "10"
+ },
+ {
"metric": "ncloc",
"value": "114"
}
@@ -81,6 +89,10 @@
"value": "35"
},
{
+ "metric": "accepted_issues",
+ "value": "10"
+ },
+ {
"metric": "ncloc",
"value": "217"
}
@@ -118,6 +130,16 @@
"qualitative": true,
"hidden": false,
"bestValue": "0"
+ },
+ {
+ "key": "accepted_issues",
+ "name": "Accepted Issues",
+ "description": "Accepted issues",
+ "domain": "Issues",
+ "type": "INT",
+ "higherValuesAreBetter": false,
+ "qualitative": false,
+ "hidden": false
}
],
"period": {
diff --git a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
index 6b40a6a72f4..38494be3b38 100644
--- a/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
+++ b/server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/live/MeasureUpdateFormulaFactoryImplTest.java
@@ -282,7 +282,7 @@ public class MeasureUpdateFormulaFactoryImplTest {
public void count_resolved() {
withNoIssues()
.assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 0)
- .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 0);
+ .assertThatValueIs(CoreMetrics.ACCEPTED_ISSUES, 0);
with(
newResolvedGroup(Issue.RESOLUTION_FIXED, Issue.STATUS_RESOLVED).setCount(3),
@@ -296,7 +296,7 @@ public class MeasureUpdateFormulaFactoryImplTest {
newGroup(RuleType.VULNERABILITY).setCount(17),
newGroup(RuleType.BUG).setCount(19))
.assertThatValueIs(CoreMetrics.FALSE_POSITIVE_ISSUES, 5)
- .assertThatValueIs(CoreMetrics.WONT_FIX_ISSUES, 7 + 11);
+ .assertThatValueIs(CoreMetrics.ACCEPTED_ISSUES, 7 + 11);
}
@Test