import com.google.common.collect.Ordering;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.sonar.server.project.Visibility;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.Common;
+import org.sonarqube.ws.Components;
import org.sonarqube.ws.Components.Component;
import org.sonarqube.ws.Components.SearchProjectsWsResponse;
import static com.google.common.base.MoreObjects.firstNonNull;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.ImmutableList.of;
import static com.google.common.collect.Sets.newHashSet;
import static java.lang.String.format;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
+import static org.sonar.api.server.ws.WebService.Param.FACETS;
import static org.sonar.api.server.ws.WebService.Param.FIELDS;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.util.Protobuf.setNullable;
public static final int MAX_PAGE_SIZE = 500;
public static final int DEFAULT_PAGE_SIZE = 100;
+ private static final String ALL = "_all";
+ private static final String ORGANIZATIONS = "organizations";
private static final String ANALYSIS_DATE = "analysisDate";
private static final String LEAK_PERIOD_DATE = "leakPeriodDate";
- private static final Set<String> POSSIBLE_FIELDS = newHashSet(ANALYSIS_DATE, LEAK_PERIOD_DATE);
+ private static final Set<String> POSSIBLE_FIELDS = newHashSet(ALL, ORGANIZATIONS, ANALYSIS_DATE, LEAK_PERIOD_DATE);
private final DbClient dbClient;
private final ProjectMeasuresIndex index;
.setRequired(false)
.setInternal(true)
.setSince("6.3");
- action.createParam(Param.FACETS)
+ action.createParam(FACETS)
.setDescription("Comma-separated list of the facets to be computed. No facet is computed by default.")
.setPossibleValues(SUPPORTED_FACETS.stream().sorted().collect(MoreCollectors.toList(SUPPORTED_FACETS.size())));
action
.setAsc(httpRequest.mandatoryParamAsBoolean(Param.ASCENDING))
.setPage(httpRequest.mandatoryParamAsInt(Param.PAGE))
.setPageSize(httpRequest.mandatoryParamAsInt(Param.PAGE_SIZE));
- if (httpRequest.hasParam(Param.FACETS)) {
- request.setFacets(httpRequest.paramAsStrings(Param.FACETS));
+ if (httpRequest.hasParam(FACETS)) {
+ request.setFacets(httpRequest.mandatoryParamAsStrings(FACETS));
}
if (httpRequest.hasParam(FIELDS)) {
- request.setAdditionalFields(httpRequest.paramAsStrings(FIELDS));
+ List<String> paramsAsString = httpRequest.mandatoryParamAsStrings(FIELDS);
+ if (paramsAsString.contains(ALL)) {
+ request.setAdditionalFields(of(ORGANIZATIONS, ANALYSIS_DATE, LEAK_PERIOD_DATE));
+ } else {
+ request.setAdditionalFields(paramsAsString);
+ }
}
return request.build();
}
Function<ComponentDto, Component> dbToWsComponent = new DbToWsComponent(request, organizationsByUuid, searchResults.favoriteProjectUuids, searchResults.analysisByProjectUuid,
userSession.isLoggedIn());
+ Map<String, OrganizationDto> organizationsByUuidForAdditionalInfo = new HashMap<>();
+ if (request.additionalFields.contains(ORGANIZATIONS)) {
+ organizationsByUuidForAdditionalInfo.putAll(organizationsByUuid);
+ }
+
return Stream.of(SearchProjectsWsResponse.newBuilder())
.map(response -> response.setPaging(Common.Paging.newBuilder()
.setPageIndex(request.getPage())
.forEach(response::addComponents);
return response;
})
+ .map(response -> {
+ organizationsByUuidForAdditionalInfo.values().stream().forEach(
+ dto -> response.addOrganizations(
+ Components.Organization.newBuilder()
+ .setKey(dto.getKey())
+ .setName(dto.getName())
+ .build()));
+ return response;
+ })
.map(response -> addFacets(searchResults, response))
.map(SearchProjectsWsResponse.Builder::build)
.findFirst()
public static RequestBuilder builder() {
return new RequestBuilder();
}
+
}
static class RequestBuilder {
import static org.sonar.server.component.index.SuggestionQuery.DEFAULT_LIMIT;
import static org.sonar.server.es.DefaultIndexSettings.MINIMUM_NGRAM_LENGTH;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
-import static org.sonarqube.ws.Components.SuggestionsWsResponse.Organization;
+import static org.sonarqube.ws.Components.Organization;
import static org.sonarqube.ws.Components.SuggestionsWsResponse.newBuilder;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SUGGESTIONS;
"pageSize": 100,
"total": 3
},
+ "organizations": [
+ {
+ "key": "my-org-key-1",
+ "name": "Foo"
+ },
+ {
+ "key": "my-org-key-2",
+ "name": "Bar"
+ }
+ ],
"components": [
{
"organization": "my-org-key-1",
import org.sonar.server.permission.index.AuthorizationTypeSupport;
import org.sonar.server.permission.index.PermissionIndexerTester;
import org.sonar.server.tester.UserSessionRule;
-import org.sonar.server.ws.KeyExamples;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.Common;
import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.DATA;
import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.PERCENT;
import static org.sonar.server.computation.task.projectanalysis.metric.Metric.MetricType.RATING;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_002;
+import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_003;
import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_FILTER;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
assertThat(asc.defaultValue()).isEqualTo("true");
assertThat(asc.possibleValues()).containsOnly("true", "false", "yes", "no");
- Param additionalFields = def.param("f");
- assertThat(additionalFields.defaultValue()).isNull();
- assertThat(additionalFields.possibleValues()).containsOnly("analysisDate", "leakPeriodDate");
+ Param f = def.param("f");
+ assertThat(f.defaultValue()).isNull();
+ assertThat(f.possibleValues()).containsOnly("_all", "organizations", "analysisDate", "leakPeriodDate");
Param facets = def.param("facets");
assertThat(facets.defaultValue()).isNull();
@Test
public void json_example() {
userSession.logIn();
- OrganizationDto organization1Dto = db.organizations().insertForKey("my-org-key-1");
- OrganizationDto organization2Dto = db.organizations().insertForKey("my-org-key-2");
+ OrganizationDto organization2Dto = db.organizations().insert(dto-> dto.setKey("my-org-key-2").setName("Bar"));
+ OrganizationDto organization1Dto = db.organizations().insert(dto-> dto.setKey("my-org-key-1").setName("Foo"));
+
MetricDto coverage = db.measures().insertMetric(c -> c.setKey(COVERAGE).setValueType(PERCENT.name()));
ComponentDto project1 = insertProject(organization1Dto, c -> c
- .setDbKey(KeyExamples.KEY_PROJECT_EXAMPLE_001)
+ .setDbKey(KEY_PROJECT_EXAMPLE_001)
.setName("My Project 1")
.setTagsString("finance, java"),
new Measure(coverage, c -> c.setValue(80d)));
ComponentDto project2 = insertProject(organization1Dto, c -> c
- .setDbKey(KeyExamples.KEY_PROJECT_EXAMPLE_002)
+ .setDbKey(KEY_PROJECT_EXAMPLE_002)
.setName("My Project 2"),
new Measure(coverage, c -> c.setValue(90d)));
ComponentDto project3 = insertProject(organization2Dto, c -> c
- .setDbKey(KeyExamples.KEY_PROJECT_EXAMPLE_003)
+ .setDbKey(KEY_PROJECT_EXAMPLE_003)
.setName("My Project 3")
.setTagsString("sales, offshore, java"),
new Measure(coverage, c -> c.setValue(20d)));
addFavourite(project1);
- String jsonResult = ws.newRequest().setParam(Param.FACETS, COVERAGE).execute().getInput();
- SearchProjectsWsResponse protobufResult = ws.newRequest().setParam(Param.FACETS, COVERAGE).executeProtobuf(SearchProjectsWsResponse.class);
+ String jsonResult = ws.newRequest()
+ .setParam(FACETS, COVERAGE)
+ .setParam(FIELDS, "_all")
+ .execute().getInput();
assertJson(jsonResult).withStrictArrayOrder().ignoreFields("id").isSimilarTo(ws.getDef().responseExampleAsString());
assertJson(ws.getDef().responseExampleAsString()).ignoreFields("id").withStrictArrayOrder().isSimilarTo(jsonResult);
- assertThat(protobufResult.getComponentsList()).extracting(Component::getId).containsExactly(project1.uuid(), project2.uuid(), project3.uuid());
+
+ SearchProjectsWsResponse protobufResult = ws.newRequest()
+ .setParam(FACETS, COVERAGE)
+ .executeProtobuf(SearchProjectsWsResponse.class);
+
+ assertThat(protobufResult.getComponentsList()).extracting(Component::getId)
+ .containsExactly(project1.uuid(), project2.uuid(), project3.uuid());
}
@Test
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.TestResponse;
import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.Components.Organization;
import org.sonarqube.ws.Components.SuggestionsWsResponse;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Category;
-import org.sonarqube.ws.Components.SuggestionsWsResponse.Organization;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Project;
import org.sonarqube.ws.Components.SuggestionsWsResponse.Suggestion;
+import org.sonarqube.ws.MediaTypes;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
optional bool isFavorite = 7;
}
- message Organization {
- optional string key = 1;
- optional string name = 2;
- }
-
message Project {
optional string key = 1;
optional string name = 2;
// WS api/components/search_projects
message SearchProjectsWsResponse {
optional sonarqube.ws.commons.Paging paging = 1;
- repeated Component components = 2;
- optional sonarqube.ws.commons.Facets facets = 3;
+ repeated Organization organizations = 2;
+ repeated Component components = 3;
+ optional sonarqube.ws.commons.Facets facets = 4;
}
// WS api/components/provisioned
}
}
+message Organization {
+ optional string key = 1;
+ optional string name = 2;
+}
+
+
+