Perform group lookups by name from the group index

Now that we have the group index, we can use it to look up groups by
name. This change is a prerequisite for migrating groups to NoteDb.

A lot of tests didn't check for null for values retrieved from the group
cache. This behavior isn't changed as improving it is beyond the scope
of this change.

Change-Id: Id0ddc3bd43aa6e6b06833c712a51e2fb80402abe
This commit is contained in:
Alice Kober-Sotzek
2017-08-21 10:25:58 +02:00
parent c7be8f9f51
commit 1e1a63a6bd
20 changed files with 152 additions and 88 deletions

View File

@@ -1067,7 +1067,8 @@ public abstract class AbstractDaemonTest {
protected void grant(Project.NameKey project, String ref, String permission, boolean force)
throws RepositoryNotFoundException, IOException, ConfigInvalidException {
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
grant(project, ref, permission, force, adminGroup.getGroupUUID());
}

View File

@@ -24,11 +24,12 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.Sequences;
import com.google.gerrit.server.account.AccountsUpdate;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.VersionedAuthorizedKeys;
import com.google.gerrit.server.account.externalids.ExternalId;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
import com.google.gerrit.server.group.Groups;
import com.google.gerrit.server.group.GroupsUpdate;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.ServerInitiated;
import com.google.gerrit.server.ssh.SshKeyCache;
import com.google.gwtorm.server.SchemaFactory;
@@ -54,7 +55,7 @@ public class AccountCreator {
private final Sequences sequences;
private final AccountsUpdate.Server accountsUpdate;
private final VersionedAuthorizedKeys.Accessor authorizedKeys;
private final Groups groups;
private final GroupCache groupCache;
private final Provider<GroupsUpdate> groupsUpdateProvider;
private final SshKeyCache sshKeyCache;
private final ExternalIdsUpdate.Server externalIdsUpdate;
@@ -66,7 +67,7 @@ public class AccountCreator {
Sequences sequences,
AccountsUpdate.Server accountsUpdate,
VersionedAuthorizedKeys.Accessor authorizedKeys,
Groups groups,
GroupCache groupCache,
@ServerInitiated Provider<GroupsUpdate> groupsUpdateProvider,
SshKeyCache sshKeyCache,
ExternalIdsUpdate.Server externalIdsUpdate,
@@ -76,7 +77,7 @@ public class AccountCreator {
this.sequences = sequences;
this.accountsUpdate = accountsUpdate;
this.authorizedKeys = authorizedKeys;
this.groups = groups;
this.groupCache = groupCache;
this.groupsUpdateProvider = groupsUpdateProvider;
this.sshKeyCache = sshKeyCache;
this.externalIdsUpdate = externalIdsUpdate;
@@ -121,7 +122,7 @@ public class AccountCreator {
if (groupNames != null) {
for (String n : groupNames) {
AccountGroup.NameKey k = new AccountGroup.NameKey(n);
Optional<AccountGroup> group = groups.getGroup(db, k);
Optional<InternalGroup> group = groupCache.get(k);
if (!group.isPresent()) {
throw new NoSuchGroupException(n);
}

View File

@@ -91,6 +91,7 @@ import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.mail.Address;
import com.google.gerrit.server.notedb.rebuild.ChangeRebuilderImpl;
import com.google.gerrit.server.project.RefPattern;
@@ -1014,7 +1015,8 @@ public class AccountIT extends AbstractDaemonTest {
String userRef = RefNames.refsUsers(foo.id);
accountIndexedCounter.clear();
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
grant(allUsers, userRef, Permission.PUSH, false, adminGroup.getGroupUUID());
grantLabel("Code-Review", -2, 2, allUsers, userRef, false, adminGroup.getGroupUUID(), false);
grant(allUsers, userRef, Permission.SUBMIT, false, adminGroup.getGroupUUID());
@@ -1179,7 +1181,8 @@ public class AccountIT extends AbstractDaemonTest {
accountsUpdate.create().update(foo.id, a -> a.setPreferredEmail(noEmail));
accountIndexedCounter.clear();
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
grant(allUsers, userRef, Permission.PUSH, false, adminGroup.getGroupUUID());
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@@ -1214,7 +1217,8 @@ public class AccountIT extends AbstractDaemonTest {
String userRef = RefNames.refsUsers(foo.id);
accountIndexedCounter.clear();
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
grant(allUsers, userRef, Permission.PUSH, false, adminGroup.getGroupUUID());
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);
@@ -1273,7 +1277,8 @@ public class AccountIT extends AbstractDaemonTest {
String userRef = RefNames.refsUsers(foo.id);
accountIndexedCounter.clear();
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
grant(allUsers, userRef, Permission.PUSH, false, adminGroup.getGroupUUID());
TestRepository<InMemoryRepository> allUsersRepo = cloneProject(allUsers);

View File

@@ -1225,7 +1225,7 @@ public class ChangeIT extends AbstractDaemonTest {
Util.allow(
cfg,
Permission.READ,
groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID(),
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null).getGroupUUID(),
"refs/*");
Util.block(cfg, Permission.READ, REGISTERED_USERS, "refs/*");
saveProjectConfig(p, cfg);
@@ -1302,7 +1302,7 @@ public class ChangeIT extends AbstractDaemonTest {
Util.allow(
cfg,
Permission.READ,
groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID(),
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null).getGroupUUID(),
"refs/*");
Util.block(cfg, Permission.READ, REGISTERED_USERS, "refs/*");
saveProjectConfig(p, cfg);
@@ -1349,7 +1349,7 @@ public class ChangeIT extends AbstractDaemonTest {
Util.allow(
cfg,
Permission.READ,
groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID(),
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null).getGroupUUID(),
"refs/*");
Util.block(cfg, Permission.READ, REGISTERED_USERS, "refs/*");
saveProjectConfig(p, cfg);

View File

@@ -19,7 +19,7 @@ import static com.google.common.truth.Truth.assertWithMessage;
import com.google.gerrit.extensions.common.GroupInfo;
import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import java.util.Set;
public class GroupAssert {
@@ -31,7 +31,7 @@ public class GroupAssert {
assertWithMessage("unexpected groups: " + actual).that(actual).isEmpty();
}
public static void assertGroupInfo(AccountGroup group, GroupInfo info) {
public static void assertGroupInfo(InternalGroup group, GroupInfo info) {
if (info.name != null) {
// 'name' is not set if returned in a map
assertThat(info.name).isEqualTo(group.getName());

View File

@@ -47,6 +47,7 @@ import com.google.gerrit.extensions.restapi.Url;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.GroupsUpdate;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.ServerInitiated;
import com.google.gerrit.server.group.SystemGroupBackend;
import com.google.inject.Inject;
@@ -257,13 +258,13 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
public void getGroup() throws Exception {
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup = getFromCache("Administrators");
testGetGroup(adminGroup.getGroupUUID().get(), adminGroup);
testGetGroup(adminGroup.getName(), adminGroup);
testGetGroup(adminGroup.getId().get(), adminGroup);
}
private void testGetGroup(Object id, AccountGroup expectedGroup) throws Exception {
private void testGetGroup(Object id, InternalGroup expectedGroup) throws Exception {
GroupInfo group = gApi.groups().id(id.toString()).get();
assertGroupInfo(expectedGroup, group);
}
@@ -559,7 +560,7 @@ public class GroupsIT extends AbstractDaemonTest {
@Test
public void allGroupInfoFieldsSetCorrectly() throws Exception {
AccountGroup adminGroup = getFromCache("Administrators");
InternalGroup adminGroup = getFromCache("Administrators");
Map<String, GroupInfo> groups = gApi.groups().list().addGroup(adminGroup.getName()).getAsMap();
assertThat(groups).hasSize(1);
assertThat(groups).containsKey("Administrators");
@@ -683,8 +684,8 @@ public class GroupsIT extends AbstractDaemonTest {
assertThat(gApi.groups().id(group).includedGroups()).isEmpty();
}
private AccountGroup getFromCache(String name) throws Exception {
return groupCache.get(new AccountGroup.NameKey(name));
private InternalGroup getFromCache(String name) throws Exception {
return groupCache.get(new AccountGroup.NameKey(name)).orElse(null);
}
private void setCreatedOnToNull(AccountGroup.UUID groupUuid) throws Exception {

View File

@@ -28,6 +28,7 @@ import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.UnprocessableEntityException;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.SystemGroupBackend;
import java.util.List;
import org.junit.Before;
@@ -39,14 +40,15 @@ public class CheckAccessIT extends AbstractDaemonTest {
private Project.NameKey secretProject;
private Project.NameKey secretRefProject;
private TestAccount privilegedUser;
private AccountGroup privilegedGroup;
private InternalGroup privilegedGroup;
@Before
public void setUp() throws Exception {
normalProject = createProject("normal");
secretProject = createProject("secret");
secretRefProject = createProject("secretRef");
privilegedGroup = groupCache.get(new AccountGroup.NameKey(createGroup("privilegedGroup")));
privilegedGroup =
groupCache.get(new AccountGroup.NameKey(createGroup("privilegedGroup"))).orElse(null);
privilegedUser = accountCreator.create("privilegedUser", "snowden@nsa.gov", "Ed Snowden");
gApi.groups().id(privilegedGroup.getGroupUUID().get()).addMembers(privilegedUser.username);

View File

@@ -82,7 +82,7 @@ public class RefAdvertisementIT extends AbstractDaemonTest {
@Before
public void setUp() throws Exception {
admins = groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID();
admins = groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null).getGroupUUID();
setUpPermissions();
setUpChanges();
}

View File

@@ -23,13 +23,14 @@ import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.common.data.GlobalCapability;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.config.ListCaches.CacheInfo;
import com.google.gerrit.server.group.InternalGroup;
import org.junit.Test;
public class FlushCacheIT extends AbstractDaemonTest {
@Test
public void flushCache() throws Exception {
AccountGroup group = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup group = groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
assertWithMessage("Precondition: The group 'Administrators' was loaded by the group cache")
.that(group)
.isNotNull();

View File

@@ -41,6 +41,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.config.AllProjectsNameProvider;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.SystemGroupBackend;
import java.util.HashMap;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
@@ -394,7 +395,8 @@ public class AccessIT extends AbstractDaemonTest {
@Test
public void addNonGlobalCapabilityToGlobalCapabilities() throws Exception {
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
ProjectAccessInput accessInput = newProjectAccessInput();
AccessSectionInfo accessSectionInfo = newAccessSectionInfo();
@@ -423,7 +425,8 @@ public class AccessIT extends AbstractDaemonTest {
@Test
public void removeGlobalCapabilityAsAdmin() throws Exception {
AccountGroup adminGroup = groupCache.get(new AccountGroup.NameKey("Administrators"));
InternalGroup adminGroup =
groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null);
ProjectAccessInput accessInput = newProjectAccessInput();
AccessSectionInfo accessSectionInfo = newAccessSectionInfo();

View File

@@ -191,7 +191,11 @@ public class CreateProjectIT extends AbstractDaemonTest {
in.owners.add(SystemGroupBackend.REGISTERED_USERS.get()); // by UUID
in.owners.add(
Integer.toString(
groupCache.get(new AccountGroup.NameKey("Administrators")).getId().get())); // by ID
groupCache
.get(new AccountGroup.NameKey("Administrators"))
.orElse(null)
.getId()
.get())); // by ID
gApi.projects().create(in);
ProjectState projectState = projectCache.get(new Project.NameKey(newProjectName));
Set<AccountGroup.UUID> expectedOwnerIds = Sets.newHashSetWithExpectedSize(3);
@@ -293,7 +297,7 @@ public class CreateProjectIT extends AbstractDaemonTest {
}
private AccountGroup.UUID groupUuid(String groupName) {
return groupCache.get(new AccountGroup.NameKey(groupName)).getGroupUUID();
return groupCache.get(new AccountGroup.NameKey(groupName)).orElse(null).getGroupUUID();
}
private void assertHead(String projectName, String expectedRef) throws Exception {

View File

@@ -24,7 +24,14 @@ import java.util.Optional;
public interface GroupCache {
AccountGroup get(AccountGroup.Id groupId);
AccountGroup get(AccountGroup.NameKey name);
/**
* Looks up an internal group by its name.
*
* @param name the name of the internal group
* @return an {@code Optional} of the internal group, or an empty {@code Optional} if no internal
* group with this name exists on this server or an error occurred during lookup
*/
Optional<InternalGroup> get(AccountGroup.NameKey name);
/**
* Looks up an internal group by its UUID.
@@ -39,11 +46,10 @@ public interface GroupCache {
ImmutableList<AccountGroup> all();
/** Notify the cache that a new group was constructed. */
void onCreateGroup(AccountGroup.NameKey newGroupName) throws IOException;
void onCreateGroup(AccountGroup group) throws IOException;
void evict(AccountGroup.UUID groupUuid, AccountGroup.Id groupId, AccountGroup.NameKey groupName)
throws IOException;
void evictAfterRename(AccountGroup.NameKey oldName, AccountGroup.NameKey newName)
throws IOException;
void evictAfterRename(AccountGroup.NameKey oldName) throws IOException;
}

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.group.Groups;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gerrit.server.query.group.InternalGroupQuery;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
@@ -59,7 +60,7 @@ public class GroupCacheImpl implements GroupCache {
cache(BYID_NAME, AccountGroup.Id.class, new TypeLiteral<Optional<AccountGroup>>() {})
.loader(ByIdLoader.class);
cache(BYNAME_NAME, String.class, new TypeLiteral<Optional<AccountGroup>>() {})
cache(BYNAME_NAME, String.class, new TypeLiteral<Optional<InternalGroup>>() {})
.loader(ByNameLoader.class);
cache(BYUUID_NAME, String.class, new TypeLiteral<Optional<InternalGroup>>() {})
@@ -72,7 +73,7 @@ public class GroupCacheImpl implements GroupCache {
}
private final LoadingCache<AccountGroup.Id, Optional<AccountGroup>> byId;
private final LoadingCache<String, Optional<AccountGroup>> byName;
private final LoadingCache<String, Optional<InternalGroup>> byName;
private final LoadingCache<String, Optional<InternalGroup>> byUUID;
private final SchemaFactory<ReviewDb> schema;
private final Provider<GroupIndexer> indexer;
@@ -81,7 +82,7 @@ public class GroupCacheImpl implements GroupCache {
@Inject
GroupCacheImpl(
@Named(BYID_NAME) LoadingCache<AccountGroup.Id, Optional<AccountGroup>> byId,
@Named(BYNAME_NAME) LoadingCache<String, Optional<AccountGroup>> byName,
@Named(BYNAME_NAME) LoadingCache<String, Optional<InternalGroup>> byName,
@Named(BYUUID_NAME) LoadingCache<String, Optional<InternalGroup>> byUUID,
SchemaFactory<ReviewDb> schema,
Provider<GroupIndexer> indexer,
@@ -122,27 +123,22 @@ public class GroupCacheImpl implements GroupCache {
}
@Override
public void evictAfterRename(final AccountGroup.NameKey oldName, AccountGroup.NameKey newName)
throws IOException {
public void evictAfterRename(AccountGroup.NameKey oldName) throws IOException {
if (oldName != null) {
byName.invalidate(oldName.get());
}
if (newName != null) {
byName.invalidate(newName.get());
}
indexer.get().index(get(newName).getGroupUUID());
}
@Override
public AccountGroup get(AccountGroup.NameKey name) {
public Optional<InternalGroup> get(AccountGroup.NameKey name) {
if (name == null) {
return null;
return Optional.empty();
}
try {
return byName.get(name.get()).orElse(null);
return byName.get(name.get());
} catch (ExecutionException e) {
log.warn(String.format("Cannot look up group %s by name", name.get()), e);
return null;
return Optional.empty();
}
}
@@ -171,9 +167,8 @@ public class GroupCacheImpl implements GroupCache {
}
@Override
public void onCreateGroup(AccountGroup.NameKey newGroupName) throws IOException {
byName.invalidate(newGroupName.get());
indexer.get().index(get(newGroupName).getGroupUUID());
public void onCreateGroup(AccountGroup group) throws IOException {
indexer.get().index(group.getGroupUUID());
}
private static AccountGroup missing(AccountGroup.Id key) {
@@ -199,21 +194,17 @@ public class GroupCacheImpl implements GroupCache {
}
}
static class ByNameLoader extends CacheLoader<String, Optional<AccountGroup>> {
private final SchemaFactory<ReviewDb> schema;
private final Groups groups;
static class ByNameLoader extends CacheLoader<String, Optional<InternalGroup>> {
private final Provider<InternalGroupQuery> groupQueryProvider;
@Inject
ByNameLoader(SchemaFactory<ReviewDb> sf, Groups groups) {
schema = sf;
this.groups = groups;
ByNameLoader(Provider<InternalGroupQuery> groupQueryProvider) {
this.groupQueryProvider = groupQueryProvider;
}
@Override
public Optional<AccountGroup> load(String name) throws Exception {
try (ReviewDb db = schema.open()) {
return groups.getGroup(db, new AccountGroup.NameKey(name));
}
public Optional<InternalGroup> load(String name) throws Exception {
return groupQueryProvider.get().byName(new AccountGroup.NameKey(name));
}
}

View File

@@ -16,8 +16,10 @@ package com.google.gerrit.server.args4j;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.group.InternalGroup;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import java.util.Optional;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser;
import org.kohsuke.args4j.OptionDef;
@@ -41,11 +43,11 @@ public class AccountGroupIdHandler extends OptionHandler<AccountGroup.Id> {
@Override
public final int parseArguments(Parameters params) throws CmdLineException {
final String n = params.getParameter(0);
final AccountGroup group = groupCache.get(new AccountGroup.NameKey(n));
if (group == null) {
Optional<InternalGroup> group = groupCache.get(new AccountGroup.NameKey(n));
if (!group.isPresent()) {
throw new CmdLineException(owner, "Group \"" + n + "\" does not exist");
}
setter.addValue(group.getId());
setter.addValue(group.get().getId());
return 1;
}

View File

@@ -21,7 +21,6 @@ import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.reviewdb.client.AccountGroupById;
import com.google.gerrit.reviewdb.client.AccountGroupMember;
import com.google.gerrit.reviewdb.client.AccountGroupName;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.OrmDuplicateKeyException;
import com.google.gwtorm.server.OrmException;
@@ -93,25 +92,6 @@ public class Groups {
}
}
/**
* Returns the {@code AccountGroup} for the specified name if it exists.
*
* @param db the {@code ReviewDb} instance to use for lookups
* @param groupName the name of the group
* @return the found {@code AccountGroup} if it exists, or else an empty {@code Optional}
* @throws OrmException if the group couldn't be retrieved from ReviewDb
*/
public Optional<AccountGroup> getGroup(ReviewDb db, AccountGroup.NameKey groupName)
throws OrmException {
AccountGroupName accountGroupName = db.accountGroupNames().get(groupName);
if (accountGroupName == null) {
return Optional.empty();
}
AccountGroup.Id groupId = accountGroupName.getId();
return Optional.ofNullable(db.accountGroups().get(groupId));
}
public Stream<AccountGroup> getAll(ReviewDb db) throws OrmException {
return Streams.stream(db.accountGroups().all());
}

View File

@@ -135,7 +135,7 @@ public class GroupsUpdate {
throws OrmException, IOException {
addNewGroup(db, group);
addNewGroupMembers(db, group, memberIds);
groupCache.onCreateGroup(group.getNameKey());
groupCache.onCreateGroup(group);
}
/**
@@ -221,8 +221,8 @@ public class GroupsUpdate {
db.accountGroupNames().deleteKeys(ImmutableList.of(oldName));
groupCache.evictAfterRename(oldName);
groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
groupCache.evictAfterRename(oldName, newName);
@SuppressWarnings("unused")
Future<?> possiblyIgnoredError =

View File

@@ -19,10 +19,12 @@ import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountGroup;
import java.io.Serializable;
import java.sql.Timestamp;
@AutoValue
public abstract class InternalGroup {
public abstract class InternalGroup implements Serializable {
private static final long serialVersionUID = 1L;
public static InternalGroup create(
AccountGroup accountGroup,

View File

@@ -0,0 +1,63 @@
// Copyright (C) 2017 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server.query.group;
import static com.google.common.collect.ImmutableList.toImmutableList;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.gerrit.index.IndexConfig;
import com.google.gerrit.index.query.InternalQuery;
import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.index.group.GroupIndexCollection;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.util.List;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Query wrapper for the group index.
*
* <p>Instances are one-time-use. Other singleton classes should inject a Provider rather than
* holding on to a single instance.
*/
public class InternalGroupQuery extends InternalQuery<InternalGroup> {
private static final Logger log = LoggerFactory.getLogger(InternalGroupQuery.class);
@Inject
InternalGroupQuery(
GroupQueryProcessor queryProcessor, GroupIndexCollection indexes, IndexConfig indexConfig) {
super(queryProcessor, indexes, indexConfig);
}
public Optional<InternalGroup> byName(AccountGroup.NameKey groupName) throws OrmException {
List<InternalGroup> groups = query(GroupPredicates.name(groupName.get()));
if (groups.isEmpty()) {
return Optional.empty();
}
if (groups.size() == 1) {
return Optional.of(Iterables.getOnlyElement(groups));
}
ImmutableList<AccountGroup.UUID> groupUuids =
groups.stream().map(InternalGroup::getGroupUUID).collect(toImmutableList());
log.warn(String.format("Ambiguous group name '%s' for groups %s.", groupName, groupUuids));
return Optional.empty();
}
}

View File

@@ -90,7 +90,7 @@ public class CommitsCollectionTest {
// registered user.
// See AccountManager#create().
accountManager.authenticate(AuthRequest.forUser("admin")).getAccountId();
admins = groupCache.get(new AccountGroup.NameKey("Administrators")).getGroupUUID();
admins = groupCache.get(new AccountGroup.NameKey("Administrators")).orElse(null).getGroupUUID();
setUpPermissions();
Account.Id userId = accountManager.authenticate(AuthRequest.forUser("user")).getAccountId();

View File

@@ -23,6 +23,7 @@ import com.google.gerrit.reviewdb.client.AccountGroup;
import com.google.gerrit.server.account.AccountLoader;
import com.google.gerrit.server.account.GroupCache;
import com.google.gerrit.server.account.GroupControl;
import com.google.gerrit.server.group.InternalGroup;
import com.google.gerrit.server.group.ListMembers;
import com.google.gerrit.server.ioutil.ColumnFormatter;
import com.google.gerrit.sshd.CommandMetaData;
@@ -31,6 +32,7 @@ import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import java.io.PrintWriter;
import java.util.List;
import java.util.Optional;
import org.kohsuke.args4j.Argument;
/** Implements a command that allows the user to see the members of a group. */
@@ -68,16 +70,16 @@ public class ListMembersCommand extends SshCommand {
}
void display(PrintWriter writer) throws OrmException {
AccountGroup group = groupCache.get(new AccountGroup.NameKey(name));
Optional<InternalGroup> group = groupCache.get(new AccountGroup.NameKey(name));
String errorText = "Group not found or not visible\n";
if (group == null) {
if (!group.isPresent()) {
writer.write(errorText);
writer.flush();
return;
}
List<AccountInfo> members = apply(group.getGroupUUID());
List<AccountInfo> members = apply(group.get().getGroupUUID());
ColumnFormatter formatter = new ColumnFormatter(writer, '\t');
formatter.addColumn("id");
formatter.addColumn("username");