Bladeren bron

SONAR-8287 Add filter parameter in api/components/search_projects

tags/6.2-RC1
Julien Lancelot 7 jaren geleden
bovenliggende
commit
3ecbbba4ff
17 gewijzigde bestanden met toevoegingen van 500 en 28 verwijderingen
  1. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ws/BulkUpdateKeyAction.java
  2. 3
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java
  3. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWsModule.java
  4. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
  5. 21
    7
      server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java
  6. 119
    0
      server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsQueryBuilder.java
  7. 52
    0
      server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderValidator.java
  8. 2
    1
      server/sonar-server/src/main/java/org/sonar/server/component/ws/UpdateKeyAction.java
  9. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsModuleTest.java
  10. 1
    1
      server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java
  11. 107
    0
      server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderTest.java
  12. 75
    0
      server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderValidatorTest.java
  13. 28
    12
      sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java
  14. 9
    2
      sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java
  15. 12
    0
      sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java
  16. 55
    0
      sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java
  17. 9
    0
      sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ws/BulkUpdateKeyAction.java Bestand weergeven

@@ -42,6 +42,7 @@ import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
import static org.sonar.db.component.ComponentKeyUpdaterDao.checkIsProjectOrModule;
import static org.sonar.server.ws.WsUtils.checkRequest;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_DRY_RUN;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
@@ -65,7 +66,7 @@ public class BulkUpdateKeyAction implements ComponentsWsAction {

@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("bulk_update_key")
WebService.NewAction action = context.createAction(ACTION_BULK_UPDATE_KEY)
.setDescription("Bulk update a project or module key and all its sub-components keys. " +
"The bulk update allows to replace a part of the current key by another string on the current project and all its sub-modules.<br>" +
"It's possible to simulate the bulk update by setting the parameter '%s' at true. No key is updated with a dry run.<br>" +

+ 3
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWs.java Bestand weergeven

@@ -23,6 +23,8 @@ import com.google.common.io.Resources;
import org.sonar.api.server.ws.RailsHandler;
import org.sonar.api.server.ws.WebService;

import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLER_COMPONENTS;

public class ComponentsWs implements WebService {

private final AppAction appAction;
@@ -37,7 +39,7 @@ public class ComponentsWs implements WebService {

@Override
public void define(Context context) {
NewController controller = context.createController("api/components")
NewController controller = context.createController(CONTROLLER_COMPONENTS)
.setSince("4.2")
.setDescription("Get information about a component (file, directory, project, ...) and its ancestors or descendants. " +
"Update a project or module key.");

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ws/ComponentsWsModule.java Bestand weergeven

@@ -36,6 +36,7 @@ public class ComponentsWsModule extends Module {
SearchViewComponentsAction.class,
UpdateKeyAction.class,
BulkUpdateKeyAction.class,
SearchProjectsAction.class);
SearchProjectsAction.class,
SearchProjectsQueryBuilderValidator.class);
}
}

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java Bestand weergeven

@@ -45,6 +45,7 @@ import static com.google.common.collect.FluentIterable.from;
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;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;

@@ -65,7 +66,7 @@ public class SearchAction implements ComponentsWsAction {

@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("search")
WebService.NewAction action = context.createAction(ACTION_SEARCH)
.setSince("5.2")
.setInternal(true)
.setDescription("Search for components")

+ 21
- 7
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsAction.java Bestand weergeven

@@ -38,28 +38,38 @@ import org.sonarqube.ws.WsComponents.Component;
import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.client.component.SearchProjectsRequest;

import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.build;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.SearchProjectsRequest.DEFAULT_PAGE_SIZE;
import static org.sonarqube.ws.client.component.SearchProjectsRequest.MAX_PAGE_SIZE;

public class SearchProjectsAction implements ComponentsWsAction {
private final DbClient dbClient;
private final ProjectMeasuresIndex index;
private final SearchProjectsQueryBuilderValidator searchProjectsQueryBuilderValidator;

public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index) {
public SearchProjectsAction(DbClient dbClient, ProjectMeasuresIndex index, SearchProjectsQueryBuilderValidator searchProjectsQueryBuilderValidator) {
this.dbClient = dbClient;
this.index = index;
this.searchProjectsQueryBuilderValidator = searchProjectsQueryBuilderValidator;
}

@Override
public void define(WebService.NewController context) {
context.createAction("search_projects")
WebService.NewAction action = context.createAction("search_projects")
.setSince("6.2")
.setDescription("Search for projects")
.addPagingParams(DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
.setInternal(true)
.setResponseExample(getClass().getResource("search_projects-example.json"))
.setHandler(this);

action
.createParam(PARAM_FILTER)
.setDescription("TODO")
.setSince("6.2");
}

@Override
@@ -78,6 +88,11 @@ public class SearchProjectsAction implements ComponentsWsAction {
}

private SearchResults searchProjects(DbSession dbSession, SearchProjectsRequest request) {
String filter = request.getFilter();
if (filter != null) {
SearchProjectsCriteriaQuery query = build(filter);
searchProjectsQueryBuilderValidator.validate(dbSession, query);
}
SearchIdResult<String> searchResult = index.search(new SearchOptions().setPage(request.getPage(), request.getPageSize()));

Ordering<ComponentDto> ordering = Ordering.explicit(searchResult.getIds()).onResultOf(ComponentDto::uuid);
@@ -87,11 +102,10 @@ public class SearchProjectsAction implements ComponentsWsAction {
}

private static SearchProjectsRequest toRequest(Request httpRequest) {
SearchProjectsRequest.Builder request = SearchProjectsRequest.builder();

request.setPage(httpRequest.mandatoryParamAsInt(Param.PAGE));
request.setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));

SearchProjectsRequest.Builder request = SearchProjectsRequest.builder()
.setFilter(httpRequest.param(PARAM_FILTER))
.setPage(httpRequest.mandatoryParamAsInt(Param.PAGE))
.setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));
return request.build();
}


+ 119
- 0
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsQueryBuilder.java Bestand weergeven

@@ -0,0 +1,119 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.component.ws;

import com.google.common.base.Splitter;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static java.util.Arrays.stream;
import static java.util.Locale.ENGLISH;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.Operator;

public class SearchProjectsQueryBuilder {

private static final Splitter CRITERIA_SPLITTER = Splitter.on("and");
private static final Pattern CRITERIA_PATTERN = Pattern.compile("(\\w+)\\s*([<>][=]?)\\s*(\\w+)");

private SearchProjectsQueryBuilder() {
// Only static methods
}

public static SearchProjectsCriteriaQuery build(String filter) {
SearchProjectsCriteriaQuery query = new SearchProjectsCriteriaQuery();
CRITERIA_SPLITTER.split(filter.toLowerCase(ENGLISH))
.forEach(criteria -> processCriteria(criteria, query));
return query;
}

private static void processCriteria(String criteria, SearchProjectsCriteriaQuery query) {
Matcher matcher = CRITERIA_PATTERN.matcher(criteria);
checkArgument(matcher.find() && matcher.groupCount() == 3, "Invalid criteria '%s'", criteria);
String metric = matcher.group(1);
Operator operator = Operator.create(matcher.group(2));
Double value = Double.parseDouble(matcher.group(3));
query.addMetricCriteria(new MetricCriteria(metric, operator, value));
}

public static class SearchProjectsCriteriaQuery {
public enum Operator {
LT("<="), GT(">"), EQ("=");

String value;

Operator(String value) {
this.value = value;
}

String getValue() {
return value;
}

public static Operator create(String value) {
return stream(Operator.values())
.filter(operator -> operator.getValue().equals(value))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException(format("Unknown operator '%s'", value)));
}
}

private List<MetricCriteria> metricCriterias = new ArrayList<>();

SearchProjectsCriteriaQuery addMetricCriteria(MetricCriteria metricCriteria) {
metricCriterias.add(metricCriteria);
return this;
}

public List<MetricCriteria> getMetricCriterias() {
return metricCriterias;
}

public static class MetricCriteria {
private String metricKey;
private Operator operator;
private double value;

private MetricCriteria(String metricKey, Operator operator, double value) {
this.metricKey = metricKey;
this.operator = operator;
this.value = value;
}

public String getMetricKey() {
return metricKey;
}

public Operator getOperator() {
return operator;
}

public double getValue() {
return value;
}
}
}

}

+ 52
- 0
server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderValidator.java Bestand weergeven

@@ -0,0 +1,52 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.component.ws;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.sonar.core.util.stream.Collectors;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.metric.MetricDto;
import org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;

import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;

public class SearchProjectsQueryBuilderValidator {

private final DbClient dbClient;

public SearchProjectsQueryBuilderValidator(DbClient dbClient) {
this.dbClient = dbClient;
}

public void validate(DbSession dbSession, SearchProjectsCriteriaQuery query) {
List<String> metricKeys = new ArrayList<>(query.getMetricCriterias().stream().map(MetricCriteria::getMetricKey).collect(Collectors.toSet()));
List<MetricDto> metricDtos = dbClient.metricDao().selectByKeys(dbSession, metricKeys);
if (metricDtos.size() == metricKeys.size()) {
return;
}
List<String> metricDtoKeys = metricDtos.stream().map(MetricDto::getKey).collect(Collectors.toList());
Set<String> unknownKeys = metricKeys.stream().filter(metricKey -> !metricDtoKeys.contains(metricKey)).collect(Collectors.toSet());
throw new IllegalArgumentException(String.format("Unknown metric(s) %s", unknownKeys));
}
}

+ 2
- 1
server/sonar-server/src/main/java/org/sonar/server/component/ws/UpdateKeyAction.java Bestand weergeven

@@ -32,6 +32,7 @@ import org.sonar.server.component.ComponentService;
import org.sonarqube.ws.client.component.UpdateWsRequest;

import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_NEW_KEY;
@@ -49,7 +50,7 @@ public class UpdateKeyAction implements ComponentsWsAction {

@Override
public void define(WebService.NewController context) {
WebService.NewAction action = context.createAction("update_key")
WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY)
.setDescription("Update a project or module key and all its sub-components keys.<br>" +
"Either '%s' or '%s' must be provided, not both.<br> " +
"Requires one of the following permissions: " +

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsModuleTest.java Bestand weergeven

@@ -29,6 +29,6 @@ public class ComponentsWsModuleTest {
public void verify_count_of_added_components() {
ComponentContainer container = new ComponentContainer();
new ComponentsWsModule().configure(container);
assertThat(container.size()).isEqualTo(11 + 2);
assertThat(container.size()).isEqualTo(12 + 2);
}
}

+ 1
- 1
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsActionTest.java Bestand weergeven

@@ -69,7 +69,7 @@ public class SearchProjectsActionTest {
ComponentDbTester componentDb = new ComponentDbTester(db);
DbClient dbClient = db.getDbClient();

WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, new ProjectMeasuresIndex(es.client())));
WsActionTester ws = new WsActionTester(new SearchProjectsAction(dbClient, new ProjectMeasuresIndex(es.client()), new SearchProjectsQueryBuilderValidator(dbClient)));

SearchProjectsRequest.Builder request = SearchProjectsRequest.builder();


+ 107
- 0
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderTest.java Bestand weergeven

@@ -0,0 +1,107 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.component.ws;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.build;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.MetricCriteria;
import static org.sonar.server.component.ws.SearchProjectsQueryBuilder.SearchProjectsCriteriaQuery.Operator;

public class SearchProjectsQueryBuilderTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Test
public void create_query() throws Exception {
SearchProjectsCriteriaQuery query = build("ncloc > 10 and coverage <= 80");

assertThat(query.getMetricCriterias())
.extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
.containsOnly(
tuple("ncloc", Operator.GT, 10d),
tuple("coverage", Operator.LT, 80d));
}

@Test
public void convert_upper_case_to_lower_case() throws Exception {
assertThat(build("NCLOC > 10 AND coVERage <= 80").getMetricCriterias())
.extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
.containsOnly(
tuple("ncloc", Operator.GT, 10d),
tuple("coverage", Operator.LT, 80d));
}

@Test
public void ignore_white_spaces() throws Exception {
assertThat(build(" ncloc > 10 ").getMetricCriterias())
.extracting(MetricCriteria::getMetricKey, MetricCriteria::getOperator, MetricCriteria::getValue)
.containsOnly(tuple("ncloc", Operator.GT, 10d));
}

@Test
public void fail_on_unknown_operator() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unknown operator '>='");
build("ncloc >= 10");
}

@Test
public void fail_on_invalid_criteria() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Invalid criteria 'ncloc ? 10'");
build("ncloc ? 10");
}

@Test
public void fail_when_no_operator() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Invalid criteria 'ncloc 10'");
build("ncloc 10");
}

@Test
public void fail_when_no_key() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Invalid criteria '>= 10'");
build(">= 10");
}

@Test
public void fail_when_no_value() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Invalid criteria 'ncloc >='");
build("ncloc >=");
}

@Test
public void fail_when_no_criteria_provided() throws Exception {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Invalid criteria ''");
build("");
}
}

+ 75
- 0
server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchProjectsQueryBuilderValidatorTest.java Bestand weergeven

@@ -0,0 +1,75 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.component.ws;

import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.metric.MetricTesting;

@Ignore
public class SearchProjectsQueryBuilderValidatorTest {

@Rule
public ExpectedException expectedException = ExpectedException.none();

@Rule
public DbTester db = DbTester.create(System2.INSTANCE);

DbClient dbClient = db.getDbClient();
DbSession dbSession = db.getSession();

SearchProjectsQueryBuilderValidator validator = new SearchProjectsQueryBuilderValidator(dbClient);

@Test
public void does_not_fail_when_metric_criteria_contains_an_existing_metric() throws Exception {
insertMetric("ncloc");

validator.validate(dbSession, SearchProjectsQueryBuilder.build("ncloc > 10"));
}

@Test
public void fail_when_metric_does_not_exists() throws Exception {
insertMetric("ncloc");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unknown metric(s) [unknown]");
validator.validate(dbSession, SearchProjectsQueryBuilder.build("unknown > 10"));
}

@Test
public void return_all_unknown_metrics() throws Exception {
insertMetric("ncloc");

expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Unknown metric(s) [coverage, debt]");
validator.validate(dbSession, SearchProjectsQueryBuilder.build("debt > 10 AND ncloc <= 20 AND coverage > 30"));
}

private void insertMetric(String metricKey) {
dbClient.metricDao().insert(dbSession, MetricTesting.newMetricDto().setKey(metricKey));
}
}

+ 28
- 12
sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsService.java Bestand weergeven

@@ -21,6 +21,7 @@ package org.sonarqube.ws.client.component;

import com.google.common.base.Joiner;
import org.sonarqube.ws.WsComponents.BulkUpdateKeyWsResponse;
import org.sonarqube.ws.WsComponents.SearchProjectsWsResponse;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.WsComponents.ShowWsResponse;
import org.sonarqube.ws.WsComponents.TreeWsResponse;
@@ -29,10 +30,17 @@ import org.sonarqube.ws.client.GetRequest;
import org.sonarqube.ws.client.PostRequest;
import org.sonarqube.ws.client.WsConnector;

import static org.sonar.api.server.ws.WebService.Param;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_BULK_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH_PROJECTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SHOW;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_TREE;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_UPDATE_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.CONTROLLER_COMPONENTS;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BASE_COMPONENT_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BASE_COMPONENT_KEY;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FROM;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ID;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_KEY;
@@ -44,15 +52,15 @@ import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_TO;
public class ComponentsService extends BaseService {

public ComponentsService(WsConnector wsConnector) {
super(wsConnector, "api/components");
super(wsConnector, CONTROLLER_COMPONENTS);
}

public SearchWsResponse search(SearchWsRequest request) {
GetRequest get = new GetRequest(path("search"))
.setParam("qualifiers", Joiner.on(",").join(request.getQualifiers()))
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
.setParam("q", request.getQuery());
GetRequest get = new GetRequest(path(ACTION_SEARCH))
.setParam(PARAM_QUALIFIERS, Joiner.on(",").join(request.getQualifiers()))
.setParam(Param.PAGE, request.getPage())
.setParam(Param.PAGE_SIZE, request.getPageSize())
.setParam(Param.TEXT_QUERY, request.getQuery());
return call(get, SearchWsResponse.parser());
}

@@ -62,10 +70,10 @@ public class ComponentsService extends BaseService {
.setParam(PARAM_BASE_COMPONENT_KEY, request.getBaseComponentKey())
.setParam(PARAM_QUALIFIERS, inlineMultipleParamValue(request.getQualifiers()))
.setParam(PARAM_STRATEGY, request.getStrategy())
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
.setParam("q", request.getQuery())
.setParam("s", request.getSort());
.setParam(Param.PAGE, request.getPage())
.setParam(Param.PAGE_SIZE, request.getPageSize())
.setParam(Param.TEXT_QUERY, request.getQuery())
.setParam(Param.SORT, request.getSort());
return call(get, TreeWsResponse.parser());
}

@@ -77,7 +85,7 @@ public class ComponentsService extends BaseService {
}

public void updateKey(UpdateWsRequest request) {
PostRequest post = new PostRequest(path("update_key"))
PostRequest post = new PostRequest(path(ACTION_UPDATE_KEY))
.setParam(PARAM_ID, request.getId())
.setParam(PARAM_KEY, request.getKey())
.setParam(PARAM_NEW_KEY, request.getNewKey());
@@ -86,7 +94,7 @@ public class ComponentsService extends BaseService {
}

public BulkUpdateKeyWsResponse bulkUpdateKey(BulkUpdateWsRequest request) {
PostRequest post = new PostRequest(path("bulk_update_key"))
PostRequest post = new PostRequest(path(ACTION_BULK_UPDATE_KEY))
.setParam(PARAM_ID, request.getId())
.setParam(PARAM_KEY, request.getKey())
.setParam(PARAM_FROM, request.getFrom())
@@ -94,4 +102,12 @@ public class ComponentsService extends BaseService {

return call(post, BulkUpdateKeyWsResponse.parser());
}

public SearchProjectsWsResponse searchProjects(SearchProjectsRequest request) {
GetRequest get = new GetRequest(path(ACTION_SEARCH_PROJECTS))
.setParam(PARAM_FILTER, request.getFilter())
.setParam(Param.PAGE, request.getPage())
.setParam(Param.PAGE_SIZE, request.getPageSize());
return call(get, SearchProjectsWsResponse.parser());
}
}

+ 9
- 2
sonar-ws/src/main/java/org/sonarqube/ws/client/component/ComponentsWsParameters.java Bestand weergeven

@@ -20,13 +20,19 @@
package org.sonarqube.ws.client.component;

public class ComponentsWsParameters {

public static final String CONTROLLER_COMPONENTS = "api/components";

// actions
public static final String ACTION_SEARCH = "search";
public static final String ACTION_UPDATE_KEY = "update_key";
public static final String ACTION_TREE = "tree";

public static final String ACTION_SHOW = "show";
public static final String ACTION_BULK_UPDATE_KEY = "bulk_update_key";
public static final String ACTION_SEARCH_PROJECTS = "search_projects";

// parameters
public static final String PARAM_QUALIFIERS = "qualifiers";

public static final String PARAM_LANGUAGE = "language";
public static final String PARAM_BASE_COMPONENT_ID = "baseComponentId";
public static final String PARAM_BASE_COMPONENT_KEY = "baseComponentKey";
@@ -37,6 +43,7 @@ public class ComponentsWsParameters {
public static final String PARAM_FROM = "from";
public static final String PARAM_TO = "to";
public static final String PARAM_DRY_RUN = "dryRun";
public static final String PARAM_FILTER = "filter";

private ComponentsWsParameters() {
// static utility class

+ 12
- 0
sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchProjectsRequest.java Bestand weergeven

@@ -28,10 +28,16 @@ public class SearchProjectsRequest {

private final int page;
private final int pageSize;
private final String filter;

private SearchProjectsRequest(Builder builder) {
this.page = builder.page;
this.pageSize = builder.pageSize;
this.filter = builder.filter;
}

public String getFilter() {
return filter;
}

public int getPageSize() {
@@ -49,11 +55,17 @@ public class SearchProjectsRequest {
public static class Builder {
private Integer page;
private Integer pageSize;
private String filter;

private Builder() {
// enforce static factory method
}

public Builder setFilter(String filter) {
this.filter = filter;
return this;
}

public Builder setPage(int page) {
this.page = page;
return this;

+ 55
- 0
sonar-ws/src/test/java/org/sonarqube/ws/client/component/ComponentsServiceTest.java Bestand weergeven

@@ -0,0 +1,55 @@
/*
* SonarQube
* Copyright (C) 2009-2016 SonarSource SA
* mailto:contact 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.sonarqube.ws.client.component;

import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.server.ws.WebService.Param;
import org.sonarqube.ws.client.ServiceTester;
import org.sonarqube.ws.client.WsConnector;

import static org.mockito.Mockito.mock;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;

public class ComponentsServiceTest {

@Rule
public ServiceTester<ComponentsService> serviceTester = new ServiceTester<>(new ComponentsService(mock(WsConnector.class)));

private ComponentsService underTest = serviceTester.getInstanceUnderTest();

@Test
public void search_projects() {
underTest.searchProjects(SearchProjectsRequest.builder()
.setFilter("ncloc > 10")
.setPage(3)
.setPageSize(10)
.build());

serviceTester.assertThat(serviceTester.getGetRequest())
.hasPath("search_projects")
.hasParam(PARAM_FILTER, "ncloc > 10")
.hasParam(Param.PAGE, 3)
.hasParam(Param.PAGE_SIZE, 10)
.andNoOtherParam();
}

}

+ 9
- 0
sonar-ws/src/test/java/org/sonarqube/ws/client/component/SearchProjectsRequestTest.java Bestand weergeven

@@ -33,6 +33,15 @@ public class SearchProjectsRequestTest {

SearchProjectsRequest.Builder underTest = SearchProjectsRequest.builder();

@Test
public void filter_parameter() throws Exception {
SearchProjectsRequest result = underTest
.setFilter("ncloc > 10")
.build();

assertThat(result.getFilter()).isEqualTo("ncloc > 10");
}

@Test
public void default_page_values() {
SearchProjectsRequest result = underTest.build();

Laden…
Annuleren
Opslaan