]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9616 Support branch in api/measures/search_history
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 3 Aug 2017 16:17:24 +0000 (18:17 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 08:55:10 +0000 (10:55 +0200)
server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchHistoryAction.java
server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchHistoryActionTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresService.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/MeasuresWsParameters.java
sonar-ws/src/main/java/org/sonarqube/ws/client/measure/SearchHistoryRequest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/measure/MeasuresServiceTest.java
sonar-ws/src/test/java/org/sonarqube/ws/client/measure/SearchHistoryRequestTest.java

index 3f5995a005d6d14c61981dbad7d0915e72544e96..47f9b31938ebd3129302fb1f11560a94b6c1c155 100644 (file)
@@ -52,8 +52,10 @@ import static org.sonar.api.utils.DateUtils.parseEndingDateOrDateTime;
 import static org.sonar.api.utils.DateUtils.parseStartingDateOrDateTime;
 import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.db.component.SnapshotDto.STATUS_PROCESSED;
+import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
 import static org.sonar.server.ws.WsUtils.writeProtobuf;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.ACTION_SEARCH_HISTORY;
+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_FROM;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRICS;
@@ -75,6 +77,7 @@ public class SearchHistoryAction implements MeasuresWsAction {
   private static SearchHistoryRequest toWsRequest(Request request) {
     return SearchHistoryRequest.builder()
       .setComponent(request.mandatoryParam(PARAM_COMPONENT))
+      .setBranch(request.param(PARAM_BRANCH))
       .setMetrics(request.mandatoryParamAsStrings(PARAM_METRICS))
       .setFrom(request.param(PARAM_FROM))
       .setTo(request.param(PARAM_TO))
@@ -99,6 +102,12 @@ public class SearchHistoryAction implements MeasuresWsAction {
       .setRequired(true)
       .setExampleValue(KeyExamples.KEY_PROJECT_EXAMPLE_001);
 
+    action.createParam(PARAM_BRANCH)
+      .setDescription("Branch key")
+      .setSince("6.6")
+      .setInternal(true)
+      .setExampleValue(KEY_BRANCH_EXAMPLE_001);
+
     action.createParam(PARAM_METRICS)
       .setDescription("Comma-separated list of metric keys")
       .setRequired(true)
@@ -141,7 +150,7 @@ public class SearchHistoryAction implements MeasuresWsAction {
   }
 
   private ComponentDto searchComponent(SearchHistoryRequest request, DbSession dbSession) {
-    ComponentDto component = componentFinder.getByKey(dbSession, request.getComponent());
+    ComponentDto component = loadComponent(dbSession, request);
     userSession.checkComponentPermission(UserRole.USER, component);
     return component;
   }
@@ -181,4 +190,13 @@ public class SearchHistoryAction implements MeasuresWsAction {
     return metrics;
   }
 
+  private ComponentDto loadComponent(DbSession dbSession, SearchHistoryRequest request) {
+    String componentKey = request.getComponent();
+    String branch = request.getBranch();
+    if (branch != null) {
+      return componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
+    }
+    return componentFinder.getByKey(dbSession, componentKey);
+  }
+
 }
index 25a0782cf2c97c9044670a3960fa28aaadd2b47d..4570c450be87470651cde631b8332a0b0f1a2a84 100644 (file)
@@ -37,6 +37,7 @@ import org.sonar.db.DbSession;
 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.exceptions.ForbiddenException;
@@ -51,6 +52,7 @@ import org.sonarqube.ws.WsMeasures.SearchHistoryResponse.HistoryValue;
 import org.sonarqube.ws.client.measure.SearchHistoryRequest;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static java.lang.Double.parseDouble;
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
@@ -64,6 +66,7 @@ import static org.sonar.db.component.SnapshotTesting.newAnalysis;
 import static org.sonar.db.measure.MeasureTesting.newMeasureDto;
 import static org.sonar.db.metric.MetricTesting.newMetricDto;
 import static org.sonar.test.JsonAssert.assertJson;
+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_FROM;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_METRICS;
@@ -272,6 +275,29 @@ public class SearchHistoryActionTest {
     assertThat(result.getMeasures(0).getHistory(0).hasValue()).isFalse();
   }
 
+  @Test
+  public void branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
+    ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+    ComponentDto file = db.components().insertComponent(newFileDto(branch));
+    SnapshotDto analysis = db.components().insertSnapshot(branch);
+    MeasureDto measure = db.measures().insertMeasure(file, analysis, nclocMetric, m -> m.setValue(2d));
+
+    SearchHistoryResponse result = ws.newRequest()
+      .setParam(PARAM_COMPONENT, file.getKey())
+      .setParam(PARAM_BRANCH, "my_branch")
+      .setParam(PARAM_METRICS, "ncloc")
+      .executeProtobuf(SearchHistoryResponse.class);
+
+    assertThat(result.getMeasuresList()).extracting(HistoryMeasure::getMetric).hasSize(1);
+    HistoryMeasure historyMeasure = result.getMeasures(0);
+    assertThat(historyMeasure.getMetric()).isEqualTo(nclocMetric.getKey());
+    assertThat(historyMeasure.getHistoryList())
+      .extracting(m -> parseDouble(m.getValue()))
+      .containsExactlyInAnyOrder(measure.getValue());
+  }
+
   @Test
   public void fail_if_unknown_metric() {
     wsRequest.setMetrics(newArrayList(complexityMetric.getKey(), nclocMetric.getKey(), "METRIC_42", "42_METRIC"));
@@ -315,6 +341,23 @@ public class SearchHistoryActionTest {
       .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_METRICS, "ncloc")
+      .execute();
+  }
+
   @Test
   public void definition() {
     WebService.Action definition = ws.getDef();
@@ -324,6 +367,12 @@ public class SearchHistoryActionTest {
     assertThat(definition.isPost()).isFalse();
     assertThat(definition.isInternal()).isFalse();
     assertThat(definition.since()).isEqualTo("6.3");
+    assertThat(definition.params()).hasSize(7);
+
+    Param branch = definition.param("branch");
+    assertThat(branch.since()).isEqualTo("6.6");
+    assertThat(branch.isInternal()).isTrue();
+    assertThat(branch.isRequired()).isFalse();
   }
 
   @Test
index 72bf576330772971e5b4198817b0952e9ebca2ee..470dfa7fa291a0b2bbec3bc258f4f8910edacb8e 100644 (file)
@@ -35,6 +35,7 @@ import static org.sonarqube.ws.client.measure.MeasuresWsParameters.CONTROLLER_ME
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_ID;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_KEY;
+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_COMPONENT_ID;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_COMPONENT_KEY;
@@ -91,6 +92,7 @@ public class MeasuresService extends BaseService {
   public SearchHistoryResponse searchHistory(SearchHistoryRequest request) {
     GetRequest getRequest = new GetRequest(path(ACTION_SEARCH_HISTORY))
       .setParam(PARAM_COMPONENT, request.getComponent())
+      .setParam(PARAM_BRANCH, request.getBranch())
       .setParam(PARAM_METRICS, inlineMultipleParamValue(request.getMetrics()))
       .setParam(PARAM_FROM, request.getFrom())
       .setParam(PARAM_TO, request.getTo())
index 4a440f313fc4126f2dddc420c9faf1cab3e615c8..48599358cc4761c94f4fcfaf40df60c6bce1efcf 100644 (file)
@@ -34,6 +34,7 @@ public class MeasuresWsParameters {
   public static final String PARAM_BASE_COMPONENT_ID = "baseComponentId";
   public static final String PARAM_BASE_COMPONENT_KEY = "baseComponentKey";
   public static final String PARAM_COMPONENT = "component";
+  public static final String PARAM_BRANCH = "branch";
   public static final String PARAM_STRATEGY = "strategy";
   public static final String PARAM_QUALIFIERS = "qualifiers";
   public static final String PARAM_METRICS = "metrics";
index 3bcc5acf209185ddaefab12326aa6d0bf982cfc0..b99b9b77b431fbaf040295afbe88d31127ecd6cc 100644 (file)
@@ -21,6 +21,7 @@ package org.sonarqube.ws.client.measure;
 
 import java.util.List;
 import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 
 import static java.lang.String.format;
 
@@ -29,6 +30,7 @@ public class SearchHistoryRequest {
   public static final int DEFAULT_PAGE_SIZE = 100;
 
   private final String component;
+  private final String branch;
   private final List<String> metrics;
   private final String from;
   private final String to;
@@ -37,6 +39,7 @@ public class SearchHistoryRequest {
 
   public SearchHistoryRequest(Builder builder) {
     this.component = builder.component;
+    this.branch = builder.branch;
     this.metrics = builder.metrics;
     this.from = builder.from;
     this.to = builder.to;
@@ -48,6 +51,11 @@ public class SearchHistoryRequest {
     return component;
   }
 
+  @CheckForNull
+  public String getBranch() {
+    return branch;
+  }
+
   public List<String> getMetrics() {
     return metrics;
   }
@@ -76,6 +84,7 @@ public class SearchHistoryRequest {
 
   public static class Builder {
     private String component;
+    private String branch;
     private List<String> metrics;
     private String from;
     private String to;
@@ -91,17 +100,22 @@ public class SearchHistoryRequest {
       return this;
     }
 
+    public Builder setBranch(@Nullable String branch) {
+      this.branch = branch;
+      return this;
+    }
+
     public Builder setMetrics(List<String> metrics) {
       this.metrics = metrics;
       return this;
     }
 
-    public Builder setFrom(String from) {
+    public Builder setFrom(@Nullable String from) {
       this.from = from;
       return this;
     }
 
-    public Builder setTo(String to) {
+    public Builder setTo(@Nullable String to) {
       this.to = to;
       return this;
     }
index f4ecaf060386cd911ebc45466be99794d5a2c6b4..c0b0d0c1967fcfd7f0c1aacac8bfac0bc7dfcbff 100644 (file)
@@ -36,6 +36,7 @@ import static org.mockito.Mockito.mock;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_ADDITIONAL_FIELDS;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_ID;
 import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BASE_COMPONENT_KEY;
+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;
@@ -121,6 +122,7 @@ public class MeasuresServiceTest {
   public void search_history() {
     SearchHistoryRequest request = SearchHistoryRequest.builder()
       .setComponent(VALUE_COMPONENT)
+      .setBranch("my_branch")
       .setMetrics(VALUE_METRICS)
       .setFrom(VALUE_FROM)
       .setTo(VALUE_TO)
@@ -134,6 +136,7 @@ public class MeasuresServiceTest {
     assertThat(serviceTester.getGetParser()).isSameAs(WsMeasures.SearchHistoryResponse.parser());
     serviceTester.assertThat(getRequest)
       .hasParam(PARAM_COMPONENT, VALUE_COMPONENT)
+      .hasParam(PARAM_BRANCH, "my_branch")
       .hasParam(PARAM_METRICS, "ncloc,complexity")
       .hasParam(PARAM_FROM, VALUE_FROM)
       .hasParam(PARAM_TO, VALUE_TO)
index b58a2671fcc0606f3b1435fb0e17048413b148ae..85a9dab34e1e44390867f43f121426000a549a30 100644 (file)
@@ -39,6 +39,7 @@ public class SearchHistoryRequestTest {
   public void full_example() {
     SearchHistoryRequest result = underTest
       .setComponent("C1")
+      .setBranch("my_branch")
       .setMetrics(singletonList("new_lines"))
       .setFrom("2017-01-15")
       .setTo("2017-01-20")
@@ -47,9 +48,9 @@ public class SearchHistoryRequestTest {
       .build();
 
     assertThat(result)
-      .extracting(SearchHistoryRequest::getComponent, SearchHistoryRequest::getMetrics, SearchHistoryRequest::getFrom, SearchHistoryRequest::getTo,
+      .extracting(SearchHistoryRequest::getComponent, SearchHistoryRequest::getBranch, SearchHistoryRequest::getMetrics, SearchHistoryRequest::getFrom, SearchHistoryRequest::getTo,
         SearchHistoryRequest::getPage, SearchHistoryRequest::getPageSize)
-      .containsExactly("C1", singletonList("new_lines"), "2017-01-15", "2017-01-20", 23, 42);
+      .containsExactly("C1", "my_branch", singletonList("new_lines"), "2017-01-15", "2017-01-20", 23, 42);
   }
 
   @Test