Propagate failure if reading external IDs from NoteDb fails
When reading external IDs from NoteDb was enabled
ExternalIds#byAccount(...) and ExternalIds#byEmail(...) returned an
empty set if reading from NoteDb failed.
Change-Id: I453beea3827d65a64d80eb2d9d9842602c15b27e
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
index b203b83..42709af 100644
--- a/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
+++ b/gerrit-acceptance-tests/src/test/java/com/google/gerrit/acceptance/rest/account/ExternalIdIT.java
@@ -25,6 +25,7 @@
import com.github.rholder.retry.RetryerBuilder;
import com.github.rholder.retry.StopStrategies;
import com.google.gerrit.acceptance.AbstractDaemonTest;
+import com.google.gerrit.acceptance.GerritConfig;
import com.google.gerrit.acceptance.PushOneCommit;
import com.google.gerrit.acceptance.RestResponse;
import com.google.gerrit.acceptance.Sandboxed;
@@ -35,6 +36,7 @@
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.account.externalids.DisabledExternalIdCache;
import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.account.externalids.ExternalIdReader;
import com.google.gerrit.server.account.externalids.ExternalIds;
import com.google.gerrit.server.account.externalids.ExternalIdsUpdate;
import com.google.gerrit.server.config.AllUsersName;
@@ -54,15 +56,18 @@
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.notes.NoteMap;
+import org.eclipse.jgit.revwalk.RevWalk;
import org.junit.Test;
@Sandboxed
public class ExternalIdIT extends AbstractDaemonTest {
@Inject private AllUsersName allUsers;
-
@Inject private ExternalIdsUpdate.Server extIdsUpdate;
-
@Inject private ExternalIds externalIds;
+ @Inject private ExternalIdReader externalIdReader;
@Test
public void getExternalIDs() throws Exception {
@@ -267,4 +272,40 @@
ExternalId extId = externalIds.get(db, extIdKey);
assertThat(extId.accountId()).isEqualTo(accountId);
}
+
+ @Test
+ @GerritConfig(name = "user.readExternalIdsFromGit", value = "true")
+ public void byAccountFailIfReadingExternalIdsFails() throws Exception {
+ externalIdReader.setFailOnLoad(true);
+
+ // update external ID branch so that external IDs need to be reloaded
+ insertExtIdBehindGerritsBack(ExternalId.create("foo", "bar", admin.id));
+
+ exception.expect(IOException.class);
+ externalIds.byAccount(db, admin.id);
+ }
+
+ @Test
+ @GerritConfig(name = "user.readExternalIdsFromGit", value = "true")
+ public void byEmailFailIfReadingExternalIdsFails() throws Exception {
+ externalIdReader.setFailOnLoad(true);
+
+ // update external ID branch so that external IDs need to be reloaded
+ insertExtIdBehindGerritsBack(ExternalId.create("foo", "bar", admin.id));
+
+ exception.expect(IOException.class);
+ externalIds.byEmail(db, admin.email);
+ }
+
+ private void insertExtIdBehindGerritsBack(ExternalId extId) throws Exception {
+ try (Repository repo = repoManager.openRepository(allUsers);
+ RevWalk rw = new RevWalk(repo);
+ ObjectInserter ins = repo.newObjectInserter()) {
+ ObjectId rev = ExternalIdReader.readRevision(repo);
+ NoteMap noteMap = ExternalIdReader.readNoteMap(rw, rev);
+ ExternalIdsUpdate.insert(rw, ins, noteMap, extId);
+ ExternalIdsUpdate.commit(
+ repo, rw, ins, rev, noteMap, "insert new ID", serverIdent.get(), serverIdent.get());
+ }
+ }
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
index 7fb61fc..6713021 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdCacheImpl.java
@@ -28,7 +28,6 @@
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import java.io.IOException;
-import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.Lock;
@@ -222,8 +221,7 @@
try {
return extIdsByAccount.get(externalIdReader.readRevision()).get(accountId);
} catch (ExecutionException e) {
- log.warn("Cannot list external ids by account", e);
- return Collections.emptySet();
+ throw new IOException("Cannot list external ids by account", e);
}
}
@@ -237,8 +235,7 @@
.filter(e -> email.equals(e.email()))
.collect(toSet());
} catch (ExecutionException e) {
- log.warn("Cannot list external ids by email", e);
- return Collections.emptySet();
+ throw new IOException("Cannot list external ids by email", e);
}
}
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdReader.java b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdReader.java
index 7b607dc..d9f0c00 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdReader.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/account/externalids/ExternalIdReader.java
@@ -16,6 +16,7 @@
import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.RefNames;
@@ -76,6 +77,7 @@
private final boolean readFromGit;
private final GitRepositoryManager repoManager;
private final AllUsersName allUsersName;
+ private boolean failOnLoad = false;
@Inject
ExternalIdReader(
@@ -85,6 +87,11 @@
this.allUsersName = allUsersName;
}
+ @VisibleForTesting
+ public void setFailOnLoad(boolean failOnLoad) {
+ this.failOnLoad = failOnLoad;
+ }
+
boolean readFromGit() {
return readFromGit;
}
@@ -97,6 +104,8 @@
/** Reads and returns all external IDs. */
Set<ExternalId> all(ReviewDb db) throws IOException, OrmException {
+ checkReadEnabled();
+
if (readFromGit) {
try (Repository repo = repoManager.openRepository(allUsersName)) {
return all(repo, readRevision(repo));
@@ -111,6 +120,8 @@
* branch.
*/
Set<ExternalId> all(ObjectId rev) throws IOException {
+ checkReadEnabled();
+
try (Repository repo = repoManager.openRepository(allUsersName)) {
return all(repo, rev);
}
@@ -142,6 +153,8 @@
@Nullable
ExternalId get(ReviewDb db, ExternalId.Key key)
throws IOException, ConfigInvalidException, OrmException {
+ checkReadEnabled();
+
if (readFromGit) {
try (Repository repo = repoManager.openRepository(allUsersName);
RevWalk rw = new RevWalk(repo)) {
@@ -159,6 +172,8 @@
/** Reads and returns the specified external ID from the given revision. */
@Nullable
ExternalId get(ExternalId.Key key, ObjectId rev) throws IOException, ConfigInvalidException {
+ checkReadEnabled();
+
if (rev.equals(ObjectId.zeroId())) {
return null;
}
@@ -181,4 +196,10 @@
rw.getObjectReader().open(noteMap.get(noteId), OBJ_BLOB).getCachedBytes(MAX_NOTE_SZ);
return ExternalId.parse(noteId.name(), raw);
}
+
+ private void checkReadEnabled() throws IOException {
+ if (failOnLoad) {
+ throw new IOException("Reading from external IDs is disabled");
+ }
+ }
}