]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-6465 Replace groupsCount by groups
authorJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Fri, 22 May 2015 09:08:06 +0000 (11:08 +0200)
committerJean-Baptiste Lievremont <jean-baptiste.lievremont@sonarsource.com>
Tue, 26 May 2015 14:04:31 +0000 (16:04 +0200)
server/sonar-server/src/main/java/org/sonar/server/user/ws/SearchAction.java
server/sonar-server/src/main/resources/org/sonar/server/user/ws/example-search.json
server/sonar-server/src/test/java/org/sonar/server/user/ws/SearchActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/user/ws/SearchActionTest/five_users.json
server/sonar-server/src/test/resources/org/sonar/server/user/ws/SearchActionTest/user_with_groups.json
sonar-core/src/main/java/org/sonar/core/user/GroupMembershipDao.java
sonar-core/src/main/java/org/sonar/core/user/GroupMembershipMapper.java
sonar-core/src/main/java/org/sonar/core/user/LoginGroup.java [new file with mode: 0644]
sonar-core/src/main/java/org/sonar/core/user/UserGroupCount.java [deleted file]
sonar-core/src/main/resources/org/sonar/core/user/GroupMembershipMapper.xml
sonar-core/src/test/java/org/sonar/core/user/GroupMembershipDaoTest.java

index 0e6e76c62083ab05eedd2b032b1e23e03b33382d..2868829d06525581e86ee6a51485b2c36c78893b 100644 (file)
@@ -24,9 +24,10 @@ import com.google.common.base.Function;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -48,8 +49,8 @@ public class SearchAction implements UsersWsAction {
   private static final String FIELD_NAME = "name";
   private static final String FIELD_EMAIL = "email";
   private static final String FIELD_SCM_ACCOUNTS = "scmAccounts";
-  private static final String FIELD_GROUPS_COUNT = "groupsCount";
-  private static final Set<String> FIELDS = ImmutableSet.of(FIELD_LOGIN, FIELD_NAME, FIELD_EMAIL, FIELD_SCM_ACCOUNTS, FIELD_GROUPS_COUNT);
+  private static final String FIELD_GROUPS = "groups";
+  private static final Set<String> FIELDS = ImmutableSet.of(FIELD_LOGIN, FIELD_NAME, FIELD_EMAIL, FIELD_SCM_ACCOUNTS, FIELD_GROUPS);
 
   private final UserIndex userIndex;
   private final DbClient dbClient;
@@ -81,7 +82,7 @@ public class SearchAction implements UsersWsAction {
     List<String> fields = request.paramAsStrings(Param.FIELDS);
     SearchResult<UserDoc> result = userIndex.search(request.param(Param.TEXT_QUERY), options);
 
-    Map<String, Integer> groupsByLogin = Maps.newHashMap();
+    Multimap<String, String> groupsByLogin = Multimaps.forMap(Maps.<String, String>newHashMap());
     DbSession session = dbClient.openSession(false);
     try {
       Collection<String> logins = Collections2.transform(result.getDocs(), new Function<UserDoc, String>() {
@@ -90,7 +91,7 @@ public class SearchAction implements UsersWsAction {
           return input.login();
         }
       });
-      groupsByLogin = dbClient.groupMembershipDao().countGroupsByLogins(session, logins);
+      groupsByLogin = dbClient.groupMembershipDao().selectGroupsByLogins(session, logins);
     } finally {
       session.close();
     }
@@ -101,7 +102,7 @@ public class SearchAction implements UsersWsAction {
     json.endObject().close();
   }
 
-  private void writeUsers(JsonWriter json, SearchResult<UserDoc> result, @Nullable List<String> fields, Map<String, Integer> groupsByLogin) {
+  private void writeUsers(JsonWriter json, SearchResult<UserDoc> result, @Nullable List<String> fields, Multimap<String, String> groupsByLogin) {
 
     json.name("users").beginArray();
     for (UserDoc user : result.getDocs()) {
@@ -109,7 +110,7 @@ public class SearchAction implements UsersWsAction {
       writeIfNeeded(json, user.login(), FIELD_LOGIN, fields);
       writeIfNeeded(json, user.name(), FIELD_NAME, fields);
       writeIfNeeded(json, user.email(), FIELD_EMAIL, fields);
-      writeIfNeeded(json, groupsByLogin.get(user.login()), FIELD_GROUPS_COUNT, fields);
+      writeGroupsIfNeeded(json, groupsByLogin.get(user.login()), fields);
       if (fieldIsWanted(FIELD_SCM_ACCOUNTS, fields)) {
         json.name(FIELD_SCM_ACCOUNTS)
           .beginArray()
@@ -127,9 +128,13 @@ public class SearchAction implements UsersWsAction {
     }
   }
 
-  private void writeIfNeeded(JsonWriter json, Integer value, String field, @Nullable List<String> fields) {
-    if (fieldIsWanted(field, fields)) {
-      json.prop(field, value);
+  private void writeGroupsIfNeeded(JsonWriter json, Collection<String> groups, @Nullable List<String> fields) {
+    if (fieldIsWanted(FIELD_GROUPS, fields)) {
+      json.name(FIELD_GROUPS).beginArray();
+      for (String groupName : groups) {
+        json.value(groupName);
+      }
+      json.endArray();
     }
   }
 
index 7b959b2c5947cd80762fa0e94150ea80a25364a0..39448ce788df933419b4b55b988965034c30b7a9 100644 (file)
@@ -4,13 +4,17 @@
       "login": "fmallet",
       "name": "Freddy Mallet",
       "active": true,
-      "email": "f@m.com"
+      "email": "f@m.com",
+      "scmAccounts": [],
+      "groups": ["sonar-users", "sonar-administrators"]
     },
     {
       "login": "sbrandhof",
       "name": "Simon",
       "active": true,
-      "scmAccounts": ["simon.brandhof", "s.brandhof@company.tld"]
+      "email": "s.brandhof@company.tld",
+      "scmAccounts": ["simon.brandhof", "s.brandhof@company.tld"],
+      "groups": ["sonar-users"]
     }
   ]
 }
index a2456afbac0c589383bfa6a5dc0c63f6804b6907..c5177efbcaa564e479927c3d7150beb3d6602bb3 100644 (file)
@@ -124,35 +124,35 @@ public class SearchActionTest {
       .contains("name")
       .contains("email")
       .contains("scmAccounts")
-      .contains("groupsCount");
+      .contains("groups");
 
     assertThat(tester.newGetRequest("api/users", "search").setParam("f", "").execute().outputAsString())
       .contains("login")
       .contains("name")
       .contains("email")
       .contains("scmAccounts")
-      .contains("groupsCount");
+      .contains("groups");
 
     assertThat(tester.newGetRequest("api/users", "search").setParam("f", "login").execute().outputAsString())
       .contains("login")
       .doesNotContain("name")
       .doesNotContain("email")
       .doesNotContain("scmAccounts")
-      .doesNotContain("groupsCount");
+      .doesNotContain("groups");
 
     assertThat(tester.newGetRequest("api/users", "search").setParam("f", "scmAccounts").execute().outputAsString())
       .doesNotContain("login")
       .doesNotContain("name")
       .doesNotContain("email")
       .contains("scmAccounts")
-      .doesNotContain("groupsCount");
+      .doesNotContain("groups");
 
-    assertThat(tester.newGetRequest("api/users", "search").setParam("f", "groupsCount").execute().outputAsString())
+    assertThat(tester.newGetRequest("api/users", "search").setParam("f", "groups").execute().outputAsString())
       .doesNotContain("login")
       .doesNotContain("name")
       .doesNotContain("email")
       .doesNotContain("scmAccounts")
-      .contains("groupsCount");
+      .contains("groups");
   }
 
   @Test
index d568e8b0b7e6a0cd36653c35faf00cc6b10b930c..86b57c314cafbd6ec44037e0b5ecb5cb456099f4 100644 (file)
@@ -10,7 +10,7 @@
       "scmAccounts": [
         "user-0"
       ],
-      "groupsCount": 0
+      "groups": []
     },
     {
       "login": "user-1",
@@ -19,7 +19,7 @@
       "scmAccounts": [
         "user-1"
       ],
-      "groupsCount": 0
+      "groups": []
     },
     {
       "login": "user-2",
@@ -28,7 +28,7 @@
       "scmAccounts": [
         "user-2"
       ],
-      "groupsCount": 0
+      "groups": []
     },
     {
       "login": "user-3",
@@ -37,7 +37,7 @@
       "scmAccounts": [
         "user-3"
       ],
-      "groupsCount": 0
+      "groups": []
     },
     {
       "login": "user-4",
@@ -46,7 +46,7 @@
       "scmAccounts": [
         "user-4"
       ],
-      "groupsCount": 0
+      "groups": []
     }
   ]
 }
index a49e8252732010cff530a7f85f2e88498f05fa76..6b2d6543f65393ad1b5e3c8310b3cb1304a80c66 100644 (file)
@@ -10,7 +10,7 @@
       "scmAccounts": [
         "user-0"
       ],
-      "groupsCount": 2
+      "groups": ["sonar-admins", "sonar-users"]
     }
   ]
 }
index 31ff32405c293fd00215800827e855384e43358b..84447d42d1f2e838cad9f7198d72f3dd6f0a3c0e 100644 (file)
@@ -22,8 +22,10 @@ package org.sonar.core.user;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
+import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
@@ -80,16 +82,16 @@ public class GroupMembershipDao implements DaoComponent {
     return result;
   }
 
-  public Map<String, Integer> countGroupsByLogins(final DbSession session, Collection<String> logins) {
-    final Map<String, Integer> result = Maps.newHashMap();
-    DaoUtils.executeLargeInputs(logins, new NonNullInputFunction<List<String>, List<UserGroupCount>>() {
+  public Multimap<String, String> selectGroupsByLogins(final DbSession session, Collection<String> logins) {
+    final Multimap<String, String> result = ArrayListMultimap.create();
+    DaoUtils.executeLargeInputs(logins, new NonNullInputFunction<List<String>, List<LoginGroup>>() {
       @Override
-      protected List<UserGroupCount> doApply(List<String> input) {
-        List<UserGroupCount> groupCounts = mapper(session).countGroupsByLogins(input);
-        for (UserGroupCount count : groupCounts) {
-          result.put(count.login(), count.groupCount());
+      protected List<LoginGroup> doApply(List<String> input) {
+        List<LoginGroup> groupMemberships = mapper(session).selectGroupsByLogins(input);
+        for (LoginGroup membership : groupMemberships) {
+          result.put(membership.login(), membership.groupName());
         }
-        return groupCounts;
+        return groupMemberships;
       }
     });
 
index b4a66a5ba9a303ab92268c8f9a4d8563e7b558e4..777aa1eea00c7f75c41798eb514397db937e7604 100644 (file)
@@ -34,5 +34,5 @@ public interface GroupMembershipMapper {
 
   List<GroupUserCount> countUsersByGroup(@Param("groupIds") List<Long> groupIds);
 
-  List<UserGroupCount> countGroupsByLogins(@Param("logins") List<String> logins);
+  List<LoginGroup> selectGroupsByLogins(@Param("logins") List<String> logins);
 }
diff --git a/sonar-core/src/main/java/org/sonar/core/user/LoginGroup.java b/sonar-core/src/main/java/org/sonar/core/user/LoginGroup.java
new file mode 100644 (file)
index 0000000..7f25a8c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.user;
+
+public class LoginGroup {
+
+  private String login;
+  private String groupName;
+
+  public String login() {
+    return login;
+  }
+
+  public String groupName() {
+    return groupName;
+  }
+}
diff --git a/sonar-core/src/main/java/org/sonar/core/user/UserGroupCount.java b/sonar-core/src/main/java/org/sonar/core/user/UserGroupCount.java
deleted file mode 100644 (file)
index 712c1b4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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.core.user;
-
-public class UserGroupCount {
-
-  private String login;
-  private int groupCount;
-
-  public String login() {
-    return login;
-  }
-
-  public int groupCount() {
-    return groupCount;
-  }
-}
\ No newline at end of file
index 7774f9eb4b0b0e7243fa1832b0869c2c67f504a0..2663c390189453c3f5c39267111240ab60c690b8 100644 (file)
     GROUP BY g.name
   </select>
 
-  <select id="countGroupsByLogins" parameterType="string" resultType="org.sonar.core.user.UserGroupCount">
-    SELECT u.login as login, count(gu.user_id) as groupCount
+  <select id="selectGroupsByLogins" parameterType="string" resultType="org.sonar.core.user.LoginGroup">
+    SELECT u.login as login, g.name as groupName
     FROM users u
     LEFT JOIN groups_users gu ON gu.user_id=u.id
+    INNER JOIN groups g ON gu.group_id=g.id
     <where>
       u.login in
       <foreach collection="logins" open="(" close=")" item="login" separator=",">
         #{login}
       </foreach>
     </where>
-    GROUP BY u.login
   </select>
 
 </mapper>
index 570a79217778525f2a397469993e429b63571d72..ed86008d099b719ae583831473dca579836a81fa 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.sonar.core.user;
 
+import com.google.common.collect.Multimap;
 import java.util.Arrays;
 import java.util.List;
 import org.junit.Before;
@@ -192,15 +193,11 @@ public class GroupMembershipDaoTest {
     DbSession session = dbTester.myBatis().openSession(false);
 
     try {
-      assertThat(dao.countGroupsByLogins(session, Arrays.<String>asList())).isEmpty();
-      assertThat(dao.countGroupsByLogins(session, Arrays.asList("two-hundred")))
-        .containsExactly(entry("two-hundred", 3));
-      assertThat(dao.countGroupsByLogins(session, Arrays.asList("two-hundred", "two-hundred-one")))
-        .containsOnly(entry("two-hundred", 3), entry("two-hundred-one", 1));
-      assertThat(dao.countGroupsByLogins(session, Arrays.asList("two-hundred", "two-hundred-one", "two-hundred-two")))
-        .containsOnly(entry("two-hundred", 3), entry("two-hundred-one", 1), entry("two-hundred-two", 0));
-      assertThat(dao.countGroupsByLogins(session, Arrays.asList("two-hundred-two")))
-        .containsOnly(entry("two-hundred-two", 0));
+      assertThat(dao.selectGroupsByLogins(session, Arrays.<String>asList()).keys()).isEmpty();
+      Multimap<String, String> groupsByLogin = dao.selectGroupsByLogins(session, Arrays.asList("two-hundred", "two-hundred-one", "two-hundred-two"));
+      assertThat(groupsByLogin.get("two-hundred")).containsOnly("sonar-administrators", "sonar-users", "sonar-reviewers");
+      assertThat(groupsByLogin.get("two-hundred-one")).containsOnly("sonar-users");
+      assertThat(groupsByLogin.get("two-hundred-two")).isEmpty();
     } finally {
       session.close();
     }