Merge "Support recursive group resolution in list members REST endpoint"
This commit is contained in:
@@ -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]]
|
[[included-groups]]
|
||||||
/groups/*/groups/ (List Included Groups)
|
/groups/*/groups/ (List Included Groups)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@@ -15,27 +15,39 @@
|
|||||||
package com.google.gerrit.server.group;
|
package com.google.gerrit.server.group;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.gerrit.common.data.GroupDetail;
|
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.AuthException;
|
||||||
import com.google.gerrit.extensions.restapi.BadRequestException;
|
import com.google.gerrit.extensions.restapi.BadRequestException;
|
||||||
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
import com.google.gerrit.extensions.restapi.ResourceConflictException;
|
||||||
import com.google.gerrit.extensions.restapi.RestReadView;
|
import com.google.gerrit.extensions.restapi.RestReadView;
|
||||||
import com.google.gerrit.reviewdb.client.Account;
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.AccountGroup;
|
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.reviewdb.client.AccountGroupMember;
|
||||||
import com.google.gerrit.server.account.AccountCache;
|
import com.google.gerrit.server.account.AccountCache;
|
||||||
import com.google.gerrit.server.account.GroupCache;
|
import com.google.gerrit.server.account.GroupCache;
|
||||||
import com.google.gerrit.server.account.GroupDetailFactory;
|
import com.google.gerrit.server.account.GroupDetailFactory;
|
||||||
import com.google.gerrit.server.group.MembersCollection.MemberInfo;
|
import com.google.gerrit.server.group.MembersCollection.MemberInfo;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
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.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class ListMembers implements RestReadView<GroupResource> {
|
public class ListMembers implements RestReadView<GroupResource> {
|
||||||
private final GroupCache groupCache;
|
private final GroupCache groupCache;
|
||||||
private final GroupDetailFactory.Factory groupDetailFactory;
|
private final GroupDetailFactory.Factory groupDetailFactory;
|
||||||
private final AccountCache accountCache;
|
private final AccountCache accountCache;
|
||||||
|
|
||||||
|
@Option(name = "--recursive", usage = "to resolve included groups recursively")
|
||||||
|
private boolean recursive;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ListMembers(final GroupCache groupCache,
|
ListMembers(final GroupCache groupCache,
|
||||||
final GroupDetailFactory.Factory groupDetailFactory,
|
final GroupDetailFactory.Factory groupDetailFactory,
|
||||||
@@ -46,22 +58,49 @@ public class ListMembers implements RestReadView<GroupResource> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MemberInfo> apply(final GroupResource resource) throws AuthException,
|
public List<MemberInfo> apply(final GroupResource resource)
|
||||||
BadRequestException, ResourceConflictException, Exception {
|
throws AuthException, BadRequestException, ResourceConflictException,
|
||||||
final List<MemberInfo> members = Lists.newArrayList();
|
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 =
|
final GroupDetail groupDetail =
|
||||||
groupDetailFactory.create(group.getId()).call();
|
groupDetailFactory.create(group.getId()).call();
|
||||||
|
|
||||||
if (groupDetail.members != null) {
|
if (groupDetail.members != null) {
|
||||||
for (final AccountGroupMember member : groupDetail.members) {
|
for (final AccountGroupMember m : groupDetail.members) {
|
||||||
final Account account = accountCache.get(member.getAccountId()).getAccount();
|
if (!members.containsKey(m.getAccountId())) {
|
||||||
members.add(MembersCollection.parse(account));
|
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;
|
return members;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user