Remove NotesMigration from AbstractChangeNotes.Args
Eliminate non-NoteDb conditions from subclasses. The only remaining thing that's not quite related to the NoteDb migration is the failOnLoadForTest mechanism, which was wedged into the NotesMigration since it was a convenient piece of global state. Replace this with an equally ugly piece of global state, a simple AtomicBoolean, punting for now on a better approach. Change-Id: I186744413ef9b263c5c6cabe19c3e5297230974f
This commit is contained in:
@@ -112,6 +112,7 @@ import com.google.gerrit.server.index.change.ChangeIndex;
|
|||||||
import com.google.gerrit.server.index.change.ChangeIndexCollection;
|
import com.google.gerrit.server.index.change.ChangeIndexCollection;
|
||||||
import com.google.gerrit.server.index.change.ChangeIndexer;
|
import com.google.gerrit.server.index.change.ChangeIndexer;
|
||||||
import com.google.gerrit.server.index.group.GroupIndexer;
|
import com.google.gerrit.server.index.group.GroupIndexer;
|
||||||
|
import com.google.gerrit.server.notedb.AbstractChangeNotes;
|
||||||
import com.google.gerrit.server.notedb.ChangeNoteUtil;
|
import com.google.gerrit.server.notedb.ChangeNoteUtil;
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
import com.google.gerrit.server.notedb.MutableNotesMigration;
|
import com.google.gerrit.server.notedb.MutableNotesMigration;
|
||||||
@@ -293,6 +294,7 @@ public abstract class AbstractDaemonTest {
|
|||||||
@Inject private AccountIndexer accountIndexer;
|
@Inject private AccountIndexer accountIndexer;
|
||||||
@Inject private Groups groups;
|
@Inject private Groups groups;
|
||||||
@Inject private GroupIndexer groupIndexer;
|
@Inject private GroupIndexer groupIndexer;
|
||||||
|
@Inject private AbstractChangeNotes.Args changeNotesArgs;
|
||||||
|
|
||||||
private ProjectResetter resetter;
|
private ProjectResetter resetter;
|
||||||
private List<Repository> toClose;
|
private List<Repository> toClose;
|
||||||
@@ -837,12 +839,12 @@ public abstract class AbstractDaemonTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Context disableDb() {
|
protected Context disableDb() {
|
||||||
notesMigration.setFailOnLoadForTest(true);
|
changeNotesArgs.failOnLoadForTest.set(true);
|
||||||
return atrScope.disableDb();
|
return atrScope.disableDb();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void enableDb(Context preDisableContext) {
|
protected void enableDb(Context preDisableContext) {
|
||||||
notesMigration.setFailOnLoadForTest(false);
|
changeNotesArgs.failOnLoadForTest.set(false);
|
||||||
atrScope.set(preDisableContext);
|
atrScope.set(preDisableContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -14,7 +14,6 @@
|
|||||||
|
|
||||||
package com.google.gerrit.server.notedb;
|
package com.google.gerrit.server.notedb;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
|
||||||
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
|
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
@@ -34,6 +33,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Provider;
|
import com.google.inject.Provider;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.Ref;
|
import org.eclipse.jgit.lib.Ref;
|
||||||
@@ -44,8 +44,10 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@Singleton
|
@Singleton
|
||||||
public static class Args {
|
public static class Args {
|
||||||
|
// TODO(dborowitz): Some less smelly way of disabling NoteDb in tests.
|
||||||
|
public final AtomicBoolean failOnLoadForTest;
|
||||||
|
|
||||||
final GitRepositoryManager repoManager;
|
final GitRepositoryManager repoManager;
|
||||||
final NotesMigration migration;
|
|
||||||
final AllUsersName allUsers;
|
final AllUsersName allUsers;
|
||||||
final ChangeNoteJson changeNoteJson;
|
final ChangeNoteJson changeNoteJson;
|
||||||
final LegacyChangeNoteRead legacyChangeNoteRead;
|
final LegacyChangeNoteRead legacyChangeNoteRead;
|
||||||
@@ -60,15 +62,14 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
@Inject
|
@Inject
|
||||||
Args(
|
Args(
|
||||||
GitRepositoryManager repoManager,
|
GitRepositoryManager repoManager,
|
||||||
NotesMigration migration,
|
|
||||||
AllUsersName allUsers,
|
AllUsersName allUsers,
|
||||||
ChangeNoteJson changeNoteJson,
|
ChangeNoteJson changeNoteJson,
|
||||||
LegacyChangeNoteRead legacyChangeNoteRead,
|
LegacyChangeNoteRead legacyChangeNoteRead,
|
||||||
NoteDbMetrics metrics,
|
NoteDbMetrics metrics,
|
||||||
Provider<ReviewDb> db,
|
Provider<ReviewDb> db,
|
||||||
Provider<ChangeNotesCache> cache) {
|
Provider<ChangeNotesCache> cache) {
|
||||||
|
this.failOnLoadForTest = new AtomicBoolean();
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.migration = migration;
|
|
||||||
this.allUsers = allUsers;
|
this.allUsers = allUsers;
|
||||||
this.legacyChangeNoteRead = legacyChangeNoteRead;
|
this.legacyChangeNoteRead = legacyChangeNoteRead;
|
||||||
this.changeNoteJson = changeNoteJson;
|
this.changeNoteJson = changeNoteJson;
|
||||||
@@ -132,8 +133,7 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkState(args.migration.readChanges(), "NoteDb is required to read changes");
|
if (args.failOnLoadForTest.get()) {
|
||||||
if (args.migration.failOnLoadForTest()) {
|
|
||||||
throw new OrmException("Reading from NoteDb is disabled");
|
throw new OrmException("Reading from NoteDb is disabled");
|
||||||
}
|
}
|
||||||
try (Timer1.Context timer = args.metrics.readLatency.start(CHANGES);
|
try (Timer1.Context timer = args.metrics.readLatency.start(CHANGES);
|
||||||
@@ -181,8 +181,6 @@ public abstract class AbstractChangeNotes<T> {
|
|||||||
public ObjectId loadRevision() throws OrmException {
|
public ObjectId loadRevision() throws OrmException {
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
return getRevision();
|
return getRevision();
|
||||||
} else if (!args.migration.readChanges()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
try (Repository repo = args.repoManager.openRepository(getProjectName())) {
|
try (Repository repo = args.repoManager.openRepository(getProjectName())) {
|
||||||
Ref ref = repo.getRefDatabase().exactRef(getRefName());
|
Ref ref = repo.getRefDatabase().exactRef(getRefName());
|
||||||
|
@@ -120,9 +120,6 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
throws OrmException {
|
throws OrmException {
|
||||||
Change change = readOneReviewDbChange(db, changeId);
|
Change change = readOneReviewDbChange(db, changeId);
|
||||||
if (change == null) {
|
if (change == null) {
|
||||||
if (!args.migration.readChanges()) {
|
|
||||||
throw new NoSuchChangeException(changeId);
|
|
||||||
}
|
|
||||||
// Change isn't in ReviewDb, but its primary storage might be in NoteDb.
|
// Change isn't in ReviewDb, but its primary storage might be in NoteDb.
|
||||||
// Prepopulate the change exists with proper noteDbState field.
|
// Prepopulate the change exists with proper noteDbState field.
|
||||||
change = newNoteDbOnlyChange(project, changeId);
|
change = newNoteDbOnlyChange(project, changeId);
|
||||||
@@ -159,10 +156,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
Change change = readOneReviewDbChange(db, changeId);
|
Change change = readOneReviewDbChange(db, changeId);
|
||||||
|
|
||||||
if (change == null) {
|
if (change == null) {
|
||||||
if (args.migration.readChanges()) {
|
return newNoteDbOnlyChange(project, changeId);
|
||||||
return newNoteDbOnlyChange(project, changeId);
|
|
||||||
}
|
|
||||||
throw new NoSuchChangeException(changeId);
|
|
||||||
}
|
}
|
||||||
checkArgument(
|
checkArgument(
|
||||||
change.getProject().equals(project),
|
change.getProject().equals(project),
|
||||||
@@ -198,33 +192,15 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
return new ChangeNotes(args, change, true, refs).load();
|
return new ChangeNotes(args, change, true, refs).load();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(ekempin): Remove when database backend is deleted
|
|
||||||
/**
|
|
||||||
* Instantiate ChangeNotes for a change that has been loaded by a batch read from the database.
|
|
||||||
*/
|
|
||||||
private ChangeNotes createFromChangeOnlyWhenNoteDbDisabled(Change change) throws OrmException {
|
|
||||||
checkState(
|
|
||||||
!args.migration.readChanges(),
|
|
||||||
"do not call createFromChangeWhenNoteDbDisabled when NoteDb is enabled");
|
|
||||||
return new ChangeNotes(args, change).load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ChangeNotes> create(ReviewDb db, Collection<Change.Id> changeIds)
|
public List<ChangeNotes> create(ReviewDb db, Collection<Change.Id> changeIds)
|
||||||
throws OrmException {
|
throws OrmException {
|
||||||
List<ChangeNotes> notes = new ArrayList<>();
|
List<ChangeNotes> notes = new ArrayList<>();
|
||||||
if (args.migration.readChanges()) {
|
for (Change.Id changeId : changeIds) {
|
||||||
for (Change.Id changeId : changeIds) {
|
try {
|
||||||
try {
|
notes.add(createChecked(changeId));
|
||||||
notes.add(createChecked(changeId));
|
} catch (NoSuchChangeException e) {
|
||||||
} catch (NoSuchChangeException e) {
|
// Ignore missing changes to match Access#get(Iterable) behavior.
|
||||||
// Ignore missing changes to match Access#get(Iterable) behavior.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Change c : ReviewDbUtil.unwrapDb(db).changes().get(changeIds)) {
|
|
||||||
notes.add(createFromChangeOnlyWhenNoteDbDisabled(c));
|
|
||||||
}
|
}
|
||||||
return notes;
|
return notes;
|
||||||
}
|
}
|
||||||
@@ -236,28 +212,16 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
Predicate<ChangeNotes> predicate)
|
Predicate<ChangeNotes> predicate)
|
||||||
throws OrmException {
|
throws OrmException {
|
||||||
List<ChangeNotes> notes = new ArrayList<>();
|
List<ChangeNotes> notes = new ArrayList<>();
|
||||||
if (args.migration.readChanges()) {
|
for (Change.Id cid : changeIds) {
|
||||||
for (Change.Id cid : changeIds) {
|
try {
|
||||||
try {
|
ChangeNotes cn = create(db, project, cid);
|
||||||
ChangeNotes cn = create(db, project, cid);
|
if (cn.getChange() != null && predicate.test(cn)) {
|
||||||
if (cn.getChange() != null && predicate.test(cn)) {
|
|
||||||
notes.add(cn);
|
|
||||||
}
|
|
||||||
} catch (NoSuchChangeException e) {
|
|
||||||
// Match ReviewDb behavior, returning not found; maybe the caller learned about it from
|
|
||||||
// a dangling patch set ref or something.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Change c : ReviewDbUtil.unwrapDb(db).changes().get(changeIds)) {
|
|
||||||
if (c != null && project.equals(c.getDest().getParentKey())) {
|
|
||||||
ChangeNotes cn = createFromChangeOnlyWhenNoteDbDisabled(c);
|
|
||||||
if (predicate.test(cn)) {
|
|
||||||
notes.add(cn);
|
notes.add(cn);
|
||||||
}
|
}
|
||||||
|
} catch (NoSuchChangeException e) {
|
||||||
|
// Match ReviewDb behavior, returning not found; maybe the caller learned about it from
|
||||||
|
// a dangling patch set ref or something.
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return notes;
|
return notes;
|
||||||
@@ -267,22 +231,13 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
ReviewDb db, Predicate<ChangeNotes> predicate) throws IOException, OrmException {
|
ReviewDb db, Predicate<ChangeNotes> predicate) throws IOException, OrmException {
|
||||||
ListMultimap<Project.NameKey, ChangeNotes> m =
|
ListMultimap<Project.NameKey, ChangeNotes> m =
|
||||||
MultimapBuilder.hashKeys().arrayListValues().build();
|
MultimapBuilder.hashKeys().arrayListValues().build();
|
||||||
if (args.migration.readChanges()) {
|
for (Project.NameKey project : projectCache.all()) {
|
||||||
for (Project.NameKey project : projectCache.all()) {
|
try (Repository repo = args.repoManager.openRepository(project)) {
|
||||||
try (Repository repo = args.repoManager.openRepository(project)) {
|
scan(repo, project)
|
||||||
scan(repo, project)
|
.filter(r -> !r.error().isPresent())
|
||||||
.filter(r -> !r.error().isPresent())
|
.map(ChangeNotesResult::notes)
|
||||||
.map(ChangeNotesResult::notes)
|
.filter(predicate)
|
||||||
.filter(predicate)
|
.forEach(n -> m.put(n.getProjectName(), n));
|
||||||
.forEach(n -> m.put(n.getProjectName(), n));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (Change change : ReviewDbUtil.unwrapDb(db).changes().all()) {
|
|
||||||
ChangeNotes notes = createFromChangeOnlyWhenNoteDbDisabled(change);
|
|
||||||
if (predicate.test(notes)) {
|
|
||||||
m.put(change.getProject(), notes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ImmutableListMultimap.copyOf(m);
|
return ImmutableListMultimap.copyOf(m);
|
||||||
@@ -594,9 +549,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
protected void onLoad(LoadHandle handle) throws NoSuchChangeException, IOException {
|
protected void onLoad(LoadHandle handle) throws NoSuchChangeException, IOException {
|
||||||
ObjectId rev = handle.id();
|
ObjectId rev = handle.id();
|
||||||
if (rev == null) {
|
if (rev == null) {
|
||||||
if (args.migration.readChanges()
|
if (PrimaryStorage.of(change) == PrimaryStorage.NOTE_DB && shouldExist) {
|
||||||
&& PrimaryStorage.of(change) == PrimaryStorage.NOTE_DB
|
|
||||||
&& shouldExist) {
|
|
||||||
throw new NoSuchChangeException(getChangeId());
|
throw new NoSuchChangeException(getChangeId());
|
||||||
}
|
}
|
||||||
loadDefaults();
|
loadDefaults();
|
||||||
|
Reference in New Issue
Block a user