From ea7785d32257e0500a020e1650d02e8b69069a86 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Fri, 3 Feb 2017 11:19:22 +0100 Subject: [PATCH] SONAR-8740 add organization to response of api/favorites/search --- .../server/favorite/ws/SearchAction.java | 86 +++++++++---------- .../server/favorite/ws/search-example.json | 3 + .../server/favorite/ws/SearchActionTest.java | 10 ++- sonar-ws/src/main/protobuf/ws-favorites.proto | 1 + 4 files changed, 52 insertions(+), 48 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java index 0a08b4e60f9..9b5c02ed5d9 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/favorite/ws/SearchAction.java @@ -20,8 +20,9 @@ package org.sonar.server.favorite.ws; -import com.google.common.collect.ImmutableSet; +import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.function.Predicate; import org.sonar.api.server.ws.Request; @@ -34,6 +35,7 @@ import org.sonar.core.util.stream.Collectors; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; +import org.sonar.db.organization.OrganizationDto; import org.sonar.server.favorite.FavoriteFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Common; @@ -41,6 +43,7 @@ import org.sonarqube.ws.Favorites.Favorite; import org.sonarqube.ws.Favorites.SearchResponse; import org.sonarqube.ws.client.favorite.SearchRequest; +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Protobuf.setNullable; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.favorite.FavoritesWsParameters.ACTION_SEARCH; @@ -86,66 +89,56 @@ public class SearchAction implements FavoritesWsAction { private SearchResults toSearchResults(SearchRequest request) { userSession.checkLoggedIn(); try (DbSession dbSession = dbClient.openSession(false)) { - SearchResults.Builder builder = SearchResults.newBuilder(request); - addAuthorizedProjectUuids(dbSession, builder); - addFavorites(builder); - return builder.build(); + List authorizedFavorites = favoriteFinder.list().stream() + .filter(isAuthorized(dbSession)) + .collect(Collectors.toList()); + Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(authorizedFavorites.size()); + List displayedFavorites = authorizedFavorites.stream() + .skip(paging.offset()) + .limit(paging.pageSize()) + .collect(Collectors.toList()); + Map organizationsByUuid = getOrganizationsOfComponents(dbSession, displayedFavorites); + return new SearchResults(paging, displayedFavorites, organizationsByUuid); } } - private void addFavorites(SearchResults.Builder builder) { - builder.allFavorites = favoriteFinder.list(); + private Predicate isAuthorized(DbSession dbSession) { + Collection rootProjectsUuids = dbClient.authorizationDao().selectAuthorizedRootProjectsUuids(dbSession, userSession.getUserId(), UserRole.USER); + Set authorizedProjectUuids = rootProjectsUuids + .stream() + .collect(Collectors.toSet(rootProjectsUuids.size())); + return dto -> authorizedProjectUuids.contains(dto.projectUuid()); } - private void addAuthorizedProjectUuids(DbSession dbSession, SearchResults.Builder results) { - results.authorizedProjectUuids = ImmutableSet - .copyOf(dbClient.authorizationDao().selectAuthorizedRootProjectsUuids(dbSession, userSession.getUserId(), UserRole.USER)); + private Map getOrganizationsOfComponents(DbSession dbSession, List displayedFavorites) { + Set organizationUuids = displayedFavorites.stream() + .map(ComponentDto::getOrganizationUuid) + .collect(Collectors.toSet()); + return dbClient.organizationDao().selectByUuids(dbSession, organizationUuids) + .stream() + .collect(Collectors.uniqueIndex(OrganizationDto::getUuid)); } private static class SearchResults { private final List favorites; private final Paging paging; + private final Map organizationsByUuid; - private SearchResults(Builder builder) { - Predicate authorizedProjects = c -> builder.authorizedProjectUuids.contains(c.projectUuid()); - int total = (int) builder.allFavorites.stream().filter(authorizedProjects).count(); - this.paging = Paging.forPageIndex(builder.page).withPageSize(builder.pageSize).andTotal(total); - this.favorites = builder.allFavorites.stream() - .filter(authorizedProjects) - .skip(paging.offset()) - .limit(paging.pageSize()) - .collect(Collectors.toList()); - } - - static Builder newBuilder(SearchRequest request) { - return new Builder(request); - } - - private static class Builder { - private final int page; - private final int pageSize; - private Set authorizedProjectUuids; - private List allFavorites; - - private Builder(SearchRequest request) { - this.page = request.getPage(); - this.pageSize = request.getPageSize(); - } - - public SearchResults build() { - return new SearchResults(this); - } + private SearchResults(Paging paging, List favorites, Map organizationsByUuid) { + this.paging = paging; + this.favorites = favorites; + this.organizationsByUuid = organizationsByUuid; } } - private SearchResponse toSearchResponse(SearchResults searchResults) { + private static SearchResponse toSearchResponse(SearchResults searchResults) { SearchResponse.Builder builder = SearchResponse.newBuilder(); addPaging(builder, searchResults); addFavorites(builder, searchResults); return builder.build(); } - private void addPaging(SearchResponse.Builder builder, SearchResults results) { + private static void addPaging(SearchResponse.Builder builder, SearchResults results) { builder .setPaging(Common.Paging.newBuilder() .setPageIndex(results.paging.pageIndex()) @@ -153,16 +146,21 @@ public class SearchAction implements FavoritesWsAction { .setTotal(results.paging.total())); } - private void addFavorites(SearchResponse.Builder builder, SearchResults results) { + private static void addFavorites(SearchResponse.Builder builder, SearchResults results) { Favorite.Builder favoriteBuilder = Favorite.newBuilder(); results.favorites.stream() - .map(componentDto -> toWsFavorite(favoriteBuilder, componentDto)) + .map(componentDto -> toWsFavorite(favoriteBuilder, results, componentDto)) .forEach(builder::addFavorites); } - private Favorite toWsFavorite(Favorite.Builder builder, ComponentDto componentDto) { + private static Favorite toWsFavorite(Favorite.Builder builder, SearchResults results, ComponentDto componentDto) { + OrganizationDto organization = results.organizationsByUuid.get(componentDto.getOrganizationUuid()); + checkArgument(organization != null, + "Organization with uuid '%s' not found for favorite with uuid '%s'", + componentDto.getOrganizationUuid(), componentDto.uuid()); builder .clear() + .setOrganization(organization.getKey()) .setKey(componentDto.key()); setNullable(componentDto.name(), builder::setName); setNullable(componentDto.qualifier(), builder::setQualifier); diff --git a/server/sonar-server/src/main/resources/org/sonar/server/favorite/ws/search-example.json b/server/sonar-server/src/main/resources/org/sonar/server/favorite/ws/search-example.json index 74d0909f625..414b8d7d4a9 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/favorite/ws/search-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/favorite/ws/search-example.json @@ -6,16 +6,19 @@ }, "favorites": [ { + "organization": "my-org", "key": "K2", "name": "Apache HBase", "qualifier": "TRK" }, { + "organization": "openjdk", "key": "K3", "name": "JDK9", "qualifier": "TRK" }, { + "organization": "my-org", "key": "K1", "name": "Samba", "qualifier": "TRK" diff --git a/server/sonar-server/src/test/java/org/sonar/server/favorite/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/favorite/ws/SearchActionTest.java index aabc2e80ba1..934bebc6043 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/favorite/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/favorite/ws/SearchActionTest.java @@ -159,13 +159,15 @@ public class SearchActionTest { @Test public void json_example() { - addComponent(newProjectDto(db.getDefaultOrganization()).setKey("K1").setName("Samba")); - addComponent(newProjectDto(db.getDefaultOrganization()).setKey("K2").setName("Apache HBase")); - addComponent(newProjectDto(db.getDefaultOrganization()).setKey("K3").setName("JDK9")); + OrganizationDto organization1 = db.organizations().insertForKey("my-org"); + OrganizationDto organization2 = db.organizations().insertForKey("openjdk"); + addComponent(newProjectDto(organization1).setKey("K1").setName("Samba")); + addComponent(newProjectDto(organization1).setKey("K2").setName("Apache HBase")); + addComponent(newProjectDto(organization2).setKey("K3").setName("JDK9")); String result = ws.newRequest().execute().getInput(); - assertJson(result).isSimilarTo(getClass().getResource("search-example.json")); + assertJson(result).isSimilarTo(ws.getDef().responseExampleAsString()); } @Test diff --git a/sonar-ws/src/main/protobuf/ws-favorites.proto b/sonar-ws/src/main/protobuf/ws-favorites.proto index 64a75848238..7cdb6eceb94 100644 --- a/sonar-ws/src/main/protobuf/ws-favorites.proto +++ b/sonar-ws/src/main/protobuf/ws-favorites.proto @@ -33,6 +33,7 @@ message SearchResponse { } message Favorite { + optional string organization = 4; optional string key = 1; optional string name = 2; optional string qualifier = 3; -- 2.39.5