AccountCacheImpl#ByNameLoader: Use account index to lookup usernames
If available, use the account index to find accounts by username. This
is a preparation for moving the external ids from ReviewDb into git.
Change-Id: I8fe3adc0a65e90e3e7a21641cfca7352c46a458f
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java
index cd172a7..2deae3f 100644
--- a/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java
+++ b/gerrit-gpg/src/main/java/com/google/gerrit/gpg/server/PostGpgKeys.java
@@ -294,12 +294,7 @@
msg.append("GPG key ").append(externalId)
.append(" associated with multiple accounts: ");
Joiner.on(", ").appendTo(msg,
- Lists.transform(accountStates, new Function<AccountState, String>() {
- @Override
- public String apply(AccountState accountState) {
- return accountState.getAccount().getId().toString();
- }
- }));
+ Lists.transform(accountStates, AccountState.ACCOUNT_ID_FUNCTION));
log.error(msg.toString());
throw new IllegalStateException(msg.toString());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountCacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountCacheImpl.java
index af0ee4c..02e8698 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountCacheImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountCacheImpl.java
@@ -14,10 +14,12 @@
package com.google.gerrit.server.account;
+import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.client.GeneralPreferencesInfo;
import com.google.gerrit.reviewdb.client.Account;
@@ -27,7 +29,9 @@
import com.google.gerrit.reviewdb.client.AccountProjectWatch;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.cache.CacheModule;
+import com.google.gerrit.server.index.account.AccountIndexCollection;
import com.google.gerrit.server.index.account.AccountIndexer;
+import com.google.gerrit.server.query.account.InternalAccountQuery;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.SchemaFactory;
import com.google.inject.Inject;
@@ -45,6 +49,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
@@ -209,19 +214,42 @@
static class ByNameLoader extends CacheLoader<String, Optional<Account.Id>> {
private final SchemaFactory<ReviewDb> schema;
+ private final AccountIndexCollection accountIndexes;
+ private final Provider<InternalAccountQuery> accountQueryProvider;
@Inject
- ByNameLoader(final SchemaFactory<ReviewDb> sf) {
+ ByNameLoader(SchemaFactory<ReviewDb> sf,
+ AccountIndexCollection accountIndexes,
+ Provider<InternalAccountQuery> accountQueryProvider) {
this.schema = sf;
+ this.accountIndexes = accountIndexes;
+ this.accountQueryProvider = accountQueryProvider;
}
@Override
public Optional<Account.Id> load(String username) throws Exception {
- try (ReviewDb db = schema.open()) {
- final AccountExternalId.Key key = new AccountExternalId.Key( //
+ AccountExternalId.Key key = new AccountExternalId.Key( //
AccountExternalId.SCHEME_USERNAME, //
username);
- final AccountExternalId id = db.accountExternalIds().get(key);
+ if (accountIndexes.getSearchIndex() != null) {
+ List<AccountState> accountStates =
+ accountQueryProvider.get().byExternalId(key.get());
+ if (accountStates.size() == 1) {
+ return Optional.of(accountStates.get(0).getAccount().getId());
+ } else if (accountStates.size() > 0) {
+ StringBuilder msg = new StringBuilder();
+ msg.append("Ambiguous username ")
+ .append(username)
+ .append("for accounts: ");
+ Joiner.on(", ").appendTo(msg, Lists.transform(accountStates,
+ AccountState.ACCOUNT_ID_FUNCTION));
+ log.warn(msg.toString());
+ }
+ return Optional.absent();
+ }
+
+ try (ReviewDb db = schema.open()) {
+ AccountExternalId id = db.accountExternalIds().get(key);
if (id != null) {
return Optional.of(id.getAccountId());
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountState.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountState.java
index 145f34b..a9eab0a 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountState.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/AccountState.java
@@ -17,6 +17,7 @@
import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_MAILTO;
import static com.google.gerrit.reviewdb.client.AccountExternalId.SCHEME_USERNAME;
+import com.google.common.base.Function;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.gerrit.common.Nullable;
@@ -32,6 +33,14 @@
import java.util.Set;
public class AccountState {
+ public static Function<AccountState, Account.Id> ACCOUNT_ID_FUNCTION =
+ new Function<AccountState, Account.Id>() {
+ @Override
+ public Account.Id apply(AccountState in) {
+ return in.getAccount().getId();
+ }
+ };
+
private final Account account;
private final Set<AccountGroup.UUID> internalGroups;
private final Collection<AccountExternalId> externalIds;