Merge "Support recursive group resolution in list members REST endpoint"

This commit is contained in:
Shawn Pearce
2013-01-17 19:00:03 +00:00
committed by Gerrit Code Review
2 changed files with 86 additions and 8 deletions

View File

@@ -337,6 +337,45 @@ Lists the direct members of a group.
]
----
To resolve the included groups of a group recursively and to list all
members the parameter `recursive` can be set.
----
GET /groups/834ec36dd5e0ed21a2ff5d7e2255da082d63bbd7/members/?recursive HTTP/1.0
HTTP/1.1 200 OK
Content-Disposition: attachment
Content-Type: application/json;charset=UTF-8
)]}'
[
{
"kind": "gerritcodereview#member",
"full_name": "Jane Roe",
"id": "1000097",
"account_id": 1000097,
"preferred_email": "jane.roe@example.com",
"user_name": "jane"
},
{
"kind": "gerritcodereview#member",
"full_name": "John Doe",
"id": "1000096",
"account_id": 1000096,
"preferred_email": "john.doe@example.com",
"user_name": "doe"
},
{
"kind": "gerritcodereview#member",
"full_name": "Richard Roe",
"id": "1000098",
"account_id": 1000098,
"preferred_email": "richard.roe@example.com",
"user_name": "richard"
}
]
----
[[included-groups]]
/groups/*/groups/ (List Included Groups)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -15,27 +15,39 @@
package com.google.gerrit.server.group;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gerrit.common.data.GroupDetail;
import com.google.gerrit.common.errors.NoSuchGroupException;
import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.extensions.restapi.BadRequestException;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestReadView;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupIncludeByUuid;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.server.account.AccountCache;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupDetailFactory;
import com.google.gerrit.server.group.MembersCollection.MemberInfo;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.kohsuke.args4j.Option;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
public class ListMembers implements RestReadView<GroupResource> {
private final GroupCache groupCache;
private final GroupDetailFactory.Factory groupDetailFactory;
private final AccountCache accountCache;
@Option(name = "--recursive", usage = "to resolve included groups recursively")
private boolean recursive;
@Inject
ListMembers(final GroupCache groupCache,
final GroupDetailFactory.Factory groupDetailFactory,
@@ -46,22 +58,49 @@ public class ListMembers implements RestReadView<GroupResource> {
}
@Override
public List<MemberInfo> apply(final GroupResource resource) throws AuthException,
BadRequestException, ResourceConflictException, Exception {
final List<MemberInfo> members = Lists.newArrayList();
public List<MemberInfo> apply(final GroupResource resource)
throws AuthException, BadRequestException, ResourceConflictException,
Exception {
final Map<Account.Id, MemberInfo> members =
getMembers(resource.getGroupUUID(), new HashSet<AccountGroup.UUID>());
return Lists.newArrayList(members.values());
}
private Map<Account.Id, MemberInfo> getMembers(
final AccountGroup.UUID groupUUID,
final HashSet<AccountGroup.UUID> seenGroups) throws OrmException,
NoSuchGroupException {
seenGroups.add(groupUUID);
final Map<Account.Id, MemberInfo> members = Maps.newHashMap();
final AccountGroup group = groupCache.get(groupUUID);
if (group == null) {
// the included group is an external group and can't be resolved
return Collections.emptyMap();
}
final AccountGroup group =
groupCache.get(resource.getGroupUUID());
final GroupDetail groupDetail =
groupDetailFactory.create(group.getId()).call();
if (groupDetail.members != null) {
for (final AccountGroupMember member : groupDetail.members) {
final Account account = accountCache.get(member.getAccountId()).getAccount();
members.add(MembersCollection.parse(account));
for (final AccountGroupMember m : groupDetail.members) {
if (!members.containsKey(m.getAccountId())) {
final Account account =
accountCache.get(m.getAccountId()).getAccount();
members.put(account.getId(), MembersCollection.parse(account));
}
}
}
if (recursive) {
if (groupDetail.includes != null) {
for (final AccountGroupIncludeByUuid includedGroup : groupDetail.includes) {
if (!seenGroups.contains(includedGroup.getIncludeUUID())) {
members.putAll(getMembers(includedGroup.getIncludeUUID(), seenGroups));
}
}
}
}
return members;
}
}