diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2017-08-04 11:52:07 +0200 |
---|---|---|
committer | Janos Gyerik <janos.gyerik@sonarsource.com> | 2017-09-12 10:55:10 +0200 |
commit | 4f500d461015eb6edc471677961c72e8e68b87bf (patch) | |
tree | 753c67161e57eacad4cbca554d268ef46581dc11 /server | |
parent | a307775b34efbbc4641b01c55aa1aa9465f7f004 (diff) | |
download | sonarqube-4f500d461015eb6edc471677961c72e8e68b87bf.tar.gz sonarqube-4f500d461015eb6edc471677961c72e8e68b87bf.zip |
SONAR-9616 Support branch in api/measures/component
Diffstat (limited to 'server')
3 files changed, 98 insertions, 14 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java index 5bcfd73345f..a23e33014e6 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentAction.java @@ -55,12 +55,13 @@ import org.sonarqube.ws.WsMeasures; import org.sonarqube.ws.WsMeasures.ComponentWsResponse; import org.sonarqube.ws.client.measure.ComponentWsRequest; +import static com.google.common.base.Preconditions.checkArgument; import static java.lang.String.format; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Collections.singletonMap; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; -import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_KEY; +import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_COMPONENT; import static org.sonar.server.component.ComponentFinder.ParamNames.DEVELOPER_ID_AND_KEY; import static org.sonar.server.measure.ws.ComponentDtoToWsComponent.componentDtoToWsComponent; import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createAdditionalFieldsParameter; @@ -68,6 +69,7 @@ import static org.sonar.server.measure.ws.MeasuresWsParametersBuilder.createDeve 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.SnapshotDtoToWsPeriods.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.WsUtils.checkRequest; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -77,6 +79,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ADDITIONAL_PE import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_COMPONENT_ID; import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_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; @@ -118,6 +121,12 @@ public class ComponentAction implements MeasuresWsAction { .setExampleValue(UUID_EXAMPLE_01) .setDeprecatedSince("6.6"); + action.createParam(PARAM_BRANCH) + .setDescription("Branch key") + .setExampleValue(KEY_BRANCH_EXAMPLE_001) + .setInternal(true) + .setSince("6.6"); + createMetricKeysParameter(action); createAdditionalFieldsParameter(action); createDeveloperParameters(action); @@ -131,7 +140,7 @@ public class ComponentAction implements MeasuresWsAction { private ComponentWsResponse doHandle(ComponentWsRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { - ComponentDto component = componentFinder.getByUuidOrKey(dbSession, request.getComponentId(), request.getComponent(), COMPONENT_ID_AND_KEY); + ComponentDto component = loadComponent(dbSession, request); Long developerId = searchDeveloperId(dbSession, request); Optional<ComponentDto> refComponent = getReferenceComponent(dbSession, component); checkPermissions(component); @@ -144,6 +153,16 @@ public class ComponentAction implements MeasuresWsAction { } } + private ComponentDto loadComponent(DbSession dbSession, ComponentWsRequest request) { + String componentKey = request.getComponent(); + String componentId = request.getComponentId(); + String branch = request.getBranch(); + checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", DEPRECATED_PARAM_COMPONENT_ID, PARAM_BRANCH); + return branch == null + ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, COMPONENT_ID_AND_COMPONENT) + : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch); + } + @CheckForNull private Long searchDeveloperId(DbSession dbSession, ComponentWsRequest request) { if (request.getDeveloperId() == null && request.getDeveloperKey() == null) { @@ -251,6 +270,7 @@ public class ComponentAction implements MeasuresWsAction { ComponentWsRequest componentWsRequest = new ComponentWsRequest() .setComponentId(request.param(DEPRECATED_PARAM_COMPONENT_ID)) .setComponent(request.param(PARAM_COMPONENT)) + .setBranch(request.param(PARAM_BRANCH)) .setAdditionalFields(request.paramAsStrings(PARAM_ADDITIONAL_FIELDS)) .setMetricKeys(request.mandatoryParamAsStrings(PARAM_METRIC_KEYS)) .setDeveloperId(request.param(PARAM_DEVELOPER_ID)) diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java index df45ff19672..3129de298a3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java @@ -20,6 +20,7 @@ package org.sonar.server.measure.ws; import java.util.Map; +import org.sonar.core.util.Protobuf; import org.sonar.db.component.ComponentDto; import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; @@ -54,19 +55,13 @@ class ComponentDtoToWsComponent { static Component.Builder componentDtoToWsComponent(ComponentDto component) { Component.Builder wsComponent = Component.newBuilder() .setId(component.uuid()) - .setKey(component.getDbKey()) + .setKey(component.getKey()) .setName(component.name()) .setQualifier(component.qualifier()); - if (component.path() != null) { - wsComponent.setPath(component.path()); - } - if (component.description() != null) { - wsComponent.setDescription(component.description()); - } - if (component.language() != null) { - wsComponent.setLanguage(component.language()); - } - + Protobuf.setNullable(component.getBranch(), wsComponent::setBranch); + Protobuf.setNullable(component.path(), wsComponent::setPath); + Protobuf.setNullable(component.description(), wsComponent::setDescription); + Protobuf.setNullable(component.language(), wsComponent::setLanguage); return wsComponent; } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java index 0e7ba8748a3..4a4012d8442 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java @@ -29,6 +29,7 @@ import org.sonar.api.web.UserRole; import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; +import org.sonar.db.measure.MeasureDto; import org.sonar.db.metric.MetricDto; import org.sonar.server.component.TestComponentFinder; import org.sonar.server.computation.task.projectanalysis.measure.Measure; @@ -37,20 +38,26 @@ import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.WsActionTester; +import org.sonarqube.ws.WsMeasures; +import org.sonarqube.ws.WsMeasures.Component; import org.sonarqube.ws.Common; import org.sonarqube.ws.Common; import org.sonarqube.ws.WsMeasures; import org.sonarqube.ws.WsMeasures.Component; import org.sonarqube.ws.WsMeasures.ComponentWsResponse; +import static java.lang.Double.parseDouble; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.sonar.api.utils.DateUtils.parseDateTime; import static org.sonar.api.web.UserRole.USER; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; import static org.sonar.db.component.SnapshotTesting.newAnalysis; import static org.sonar.test.JsonAssert.assertJson; +import static org.sonarqube.ws.client.measure.MeasuresWsParameters.DEPRECATED_PARAM_COMPONENT_ID; 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_METRIC_KEYS; @@ -72,10 +79,15 @@ public class ComponentActionTest { assertThat(def.since()).isEqualTo("5.4"); assertThat(def.params()).extracting(Param::key) - .containsExactlyInAnyOrder("componentId", "component", "metricKeys", "additionalFields", "developerId", "developerKey"); + .containsExactlyInAnyOrder("componentId", "component", "branch", "metricKeys", "additionalFields", "developerId", "developerKey"); assertThat(def.param("developerId").deprecatedSince()).isEqualTo("6.4"); assertThat(def.param("developerKey").deprecatedSince()).isEqualTo("6.4"); assertThat(def.param("componentId").deprecatedSince()).isEqualTo("6.6"); + + WebService.Param branch = def.param("branch"); + assertThat(branch.since()).isEqualTo("6.6"); + assertThat(branch.isInternal()).isTrue(); + assertThat(branch.isRequired()).isFalse(); } @Test @@ -109,6 +121,29 @@ public class ComponentActionTest { } @Test + public void branch() { + ComponentDto project = db.components().insertPrivateProject(); + logAsUser(project); + 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).setVariation(2.0d)); + + ComponentWsResponse response = ws.newRequest() + .setParam(PARAM_COMPONENT, file.getKey()) + .setParam(PARAM_BRANCH, file.getBranch()) + .setParam(PARAM_METRIC_KEYS, complexity.getKey()) + .executeProtobuf(ComponentWsResponse.class); + + assertThat(response.getComponent()).extracting(Component::getKey, Component::getBranch) + .containsExactlyInAnyOrder(file.getKey(), file.getBranch()); + assertThat(response.getComponent().getMeasuresList()) + .extracting(WsMeasures.Measure::getMetric, m -> parseDouble(m.getValue())) + .containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue())); + } + + @Test public void reference_uuid_in_the_response() { userSession.logIn().setRoot(); ComponentDto project = db.components().insertPrivateProject(); @@ -272,6 +307,40 @@ public class ComponentActionTest { } @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(); + } + + @Test + public void fail_when_componentId_and_branch_params_are_used_together() { + 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(IllegalArgumentException.class); + expectedException.expectMessage("'componentId' and 'branch' parameters cannot be used at the same time"); + + ws.newRequest() + .setParam(DEPRECATED_PARAM_COMPONENT_ID, file.uuid()) + .setParam(PARAM_BRANCH, "my_branch") + .setParam(PARAM_METRIC_KEYS, "ncloc") + .execute(); + } + + @Test public void json_example() { ComponentDto project = db.components().insertPrivateProject(); logAsUser(project); |