Fall-back to loading groups from ReviewDb if group index is not available

In Gerrit slaves indexes are not available and hence trying to query
groups from the group index fails. This prevents loading of accounts via
the account cache. As result of this the account cache returns inactive
account instances to represent the missing accounts. This prevents users
from authenticating with SSH and SSH requests are rejected with
"Permission denied (publickey)."

To fix this fall-back to loading groups from ReviewDb if the group index
is not available. This reverts change I86f85b6e41 partially.

Bug: Issue 7340
Change-Id: I196c313f75f0a2f2bcb97445347bfe7113283198
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2017-10-05 09:55:22 +02:00
parent 8dac226947
commit b70b92ca57
3 changed files with 44 additions and 3 deletions

View File

@@ -224,7 +224,8 @@ public class AccountCacheImpl implements AccountCache {
private ImmutableSet<AccountGroup.UUID> getGroupsWithMember(ReviewDb db, Account.Id memberId)
throws OrmException {
Stream<InternalGroup> internalGroupStream;
if (groupIndexProvider.get().getSchema().hasField(GroupField.MEMBER)) {
if (groupIndexProvider.get() != null
&& groupIndexProvider.get().getSchema().hasField(GroupField.MEMBER)) {
internalGroupStream = groupQueryProvider.get().byMember(memberId).stream();
} else {
internalGroupStream =

View File

@@ -21,6 +21,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
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.GroupIndexCollection;
import com.google.gerrit.server.index.group.GroupIndexer;
import com.google.gerrit.server.query.group.InternalGroupQuery;
import com.google.gwtorm.server.SchemaFactory;
@@ -147,17 +148,33 @@ public class GroupCacheImpl implements GroupCache {
}
static class ByIdLoader extends CacheLoader<AccountGroup.Id, Optional<InternalGroup>> {
private final SchemaFactory<ReviewDb> schema;
private final Groups groups;
private final boolean hasGroupIndex;
private final Provider<InternalGroupQuery> groupQueryProvider;
@Inject
ByIdLoader(Provider<InternalGroupQuery> groupQueryProvider) {
ByIdLoader(
SchemaFactory<ReviewDb> schema,
Groups groups,
GroupIndexCollection groupIndexCollection,
Provider<InternalGroupQuery> groupQueryProvider) {
this.schema = schema;
this.groups = groups;
this.hasGroupIndex = groupIndexCollection.getSearchIndex() != null;
this.groupQueryProvider = groupQueryProvider;
}
@Override
public Optional<InternalGroup> load(AccountGroup.Id key) throws Exception {
if (hasGroupIndex) {
return groupQueryProvider.get().byId(key);
}
try (ReviewDb db = schema.open()) {
return groups.getGroup(db, key);
}
}
}
static class ByNameLoader extends CacheLoader<String, Optional<InternalGroup>> {

View File

@@ -46,6 +46,29 @@ import java.util.stream.Stream;
@Singleton
public class Groups {
/**
* Returns the {@code AccountGroup} for the specified ID if it exists.
*
* @param db the {@code ReviewDb} instance to use for lookups
* @param groupId the ID 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<InternalGroup> getGroup(ReviewDb db, AccountGroup.Id groupId)
throws OrmException, NoSuchGroupException {
Optional<AccountGroup> accountGroup = Optional.ofNullable(db.accountGroups().get(groupId));
if (!accountGroup.isPresent()) {
return Optional.empty();
}
AccountGroup.UUID groupUuid = accountGroup.get().getGroupUUID();
ImmutableSet<Account.Id> members = getMembers(db, groupUuid).collect(toImmutableSet());
ImmutableSet<AccountGroup.UUID> subgroups =
getSubgroups(db, groupUuid).collect(toImmutableSet());
return accountGroup.map(group -> InternalGroup.create(group, members, subgroups));
}
/**
* Returns the {@code InternalGroup} for the specified UUID if it exists.
*