Fix to reindex a change via SSH: get from DB/Notes instead of Lucene When reindexing a change via SSH, we need to avoid using the Lucene index to decode the change-id into a ChangeControl. The rationale stays in the typical use-case of the reindex itself: if we need to recreate the Lucene index entry we cannot rely on a Lucene query to find it. Change-Id: I34dbf535241a604089ddb5d3af570c4b97c5cc2e
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/ChangeArgumentParser.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/ChangeArgumentParser.java index f3e9a98..d636628 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/ChangeArgumentParser.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/ChangeArgumentParser.java
@@ -14,6 +14,10 @@ package com.google.gerrit.sshd; +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.base.Predicates; +import com.google.common.collect.FluentIterable; import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Project; import com.google.gerrit.reviewdb.server.ReviewDb; @@ -21,13 +25,16 @@ import com.google.gerrit.server.CurrentUser; import com.google.gerrit.server.change.ChangeResource; import com.google.gerrit.server.change.ChangesCollection; +import com.google.gerrit.server.notedb.ChangeNotes; import com.google.gerrit.server.project.ChangeControl; +import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.sshd.BaseCommand.UnloggedFailure; import com.google.gwtorm.server.OrmException; import com.google.inject.Inject; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -36,16 +43,22 @@ private final ChangesCollection changesCollection; private final ChangeFinder changeFinder; private final ReviewDb db; + private final ChangeNotes.Factory changeNotesFactory; + private final ChangeControl.GenericFactory changeControlFactory; @Inject ChangeArgumentParser(CurrentUser currentUser, ChangesCollection changesCollection, ChangeFinder changeFinder, - ReviewDb db) { + ReviewDb db, + ChangeNotes.Factory changeNotesFactory, + ChangeControl.GenericFactory changeControlFactory) { this.currentUser = currentUser; this.changesCollection = changesCollection; this.changeFinder = changeFinder; this.db = db; + this.changeNotesFactory = changeNotesFactory; + this.changeControlFactory = changeControlFactory; } public void addChange(String id, Map<Change.Id, ChangeResource> changes) @@ -55,7 +68,16 @@ public void addChange(String id, Map<Change.Id, ChangeResource> changes, ProjectControl projectControl) throws UnloggedFailure, OrmException { - List<ChangeControl> matched = changeFinder.find(id, currentUser); + addChange(id, changes, projectControl, true); + } + + public void addChange(String id, Map<Change.Id, ChangeResource> changes, + ProjectControl projectControl, boolean useIndex) throws UnloggedFailure, + OrmException { + List<ChangeControl> matched = + useIndex ? + changeFinder.find(id, currentUser) : + changeFromNotesFactory(id, currentUser); List<ChangeControl> toAdd = new ArrayList<>(changes.size()); for (ChangeControl ctl : matched) { if (!changes.containsKey(ctl.getId()) @@ -74,6 +96,27 @@ changes.put(ctl.getId(), changesCollection.parse(ctl)); } + private List<ChangeControl> changeFromNotesFactory(String id, + final CurrentUser currentUser) throws OrmException { + List<ChangeNotes> changes = + changeNotesFactory.create(db, Arrays.asList(Change.Id.parse(id))); + return FluentIterable.from(changes) + .transform(new Function<ChangeNotes, ChangeControl>() { + @Override + public ChangeControl apply(ChangeNotes changeNote) { + return controlForChange(changeNote, currentUser); + } + }).filter(Predicates.notNull()).toList(); + } + + private ChangeControl controlForChange(ChangeNotes change, CurrentUser user) { + try { + return changeControlFactory.controlFor(change, user); + } catch (NoSuchChangeException e) { + return null; + } + } + private boolean inProject(ProjectControl projectControl, Project project) { if (projectControl != null) { return projectControl.getProject().getNameKey().equals(project.getNameKey());
diff --git a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java index 94f35a8..85b1f32 100644 --- a/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java +++ b/gerrit-sshd/src/main/java/com/google/gerrit/sshd/commands/IndexChangesCommand.java
@@ -42,7 +42,7 @@ usage = "changes to index") void addChange(String token) { try { - changeArgumentParser.addChange(token, changes); + changeArgumentParser.addChange(token, changes, null, false); } catch (UnloggedFailure e) { throw new IllegalArgumentException(e.getMessage(), e); } catch (OrmException e) {