aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java132
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java3
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java47
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java29
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java4
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml3
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java76
-rw-r--r--sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java10
8 files changed, 207 insertions, 97 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
index 3538aaca55d..25427abe3da 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
@@ -19,12 +19,11 @@
*/
package org.sonar.server.component.ws;
-import com.google.common.base.Function;
import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
-import javax.annotation.Nonnull;
import org.sonar.api.i18n.I18n;
import org.sonar.api.resources.Languages;
import org.sonar.api.resources.ResourceTypes;
@@ -39,12 +38,14 @@ import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentQuery;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.server.organization.DefaultOrganizationProvider;
import org.sonar.server.user.UserSession;
+import org.sonar.server.ws.WsUtils;
import org.sonarqube.ws.WsComponents;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.client.component.SearchWsRequest;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.api.web.UserRole.USER;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.core.util.stream.Collectors.uniqueIndex;
@@ -55,6 +56,7 @@ import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.n
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_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
public class SearchAction implements ComponentsWsAction {
@@ -63,13 +65,16 @@ public class SearchAction implements ComponentsWsAction {
private final I18n i18n;
private final UserSession userSession;
private final Languages languages;
+ private final DefaultOrganizationProvider defaultOrganizationProvider;
- public SearchAction(DbClient dbClient, ResourceTypes resourceTypes, I18n i18n, UserSession userSession, Languages languages) {
+ public SearchAction(DbClient dbClient, ResourceTypes resourceTypes, I18n i18n, UserSession userSession,
+ Languages languages, DefaultOrganizationProvider defaultOrganizationProvider) {
this.dbClient = dbClient;
this.resourceTypes = resourceTypes;
this.i18n = i18n;
this.userSession = userSession;
this.languages = languages;
+ this.defaultOrganizationProvider = defaultOrganizationProvider;
}
@Override
@@ -82,6 +87,13 @@ public class SearchAction implements ComponentsWsAction {
.setResponseExample(getClass().getResource("search-components-example.json"))
.setHandler(this);
action
+ .createParam(PARAM_ORGANIZATION)
+ .setDescription("Organization key")
+ .setRequired(false)
+ .setInternal(true)
+ .setExampleValue("my-org")
+ .setSince("6.3");
+ action
.createParam(PARAM_LANGUAGE)
.setDescription("Language key. If provided, only components for the given language are returned.")
.setExampleValue(getExampleValue(languages))
@@ -96,24 +108,9 @@ public class SearchAction implements ComponentsWsAction {
writeProtobuf(searchWsResponse, wsRequest, wsResponse);
}
- private SearchWsResponse doHandle(SearchWsRequest request) {
- try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentQuery query = buildQuery(request);
- Paging paging = buildPaging(dbSession, request, query);
- List<ComponentDto> components = searchComponents(dbSession, query, paging);
-
- Set<String> organizationUuids = components.stream()
- .map(ComponentDto::getOrganizationUuid)
- .collect(Collectors.toSet());
- Map<String, OrganizationDto> organizationsByUuid = dbClient.organizationDao().selectByUuids(dbSession, organizationUuids)
- .stream()
- .collect(Collectors.uniqueIndex(OrganizationDto::getUuid));
- return buildResponse(components, organizationsByUuid, paging);
- }
- }
-
private static SearchWsRequest toSearchWsRequest(Request request) {
return new SearchWsRequest()
+ .setOrganization(request.param(PARAM_ORGANIZATION))
.setQualifiers(request.mandatoryParamAsStrings(PARAM_QUALIFIERS))
.setLanguage(request.param(PARAM_LANGUAGE))
.setQuery(request.param(Param.TEXT_QUERY))
@@ -121,8 +118,43 @@ public class SearchAction implements ComponentsWsAction {
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE));
}
- private List<ComponentDto> searchComponents(DbSession dbSession, ComponentQuery query, Paging paging) {
- List<ComponentDto> componentDtos = dbClient.componentDao().selectByQuery(dbSession, query, paging.offset(), paging.pageSize());
+ private SearchWsResponse doHandle(SearchWsRequest request) {
+ try (DbSession dbSession = dbClient.openSession(false)) {
+ ComponentQuery query = buildQuery(request);
+ OrganizationDto organization = getOrganization(dbSession, request);
+ Paging paging = buildPaging(dbSession, request, organization, query);
+ List<ComponentDto> components = searchComponents(dbSession, organization, query, paging);
+
+ return buildResponse(components, organization, paging);
+ }
+ }
+
+ private static ComponentQuery buildQuery(SearchWsRequest request) {
+ List<String> qualifiers = request.getQualifiers();
+ return ComponentQuery.builder()
+ .setNameOrKeyQuery(request.getQuery())
+ .setLanguage(request.getLanguage())
+ .setQualifiers(qualifiers.toArray(new String[qualifiers.size()]))
+ .build();
+ }
+
+ private OrganizationDto getOrganization(DbSession dbSession, SearchWsRequest request) {
+ String organizationKey = Optional.ofNullable(request.getOrganization())
+ .orElseGet(defaultOrganizationProvider.get()::getKey);
+ return WsUtils.checkFoundWithOptional(
+ dbClient.organizationDao().selectByKey(dbSession, organizationKey),
+ "No organizationDto with key '%s'", organizationKey);
+ }
+
+ private Paging buildPaging(DbSession dbSession, SearchWsRequest request, OrganizationDto organization, ComponentQuery query) {
+ int total = dbClient.componentDao().countByQuery(dbSession, organization.getUuid(), query);
+ return Paging.forPageIndex(request.getPage())
+ .withPageSize(request.getPageSize())
+ .andTotal(total);
+ }
+
+ private List<ComponentDto> searchComponents(DbSession dbSession, OrganizationDto organization, ComponentQuery query, Paging paging) {
+ List<ComponentDto> componentDtos = dbClient.componentDao().selectByQuery(dbSession, organization.getUuid(), query, paging.offset(), paging.pageSize());
return filterAuthorizedComponents(dbSession, componentDtos);
}
@@ -136,7 +168,7 @@ public class SearchAction implements ComponentsWsAction {
.collect(Collectors.toList());
}
- private static SearchWsResponse buildResponse(List<ComponentDto> components, Map<String, OrganizationDto> organizationsByUuid, Paging paging) {
+ private static SearchWsResponse buildResponse(List<ComponentDto> components, OrganizationDto organization, Paging paging) {
SearchWsResponse.Builder responseBuilder = SearchWsResponse.newBuilder();
responseBuilder.getPagingBuilder()
.setPageIndex(paging.pageIndex())
@@ -145,50 +177,26 @@ public class SearchAction implements ComponentsWsAction {
.build();
components.stream()
- .map(new ComponentDToComponentResponseFunction(organizationsByUuid)::apply)
+ .map(dto -> dtoToComponent(organization, dto))
.forEach(responseBuilder::addComponents);
return responseBuilder.build();
}
- private Paging buildPaging(DbSession dbSession, SearchWsRequest request, ComponentQuery query) {
- int total = dbClient.componentDao().countByQuery(dbSession, query);
- return Paging.forPageIndex(request.getPage())
- .withPageSize(request.getPageSize())
- .andTotal(total);
+ private static WsComponents.Component dtoToComponent(OrganizationDto organization, ComponentDto dto) {
+ checkArgument(
+ organization.getUuid().equals(dto.getOrganizationUuid()),
+ "No Organization found for uuid '%s'",
+ dto.getOrganizationUuid());
+
+ WsComponents.Component.Builder builder = WsComponents.Component.newBuilder()
+ .setOrganization(organization.getKey())
+ .setId(dto.uuid())
+ .setKey(dto.key())
+ .setName(dto.name())
+ .setQualifier(dto.qualifier());
+ setNullable(dto.language(), builder::setLanguage);
+ return builder.build();
}
- private static ComponentQuery buildQuery(SearchWsRequest request) {
- List<String> qualifiers = request.getQualifiers();
- return ComponentQuery.builder()
- .setNameOrKeyQuery(request.getQuery())
- .setLanguage(request.getLanguage())
- .setQualifiers(qualifiers.toArray(new String[qualifiers.size()]))
- .build();
- }
-
- private static class ComponentDToComponentResponseFunction implements Function<ComponentDto, WsComponents.Component> {
- private final Map<String, OrganizationDto> organizationsByUuid;
-
- private ComponentDToComponentResponseFunction(Map<String, OrganizationDto> organizationsByUuid) {
- this.organizationsByUuid = organizationsByUuid;
- }
-
- @Override
- public WsComponents.Component apply(@Nonnull ComponentDto dto) {
- OrganizationDto organization = checkNotNull(
- organizationsByUuid.get(dto.getOrganizationUuid()),
- "No Organization found for uuid '%s'",
- dto.getOrganizationUuid());
-
- WsComponents.Component.Builder builder = WsComponents.Component.newBuilder()
- .setOrganization(organization.getKey())
- .setId(dto.uuid())
- .setKey(dto.key())
- .setName(dto.name())
- .setQualifier(dto.qualifier());
- setNullable(dto.language(), builder::setLanguage);
- return builder.build();
- }
- }
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
index 8e937c36ffe..b93c6051c37 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/ComponentsWsTest.java
@@ -30,6 +30,7 @@ import org.sonar.api.server.ws.WebService;
import org.sonar.db.DbClient;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.component.index.ComponentIndex;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.WsTester;
@@ -52,7 +53,7 @@ public class ComponentsWsTest {
WsTester tester = new WsTester(new ComponentsWs(
new AppAction(mock(DbClient.class), userSessionRule, mock(ComponentFinder.class)),
new SuggestionsAction(mock(DbClient.class), mock(ComponentIndex.class)),
- new SearchAction(mock(DbClient.class), mock(ResourceTypes.class), mock(I18n.class), userSessionRule, languages)));
+ new SearchAction(mock(DbClient.class), mock(ResourceTypes.class), mock(I18n.class), userSessionRule, languages, TestDefaultOrganizationProvider.fromUuid("foo"))));
controller = tester.controller("api/components");
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
index 24ee4f44ea0..064ed90b921 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
@@ -40,6 +40,7 @@ import org.sonar.db.component.ResourceTypesRule;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.i18n.I18nRule;
+import org.sonar.server.organization.TestDefaultOrganizationProvider;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
@@ -68,6 +69,7 @@ import static org.sonar.test.JsonAssert.assertJson;
import static org.sonarqube.ws.MediaTypes.PROTOBUF;
import static org.sonarqube.ws.WsComponents.Component;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
public class SearchActionTest {
@@ -80,6 +82,7 @@ public class SearchActionTest {
private I18nRule i18n = new I18nRule();
+ private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
private ResourceTypesRule resourceTypes = new ResourceTypesRule();
private Languages languages = mock(Languages.class);
private UserDto user;
@@ -90,13 +93,36 @@ public class SearchActionTest {
public void setUp() {
resourceTypes.setAllQualifiers(PROJECT, MODULE, DIRECTORY, FILE);
when(languages.all()).thenReturn(javaLanguage());
- ws = new WsActionTester(new SearchAction(db.getDbClient(), resourceTypes, i18n, userSession, languages));
+ ws = new WsActionTester(new SearchAction(db.getDbClient(), resourceTypes, i18n, userSession, languages, defaultOrganizationProvider));
user = db.users().insertUser("john");
userSession.login(user);
}
@Test
+ public void verify_definition() {
+ WebService.Action action = ws.getDef();
+
+ assertThat(action.description()).isEqualTo("Search for components");
+ assertThat(action.since()).isEqualTo("6.3");
+ assertThat(action.isPost()).isFalse();
+ assertThat(action.isInternal()).isFalse();
+ assertThat(action.responseExampleAsString()).isNotEmpty();
+
+ assertThat(action.params()).hasSize(6);
+
+ WebService.Param qualifiers = action.param("qualifiers");
+ assertThat(qualifiers.isRequired()).isTrue();
+
+ WebService.Param organization = action.param("organization");
+ assertThat(organization.isRequired()).isFalse();
+ assertThat(organization.description()).isEqualTo("Organization key");
+ assertThat(organization.isInternal()).isTrue();
+ assertThat(organization.exampleValue()).isEqualTo("my-org");
+ assertThat(organization.since()).isEqualTo("6.3");
+ }
+
+ @Test
public void search_by_key_query() throws IOException {
insertProjectsAuthorizedForUser(
newProjectDto(db.getDefaultOrganization()).setKey("project-_%-key"),
@@ -129,7 +155,7 @@ public class SearchActionTest {
}
insertProjectsAuthorizedForUser(componentDtoList.toArray(new ComponentDto[] {}));
- SearchWsResponse response = call(new SearchWsRequest().setPage(2).setPageSize(3).setQualifiers(singletonList(PROJECT)));
+ SearchWsResponse response = call(new SearchWsRequest().setOrganization(organizationDto.getKey()).setPage(2).setPageSize(3).setQualifiers(singletonList(PROJECT)));
assertThat(response.getComponentsList()).extracting(Component::getKey).containsExactly("project-key-4", "project-key-5", "project-key-6");
}
@@ -141,7 +167,7 @@ public class SearchActionTest {
newProjectDto(organizationDto).setKey("java-project").setLanguage("java"),
newProjectDto(organizationDto).setKey("cpp-project").setLanguage("cpp"));
- SearchWsResponse response = call(new SearchWsRequest().setLanguage("java").setQualifiers(singletonList(PROJECT)));
+ SearchWsResponse response = call(new SearchWsRequest().setOrganization(organizationDto.getKey()).setLanguage("java").setQualifiers(singletonList(PROJECT)));
assertThat(response.getComponentsList()).extracting(Component::getKey).containsOnly("java-project");
}
@@ -190,24 +216,12 @@ public class SearchActionTest {
String response = ws.newRequest()
.setMediaType(MediaTypes.JSON)
+ .setParam(PARAM_ORGANIZATION, organizationDto.getKey())
.setParam(PARAM_QUALIFIERS, Joiner.on(",").join(PROJECT, MODULE, DIRECTORY, FILE))
.execute().getInput();
assertJson(response).isSimilarTo(ws.getDef().responseExampleAsString());
}
- @Test
- public void test_definition() {
- WebService.Action action = ws.getDef();
-
- assertThat(action).isNotNull();
- assertThat(action.param("qualifiers").isRequired()).isTrue();
- assertThat(action.responseExampleAsString()).isNotEmpty();
- assertThat(action.description()).isNotEmpty();
- assertThat(action.isInternal()).isFalse();
- assertThat(action.isPost()).isFalse();
- assertThat(action.since()).isEqualTo("6.3");
- }
-
private void insertProjectsAuthorizedForUser(ComponentDto... projects) {
db.components().insertComponents(projects);
setBrowsePermissionOnUser(projects);
@@ -222,6 +236,7 @@ public class SearchActionTest {
private SearchWsResponse call(SearchWsRequest wsRequest) {
TestRequest request = ws.newRequest()
.setMediaType(PROTOBUF);
+ setNullable(wsRequest.getOrganization(), p -> request.setParam(PARAM_ORGANIZATION, p));
setNullable(wsRequest.getLanguage(), p -> request.setParam(PARAM_LANGUAGE, p));
setNullable(wsRequest.getQualifiers(), p -> request.setParam(PARAM_QUALIFIERS, Joiner.on(",").join(p)));
setNullable(wsRequest.getQuery(), p -> request.setParam(TEXT_QUERY, p));
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
index 9880e51467f..d475e9ead20 100644
--- a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
@@ -77,17 +77,37 @@ public class ComponentDao implements Dao {
}
public List<ComponentDto> selectByQuery(DbSession session, ComponentQuery query, int offset, int limit) {
- if (query.getComponentIds() != null && query.getComponentIds().isEmpty()) {
+ return selectByQueryImpl(session, null, query, offset, limit);
+ }
+
+ public List<ComponentDto> selectByQuery(DbSession dbSession, String organizationUuid, ComponentQuery query, int offset, int limit) {
+ requireNonNull(organizationUuid, "organizationUuid can't be null");
+ return selectByQueryImpl(dbSession, organizationUuid, query, offset, limit);
+ }
+
+ private static List<ComponentDto> selectByQueryImpl(DbSession session, @Nullable String organizationUuid, ComponentQuery query, int offset, int limit) {
+ Set<Long> componentIds = query.getComponentIds();
+ if (componentIds != null && componentIds.isEmpty()) {
return emptyList();
}
- return mapper(session).selectByQuery(query, new RowBounds(offset, limit));
+ return mapper(session).selectByQuery(organizationUuid, query, new RowBounds(offset, limit));
}
public int countByQuery(DbSession session, ComponentQuery query) {
- if (query.getComponentIds() != null && query.getComponentIds().isEmpty()) {
+ return countByQueryImpl(session, null, query);
+ }
+
+ public int countByQuery(DbSession session, String organizationUuid, ComponentQuery query) {
+ requireNonNull(organizationUuid, "organizationUuid can't be null");
+ return countByQueryImpl(session, organizationUuid, query);
+ }
+
+ private static int countByQueryImpl(DbSession session, @Nullable String organizationUuid, ComponentQuery query) {
+ Set<Long> componentIds = query.getComponentIds();
+ if (componentIds != null && componentIds.isEmpty()) {
return 0;
}
- return mapper(session).countByQuery(query);
+ return mapper(session).countByQuery(organizationUuid, query);
}
public List<ComponentDto> selectSubProjectsByComponentUuids(DbSession session, Collection<String> keys) {
@@ -342,5 +362,4 @@ public class ComponentDao implements Dao {
private static ComponentMapper mapper(DbSession session) {
return session.getMapper(ComponentMapper.class);
}
-
}
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
index 9c3bb96b7e5..2cddadffbd4 100644
--- a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
@@ -65,9 +65,9 @@ public interface ComponentMapper {
*/
int countComponentByOrganizationAndId(@Param("organizationUuid") String organizationUuid, @Param("componentId") long componentId);
- List<ComponentDto> selectByQuery(@Param("query") ComponentQuery query, RowBounds rowBounds);
+ List<ComponentDto> selectByQuery(@Nullable @Param("organizationUuid") String organizationUuid, @Param("query") ComponentQuery query, RowBounds rowBounds);
- int countByQuery(@Param("query") ComponentQuery query);
+ int countByQuery(@Nullable @Param("organizationUuid") String organizationUuid, @Param("query") ComponentQuery query);
List<ComponentDto> selectDescendants(@Param("query") ComponentTreeQuery query, @Param("baseUuid") String baseUuid, @Param("baseUuidPath") String baseUuidPath);
diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
index a9e91ccca50..b8a97b3df49 100644
--- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
@@ -251,6 +251,9 @@
where
p.enabled=${_true}
AND p.copy_component_uuid is null
+ <if test="organizationUuid!=null">
+ and p.organization_uuid=#{organizationUuid,jdbcType=VARCHAR}
+ </if>
<if test="query.qualifiers!=null">
AND p.qualifier in
<foreach collection="query.qualifiers" item="qualifier" open="(" close=")" separator=",">
diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
index 632d98a3d8f..646a54be31a 100644
--- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
@@ -66,9 +66,10 @@ public class ComponentDaoTest {
private static final String FILE_2_UUID = "file-2-uuid";
private static final String FILE_3_UUID = "file-3-uuid";
private static final String A_VIEW_UUID = "view-uuid";
+ private static final ComponentQuery ALL_PROJECTS_COMPONENT_QUERY = ComponentQuery.builder().setQualifiers("TRK").build();
@Rule
- public ExpectedException thrown = ExpectedException.none();
+ public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
@@ -144,7 +145,7 @@ public class ComponentDaoTest {
@Test
public void selectOrFailByUuid_fails_when_component_not_found() {
- thrown.expect(RowNotFoundException.class);
+ expectedException.expect(RowNotFoundException.class);
db.prepareDbUnit(getClass(), "shared.xml");
@@ -175,7 +176,7 @@ public class ComponentDaoTest {
@Test
public void selectOrFailByKey_fails_when_component_not_found() {
- thrown.expect(RowNotFoundException.class);
+ expectedException.expect(RowNotFoundException.class);
db.prepareDbUnit(getClass(), "shared.xml");
@@ -345,8 +346,8 @@ public class ComponentDaoTest {
@Test
public void fail_with_IAE_select_component_keys_by_qualifiers_on_empty_qualifier() throws Exception {
- thrown.expect(IllegalArgumentException.class);
- thrown.expectMessage("Qualifiers cannot be empty");
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Qualifiers cannot be empty");
db.prepareDbUnit(getClass(), "shared.xml");
underTest.selectComponentsByQualifiers(dbSession, Collections.<String>emptySet());
@@ -807,7 +808,23 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_with_paging_query_and_qualifiers() {
+ public void selectByQuery_with_organization_throws_NPE_of_organizationUuid_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null");
+
+ underTest.selectByQuery(dbSession, null, ALL_PROJECTS_COMPONENT_QUERY, 1, 1);
+ }
+
+ @Test
+ public void countByQuery_with_organization_throws_NPE_of_organizationUuid_is_null() {
+ expectedException.expect(NullPointerException.class);
+ expectedException.expectMessage("organizationUuid can't be null");
+
+ underTest.countByQuery(dbSession, null, ALL_PROJECTS_COMPONENT_QUERY);
+ }
+
+ @Test
+ public void selectByQuery_with_paging_query_and_qualifiers() {
OrganizationDto organizationDto = db.organizations().insert();
componentDb.insertProjectAndSnapshot(newProjectDto(organizationDto).setName("aaaa-name"));
componentDb.insertProjectAndSnapshot(newView(organizationDto));
@@ -827,7 +844,44 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_name_with_special_characters() {
+ public void selectByQuery_with_organization_filters_on_specified_organization() {
+ OrganizationDto organization1 = db.organizations().insert();
+ OrganizationDto organization2 = db.organizations().insert();
+ ComponentDto project1 = componentDb.insertProject(organization1);
+ ComponentDto project2 = componentDb.insertProject(organization2);
+
+ assertThat(underTest.selectByQuery(dbSession, ALL_PROJECTS_COMPONENT_QUERY, 0, 2))
+ .extracting(ComponentDto::uuid)
+ .containsOnly(project1.uuid(), project2.uuid());
+ assertThat(underTest.selectByQuery(dbSession, organization1.getUuid(), ALL_PROJECTS_COMPONENT_QUERY, 0, 2))
+ .extracting(ComponentDto::uuid)
+ .containsOnly(project1.uuid());
+ assertThat(underTest.selectByQuery(dbSession, organization2.getUuid(), ALL_PROJECTS_COMPONENT_QUERY, 0, 2))
+ .extracting(ComponentDto::uuid)
+ .containsOnly(project2.uuid());
+ assertThat(underTest.selectByQuery(dbSession, "non existent organization uuid", ALL_PROJECTS_COMPONENT_QUERY, 0, 2))
+ .isEmpty();
+ }
+
+ @Test
+ public void countByQuery_with_organization_filters_on_specified_organization() {
+ OrganizationDto organization1 = db.organizations().insert();
+ OrganizationDto organization2 = db.organizations().insert();
+ ComponentDto project1 = componentDb.insertProject(organization1);
+ ComponentDto project2 = componentDb.insertProject(organization2);
+
+ assertThat(underTest.countByQuery(dbSession, ALL_PROJECTS_COMPONENT_QUERY))
+ .isEqualTo(2);
+ assertThat(underTest.countByQuery(dbSession, organization1.getUuid(), ALL_PROJECTS_COMPONENT_QUERY))
+ .isEqualTo(1);
+ assertThat(underTest.countByQuery(dbSession, organization2.getUuid(), ALL_PROJECTS_COMPONENT_QUERY))
+ .isEqualTo(1);
+ assertThat(underTest.countByQuery(dbSession, "non existent organization uuid", ALL_PROJECTS_COMPONENT_QUERY))
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void selectByQuery_name_with_special_characters() {
componentDb.insertProjectAndSnapshot(newProjectDto(db.getDefaultOrganization()).setName("project-\\_%/-name"));
ComponentQuery query = ComponentQuery.builder().setNameOrKeyQuery("-\\_%/-").setQualifiers(Qualifiers.PROJECT).build();
@@ -838,7 +892,7 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_key_with_special_characters() {
+ public void selectByQuery_key_with_special_characters() {
componentDb.insertProjectAndSnapshot(newProjectDto(db.organizations().insert()).setKey("project-_%-key"));
ComponentQuery query = ComponentQuery.builder().setNameOrKeyQuery("project-_%-key").setQualifiers(Qualifiers.PROJECT).build();
@@ -849,7 +903,7 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_filter_on_language() {
+ public void selectByQuery_filter_on_language() {
componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("java-project-key").setLanguage("java"));
componentDb.insertComponent(newProjectDto(db.getDefaultOrganization()).setKey("cpp-project-key").setLanguage("cpp"));
@@ -861,7 +915,7 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_on_empty_list_of_component_id() {
+ public void selectByQuery_on_empty_list_of_component_id() {
ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentIds(emptySet()).build();
List<ComponentDto> result = underTest.selectByQuery(dbSession, dbQuery, 0, 10);
int count = underTest.countByQuery(dbSession, dbQuery);
@@ -871,7 +925,7 @@ public class ComponentDaoTest {
}
@Test
- public void select_by_query_on_component_ids() {
+ public void selectByQuery_on_component_ids() {
OrganizationDto organizationDto = db.organizations().insert();
ComponentDto sonarqube = componentDb.insertComponent(newProjectDto(organizationDto));
ComponentDto jdk8 = componentDb.insertComponent(newProjectDto(organizationDto));
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java
index 80d5acb65cb..00910b0366d 100644
--- a/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java
+++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/component/SearchWsRequest.java
@@ -26,12 +26,22 @@ import javax.annotation.Nullable;
import static java.util.Objects.requireNonNull;
public class SearchWsRequest {
+ private String organization;
private List<String> qualifiers;
private Integer page;
private Integer pageSize;
private String query;
private String language;
+ public String getOrganization() {
+ return organization;
+ }
+
+ public SearchWsRequest setOrganization(String organization) {
+ this.organization = organization;
+ return this;
+ }
+
public List<String> getQualifiers() {
return qualifiers;
}