aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-08-04 12:02:40 +0200
committerJanos Gyerik <janos.gyerik@sonarsource.com>2017-09-12 10:55:10 +0200
commit5c9f6c0ddd90b00de33f37bd1ce40b10935eaa27 (patch)
treec757f599841f7342e0223e0a4ec2addd00be0e3d
parent4f500d461015eb6edc471677961c72e8e68b87bf (diff)
downloadsonarqube-5c9f6c0ddd90b00de33f37bd1ce40b10935eaa27.tar.gz
sonarqube-5c9f6c0ddd90b00de33f37bd1ce40b10935eaa27.zip
SONAR-9616 Support branch in api/measures/component_tree
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java9
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java68
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java11
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java1
-rw-r--r--sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java2
6 files changed, 91 insertions, 14 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
index b3e3c5b5ae6..8c894c4dae9 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
@@ -54,6 +54,7 @@ import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAddi
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createDeveloperParameters;
import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createMetricKeysParameter;
import static org.sonar.server.measure.ws.MetricDtoToWsMetric.metricDtoToWsMetric;
+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.WsParameterBuilder.createQualifiersParameter;
import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
@@ -65,6 +66,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ADDITIONAL_PE
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_ID;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_KEY;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_COMPONENT;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOPER_ID;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_DEVELOPER_KEY;
@@ -165,6 +167,12 @@ public class ComponentTreeAction implements MeasuresWsAction {
.setExampleValue(KEY_PROJECT_EXAMPLE_001)
.setDeprecatedKey(DEPRECATED_PARAM_BASE_COMPONENT_KEY, "6.6");
+ action.createParam(PARAM_BRANCH)
+ .setDescription("Branch key")
+ .setExampleValue(KEY_BRANCH_EXAMPLE_001)
+ .setInternal(true)
+ .setSince("6.6");
+
action.createParam(PARAM_METRIC_SORT)
.setDescription(
format("Metric key to sort by. The '%s' parameter must contain the '%s' or '%s' value. It must be part of the '%s' parameter", Param.SORT, METRIC_SORT, METRIC_PERIOD_SORT,
@@ -283,6 +291,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
ComponentTreeWsRequest componentTreeWsRequest = new ComponentTreeWsRequest()
.setBaseComponentId(request.param(DEPRECATED_PARAM_BASE_COMPONENT_ID))
.setComponent(request.param(PARAM_COMPONENT))
+ .setBranch(request.param(PARAM_BRANCH))
.setMetricKeys(metricKeys)
.setStrategy(request.mandatoryParam(PARAM_STRATEGY))
.setQualifiers(request.paramAsStrings(PARAM_QUALIFIERS))
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java
index b454bebd4fa..e599bb77803 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentTreeDataLoader.java
@@ -74,6 +74,8 @@ import static org.sonar.server.measure.ws.ComponentTreeAction.LEAVES_STRATEGY;
import static org.sonar.server.measure.ws.ComponentTreeAction.STRATEGIES;
import static org.sonar.server.measure.ws.ComponentTreeAction.WITH_MEASURES_ONLY_METRIC_SORT_FILTER;
import static org.sonar.server.measure.ws.SnapshotDtoToWsPeriods.snapshotToWsPeriods;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_ID;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
public class ComponentTreeDataLoader {
private static final Set<String> QUALIFIERS_ELIGIBLE_FOR_BEST_VALUE = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
@@ -93,7 +95,7 @@ public class ComponentTreeDataLoader {
ComponentTreeData load(ComponentTreeWsRequest wsRequest) {
try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto baseComponent = componentFinder.getByUuidOrKey(dbSession, wsRequest.getBaseComponentId(), wsRequest.getComponent(), BASE_COMPONENT_ID_AND_KEY);
+ ComponentDto baseComponent = loadComponent(dbSession, wsRequest);
checkPermissions(baseComponent);
Optional<SnapshotDto> baseSnapshot = dbClient.snapshotDao().selectLastAnalysisByRootComponentUuid(dbSession, baseComponent.projectUuid());
if (!baseSnapshot.isPresent()) {
@@ -128,6 +130,16 @@ public class ComponentTreeDataLoader {
}
}
+ private ComponentDto loadComponent(DbSession dbSession, ComponentTreeWsRequest request) {
+ String componentKey = request.getComponent();
+ String componentId = request.getBaseComponentId();
+ String branch = request.getBranch();
+ checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_BASE_COMPONENT_ID, PARAM_BRANCH);
+ return branch == null
+ ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, BASE_COMPONENT_ID_AND_KEY)
+ : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
+ }
+
@CheckForNull
private Long searchDeveloperId(DbSession dbSession, ComponentTreeWsRequest wsRequest) {
if (wsRequest.getDeveloperId() == null && wsRequest.getDeveloperKey() == null) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
index b9f233b5693..2c3e8e2cfd5 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java
@@ -22,7 +22,6 @@ package org.sonar.server.measure.ws;
import com.google.common.base.Joiner;
import java.util.List;
import java.util.stream.IntStream;
-import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -39,6 +38,7 @@ import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.component.SnapshotDto;
+import org.sonar.db.measure.MeasureDto;
import org.sonar.db.metric.MetricDto;
import org.sonar.db.metric.MetricTesting;
import org.sonar.server.component.ComponentFinder;
@@ -52,6 +52,7 @@ import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsMeasures;
import org.sonarqube.ws.WsMeasures.ComponentTreeWsResponse;
+import static java.lang.Double.parseDouble;
import static java.lang.String.format;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
@@ -60,6 +61,11 @@ import static org.sonar.api.measures.Metric.ValueType.DISTRIB;
import static org.sonar.api.measures.Metric.ValueType.FLOAT;
import static org.sonar.api.measures.Metric.ValueType.INT;
import static org.sonar.api.measures.Metric.ValueType.RATING;
+import static org.sonar.api.resources.Qualifiers.DIRECTORY;
+import static org.sonar.api.resources.Qualifiers.FILE;
+import static org.sonar.api.resources.Qualifiers.MODULE;
+import static org.sonar.api.resources.Qualifiers.PROJECT;
+import static org.sonar.api.resources.Qualifiers.UNIT_TEST_FILE;
import static org.sonar.api.server.ws.WebService.Param.SORT;
import static org.sonar.api.utils.DateUtils.parseDateTime;
import static org.sonar.api.web.UserRole.USER;
@@ -78,6 +84,7 @@ import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ADDITIONAL_PERIODS;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_BASE_COMPONENT_KEY;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_COMPONENT;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_KEYS;
import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRIC_PERIOD_SORT;
@@ -88,14 +95,17 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_STRATEG
public class ComponentTreeActionTest {
@Rule
- public UserSessionRule userSession = UserSessionRule.standalone();
+ public UserSessionRule userSession = UserSessionRule.standalone().logIn().setRoot();
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
private I18nRule i18n = new I18nRule();
- private ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT);
+ private ResourceTypesRule resourceTypes = new ResourceTypesRule()
+ .setRootQualifiers(PROJECT)
+ .setChildrenQualifiers(MODULE, FILE, DIRECTORY)
+ .setLeavesQualifiers(FILE, UNIT_TEST_FILE);
private ComponentDbTester componentDb = new ComponentDbTester(db);
private DbClient dbClient = db.getDbClient();
private DbSession dbSession = db.getSession();
@@ -105,13 +115,6 @@ public class ComponentTreeActionTest {
new ComponentTreeDataLoader(dbClient, new ComponentFinder(dbClient, resourceTypes), userSession, resourceTypes),
i18n, resourceTypes));
- @Before
- public void setUp() {
- userSession.logIn().setRoot();
- resourceTypes.setChildrenQualifiers(Qualifiers.MODULE, Qualifiers.FILE, Qualifiers.DIRECTORY);
- resourceTypes.setLeavesQualifiers(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
- }
-
@Test
public void json_example() {
ComponentDto project = db.components().insertPrivateProject(p -> p.setDbKey("MY_PROJECT")
@@ -124,19 +127,19 @@ public class ComponentTreeActionTest {
.setDbKey("com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl/ElementImpl.java")
.setName("ElementImpl.java")
.setLanguage("java")
- .setQualifier(Qualifiers.FILE)
+ .setQualifier(FILE)
.setPath("src/main/java/com/sonarsource/markdown/impl/ElementImpl.java"));
ComponentDto file2 = componentDb.insertComponent(newFileDto(project, null)
.setUuid("AVIwDXE_bJbJqrw6wFwJ")
.setDbKey("com.sonarsource:java-markdown:src/test/java/com/sonarsource/markdown/impl/ElementImplTest.java")
.setName("ElementImplTest.java")
.setLanguage("java")
- .setQualifier(Qualifiers.UNIT_TEST_FILE)
+ .setQualifier(UNIT_TEST_FILE)
.setPath("src/test/java/com/sonarsource/markdown/impl/ElementImplTest.java"));
ComponentDto dir = componentDb.insertComponent(newDirectory(project, "src/main/java/com/sonarsource/markdown/impl")
.setUuid("AVIwDXE-bJbJqrw6wFv8")
.setDbKey("com.sonarsource:java-markdown:src/main/java/com/sonarsource/markdown/impl")
- .setQualifier(Qualifiers.DIRECTORY));
+ .setQualifier(DIRECTORY));
MetricDto complexity = insertComplexityMetric();
dbClient.measureDao().insert(dbSession,
@@ -488,6 +491,28 @@ public class ComponentTreeActionTest {
}
@Test
+ public void branch() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+ SnapshotDto analysis = db.components().insertSnapshot(branch);
+ ComponentDto file = db.components().insertComponent(newFileDto(branch));
+ MetricDto complexity = insertComplexityMetric();
+ MeasureDto measure = db.measures().insertMeasure(file, analysis, complexity, m -> m.setValue(12.0d));
+
+ ComponentTreeWsResponse response = ws.newRequest()
+ .setParam(PARAM_COMPONENT, file.getKey())
+ .setParam(PARAM_BRANCH, file.getBranch())
+ .setParam(PARAM_METRIC_KEYS, complexity.getKey())
+ .executeProtobuf(WsMeasures.ComponentTreeWsResponse.class);
+
+ assertThat(response.getBaseComponent()).extracting(WsMeasures.Component::getKey, WsMeasures.Component::getBranch)
+ .containsExactlyInAnyOrder(file.getKey(), file.getBranch());
+ assertThat(response.getBaseComponent().getMeasuresList())
+ .extracting(WsMeasures.Measure::getMetric, m -> parseDouble(m.getValue()))
+ .containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue()));
+ }
+
+ @Test
public void return_deprecated_id_in_the_response() {
ComponentDto project = db.components().insertPrivateProject();
SnapshotDto analysis = db.components().insertSnapshot(project);
@@ -796,6 +821,23 @@ public class ComponentTreeActionTest {
.execute();
}
+ @Test
+ public void fail_if_branch_does_not_exist() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ userSession.addProjectPermission(UserRole.USER, project);
+ db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", file.getKey(), "another_branch"));
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT, file.getKey())
+ .setParam(PARAM_BRANCH, "another_branch")
+ .setParam(PARAM_METRIC_KEYS, "ncloc")
+ .execute();
+ }
+
private static MetricDto newMetricDto() {
return MetricTesting.newMetricDto()
.setWorstValue(null)
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
index d6c550eae92..0a89515828a 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/ComponentTreeWsRequest.java
@@ -28,6 +28,7 @@ public class ComponentTreeWsRequest {
private String baseComponentId;
private String baseComponentKey;
private String component;
+ private String branch;
private String strategy;
private List<String> qualifiers;
private List<String> additionalFields;
@@ -90,6 +91,16 @@ public class ComponentTreeWsRequest {
}
@CheckForNull
+ public String getBranch() {
+ return branch;
+ }
+
+ public ComponentTreeWsRequest setBranch(@Nullable String branch) {
+ this.branch = branch;
+ return this;
+ }
+
+ @CheckForNull
public String getStrategy() {
return strategy;
}
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
index 9c94c285667..db8b7e4bde2 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
@@ -61,6 +61,7 @@ public class MeasuresService extends BaseService {
.setParam(DEPRECATED_PARAM_BASE_COMPONENT_ID, request.getBaseComponentId())
.setParam(DEPRECATED_PARAM_BASE_COMPONENT_KEY, request.getBaseComponentKey())
.setParam(PARAM_COMPONENT, request.getComponent())
+ .setParam(PARAM_BRANCH, request.getBranch())
.setParam(PARAM_STRATEGY, request.getStrategy())
.setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))
.setParam(PARAM_METRIC_KEYS, inlineMultipleParamValue(request.getMetricKeys()))
diff --git a/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java b/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
index b42cc3e45ad..c8d4e66d339 100644
--- a/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
+++ b/sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
@@ -114,6 +114,7 @@ public class MeasuresServiceTest {
.setBaseComponentId(VALUE_BASE_COMPONENT_ID)
.setBaseComponentKey(VALUE_BASE_COMPONENT_KEY)
.setComponent(VALUE_BASE_COMPONENT_KEY)
+ .setBranch("my_branch")
.setMetricKeys(VALUE_METRIC_KEYS)
.setStrategy(VALUE_STRATEGY)
.setQualifiers(VALUE_QUALIFIERS)
@@ -136,6 +137,7 @@ public class MeasuresServiceTest {
.hasParam(DEPRECATED_PARAM_BASE_COMPONENT_ID, VALUE_BASE_COMPONENT_ID)
.hasParam(DEPRECATED_PARAM_BASE_COMPONENT_KEY, VALUE_BASE_COMPONENT_KEY)
.hasParam(PARAM_COMPONENT, VALUE_BASE_COMPONENT_KEY)
+ .hasParam(PARAM_BRANCH, "my_branch")
.hasParam(PARAM_METRIC_KEYS, "ncloc,complexity")
.hasParam(PARAM_STRATEGY, VALUE_STRATEGY)
.hasParam(PARAM_QUALIFIERS, "FIL,PRJ")