import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.Paging;
import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonarqube.ws.client.project.SearchWsRequest;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
import static org.sonar.api.resources.Qualifiers.APP;
import static org.sonar.api.resources.Qualifiers.PROJECT;
import static org.sonar.api.resources.Qualifiers.VIEW;
.setResponseExample(getClass().getResource("search-example.json"))
.setHandler(this);
- action.setChangelog(new Change("6.4", "The 'uuid' field is deprecated in the response"));
+ action.setChangelog(
+ new Change("6.4", "The 'uuid' field is deprecated in the response"),
+ new Change("6.7.2", format("Parameters %s and %s accept maximum %d values", PARAM_PROJECTS, PARAM_PROJECT_IDS, DatabaseUtils.PARTITION_SIZE_FOR_ORACLE)));
action.createParam(Param.TEXT_QUERY)
.setDescription("Limit search to: <ul>" +
.createParam(PARAM_PROJECTS)
.setDescription("Comma-separated list of project keys")
.setSince("6.6")
+ // Limitation of ComponentDao#selectByQuery(), max 1000 values are accepted.
+ // Restricting size of HTTP parameter allows to not fail with SQL error
+ .setMaxValuesAllowed(DatabaseUtils.PARTITION_SIZE_FOR_ORACLE)
.setExampleValue(String.join(",", KEY_PROJECT_EXAMPLE_001, KEY_PROJECT_EXAMPLE_002));
action
.setSince("6.6")
// parameter added to match api/projects/bulk_delete parameters
.setDeprecatedSince("6.6")
+ // Limitation of ComponentDao#selectByQuery(), max 1000 values are accepted.
+ // Restricting size of HTTP parameter allows to not fail with SQL error
+ .setMaxValuesAllowed(DatabaseUtils.PARTITION_SIZE_FOR_ORACLE)
.setExampleValue(String.join(",", UUID_EXAMPLE_01, UUID_EXAMPLE_02));
}
package org.sonar.server.project.ws;
import com.google.common.base.Joiner;
-import java.io.IOException;
-import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.assertj.core.api.Assertions;
new SearchAction(db.getDbClient(), userSession, new ProjectsWsSupport(db.getDbClient(), defaultOrganizationProvider, mock(BillingValidationsProxy.class))));
@Test
- public void search_by_key_query_with_partial_match_case_insensitive() throws IOException {
+ public void search_by_key_query_with_partial_match_case_insensitive() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
db.components().insertComponents(
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey("project-_%-key"),
}
@Test
- public void search_projects_when_no_qualifier_set() throws IOException {
+ public void search_projects_when_no_qualifier_set() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
db.components().insertComponents(
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey(PROJECT_KEY_1),
}
@Test
- public void search_projects() throws IOException {
+ public void search_projects() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
ComponentDto project = ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey(PROJECT_KEY_1);
ComponentDto module = newModuleDto(project);
}
@Test
- public void search_views() throws IOException {
+ public void search_views() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
db.components().insertComponents(
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey(PROJECT_KEY_1),
}
@Test
- public void search_projects_and_views() throws IOException {
+ public void search_projects_and_views() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
db.components().insertComponents(
ComponentTesting.newPrivateProjectDto(db.getDefaultOrganization()).setDbKey(PROJECT_KEY_1),
}
@Test
- public void search_on_default_organization_when_no_organization_set() throws IOException {
+ public void search_on_default_organization_when_no_organization_set() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
OrganizationDto otherOrganization = db.organizations().insert();
db.components().insertComponents(
}
@Test
- public void search_for_projects_on_given_organization() throws IOException {
+ public void search_for_projects_on_given_organization() {
OrganizationDto organization1 = db.organizations().insert();
OrganizationDto organization2 = db.organizations().insert();
userSession.addPermission(ADMINISTER, organization1);
}
@Test
- public void result_is_paginated() throws IOException {
+ public void result_is_paginated() {
userSession.addPermission(ADMINISTER, db.getDefaultOrganization());
List<ComponentDto> componentDtoList = new ArrayList<>();
for (int i = 1; i <= 9; i++) {
}
@Test
- public void fail_when_not_system_admin() throws Exception {
+ public void request_throws_IAE_if_more_than_1000_projects() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("'projects' can contains only 1000 values, got 1001");
+
+ call(SearchWsRequest.builder()
+ .setProjects(Collections.nCopies(1_001, "foo"))
+ .build());
+ }
+
+ @Test
+ public void request_throws_IAE_if_more_than_1000_project_ids() {
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("'projectIds' can contains only 1000 values, got 1001");
+
+ call(SearchWsRequest.builder()
+ .setProjectIds(Collections.nCopies(1_001, "foo"))
+ .build());
+ }
+
+ @Test
+ public void fail_when_not_system_admin() {
userSession.addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
expectedException.expect(ForbiddenException.class);
}
@Test
- public void fail_on_unknown_organization() throws Exception {
+ public void fail_on_unknown_organization() {
expectedException.expect(NotFoundException.class);
call(SearchWsRequest.builder().setOrganization("unknown").build());
}
@Test
- public void fail_on_invalid_qualifier() throws Exception {
+ public void fail_on_invalid_qualifier() {
userSession.addPermission(ADMINISTER_QUALITY_PROFILES, db.getDefaultOrganization());
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Value of parameter 'qualifiers' (BRC) must be one of: [TRK, VW, APP]");
}
@Test
- public void json_example() throws URISyntaxException, IOException {
+ public void json_example() {
OrganizationDto organization = db.organizations().insertForKey("my-org-1");
userSession.addPermission(ADMINISTER, organization);
ComponentDto publicProject = newPrivateProjectDto(organization, "project-uuid-1").setName("Project Name 1").setDbKey("project-key-1").setPrivate(false);