Merge "Add support for NoteDb" into stable-2.15
diff --git a/README.md b/README.md
index 1ed0bf5..e14491a 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,6 @@
# Rename project plugin for Gerrit Code Review
-This plugin currently supports Gerrit version 2.14.X and 2.15.X with changes in reviewDb, noteDB is not yet supported.
+This plugin currently supports Gerrit version 2.14.X and 2.15.X with changes in reviewDb.
+Also supported is the noteDb alternative for Gerrit versions 2.15.X and above.
For more information, see: `src/main/resources/Documentation/about.md`
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
index e6a320d..b3519fa 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/RenameProject.java
@@ -167,7 +167,8 @@
}
}
- List<Change.Id> getChanges(ProjectResource rsrc, ProgressMonitor pm) throws OrmException {
+ List<Change.Id> getChanges(ProjectResource rsrc, ProgressMonitor pm)
+ throws OrmException, IOException {
pm.beginTask("Retrieving the list of changes from DB");
Project.NameKey oldProjectKey = rsrc.getControl().getProject().getNameKey();
return dbHandler.getChangeIds(oldProjectKey);
diff --git a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
index fb6c69f..2d123a5 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/renameproject/database/DatabaseRenameHandler.java
@@ -23,6 +23,10 @@
import com.google.gerrit.server.account.WatchConfig.Accessor;
import com.google.gerrit.server.account.WatchConfig.NotifyType;
import com.google.gerrit.server.account.WatchConfig.ProjectWatchKey;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.notedb.ChangeNotes.Factory.ChangeNotesResult;
+import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.query.account.InternalAccountQuery;
import com.google.gwtorm.jdbc.JdbcSchema;
import com.google.gwtorm.server.OrmException;
@@ -37,9 +41,11 @@
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Stream;
import org.eclipse.jgit.errors.ConfigInvalidException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,22 +55,35 @@
private static final Logger log = LoggerFactory.getLogger(DatabaseRenameHandler.class);
private final SchemaFactory<ReviewDb> schemaFactory;
+ private final ChangeNotes.Factory schemaFactoryNoteDb;
+ private final GitRepositoryManager repoManager;
private final Provider<InternalAccountQuery> accountQueryProvider;
private final Provider<Accessor> watchConfig;
+ private NotesMigration migration;
@Inject
public DatabaseRenameHandler(
SchemaFactory<ReviewDb> schemaFactory,
+ ChangeNotes.Factory schemaFactoryNoteDb,
+ GitRepositoryManager repoManager,
+ NotesMigration migration,
Provider<InternalAccountQuery> accountQueryProvider,
Provider<WatchConfig.Accessor> watchConfig) {
this.accountQueryProvider = accountQueryProvider;
this.watchConfig = watchConfig;
this.schemaFactory = schemaFactory;
+ this.schemaFactoryNoteDb = schemaFactoryNoteDb;
+ this.repoManager = repoManager;
+ this.migration = migration;
}
- public List<Change.Id> getChangeIds(Project.NameKey oldProjectKey) throws OrmException {
+ public List<Change.Id> getChangeIds(Project.NameKey oldProjectKey)
+ throws OrmException, IOException {
log.debug("Starting to retrieve changes from the DB for project {}", oldProjectKey.get());
- return getChangeIdsFromReviewDb(oldProjectKey, schemaFactory.open());
+ ReviewDb db = schemaFactory.open();
+ return (isNoteDb())
+ ? getChangeIdsFromNoteDb(oldProjectKey, db)
+ : getChangeIdsFromReviewDb(oldProjectKey, db);
}
private List<Change.Id> getChangeIdsFromReviewDb(Project.NameKey oldProjectKey, ReviewDb db)
@@ -80,7 +99,7 @@
changeIds.add(changeId);
}
log.debug(
- "Number of changes related to the project {} are {}",
+ "Number of changes in reviewDb related to the project {} are {}",
oldProjectKey.get(),
changeIds.size());
return changeIds;
@@ -89,14 +108,38 @@
}
}
+ private List<Change.Id> getChangeIdsFromNoteDb(Project.NameKey oldProjectKey, ReviewDb db)
+ throws IOException {
+ List<Change.Id> changeIds = new ArrayList<>();
+ Stream<ChangeNotesResult> changes =
+ schemaFactoryNoteDb.scan(repoManager.openRepository(oldProjectKey), db, oldProjectKey);
+ Iterator<ChangeNotesResult> iterator = changes.iterator();
+ while (iterator.hasNext()) {
+ ChangeNotesResult change = iterator.next();
+ changeIds.add(change.id());
+ }
+ log.debug(
+ "Number of changes in noteDb related to the project {} are {}",
+ oldProjectKey.get(),
+ changeIds.size());
+ return changeIds;
+ }
+
+ private boolean isNoteDb() {
+ return migration.disableChangeReviewDb();
+ }
+
public List<Change.Id> rename(
List<Change.Id> changes,
Project.NameKey oldProjectKey,
Project.NameKey newProjectKey,
ProgressMonitor pm)
- throws OrmException {
+ throws OrmException, IOException {
pm.beginTask("Updating changes in the database");
- return renameInReviewDb(changes, oldProjectKey, newProjectKey, schemaFactory.open());
+ ReviewDb db = schemaFactory.open();
+ return (isNoteDb())
+ ? renameInNoteDb(changes, oldProjectKey, newProjectKey)
+ : renameInReviewDb(changes, oldProjectKey, newProjectKey, db);
}
private List<Change.Id> renameInReviewDb(
@@ -109,7 +152,7 @@
try (Statement stmt = conn.createStatement()) {
conn.setAutoCommit(false);
try {
- log.debug("Updating the changes in the DB related to project {}", oldProjectKey.get());
+ log.debug("Updating the changes in reviewDb related to project {}", oldProjectKey.get());
for (Change.Id cd : changes) {
stmt.addBatch(
"update changes set dest_project_name='"
@@ -122,7 +165,7 @@
updateWatchEntries(oldProjectKey, newProjectKey);
conn.commit();
log.debug(
- "Successfully updated the changes in the DB related to project {}",
+ "Successfully updated the changes in reviewDb related to project {}",
oldProjectKey.get());
return changes;
} finally {
@@ -131,7 +174,7 @@
} catch (SQLException e) {
try {
log.error(
- "Failed to update changes in the DB for the project {}, rolling back the operation.",
+ "Failed to update changes in reviewDb for the project {}, rolling back the operation.",
oldProjectKey.get());
conn.rollback();
} catch (SQLException ex) {
@@ -141,6 +184,30 @@
}
}
+ private List<Change.Id> renameInNoteDb(
+ List<Change.Id> changes, Project.NameKey oldProjectKey, Project.NameKey newProjectKey)
+ throws OrmException {
+ log.debug("Updating the changes in noteDb related to project {}", oldProjectKey.get());
+ try {
+ updateWatchEntries(oldProjectKey, newProjectKey);
+ } catch (OrmException e) {
+ log.error(
+ "Failed to update changes in noteDb for the project {}, rolling back the operation.",
+ oldProjectKey.get());
+ try {
+ updateWatchEntries(newProjectKey, oldProjectKey);
+ } catch (OrmException ex) {
+ log.error("Failed to revert watched projects after catching {}", e.getMessage());
+ throw ex;
+ }
+ throw e;
+ }
+
+ log.debug(
+ "Successfully updated the changes in noteDb related to project {}", oldProjectKey.get());
+ return changes;
+ }
+
private void updateWatchEntries(Project.NameKey oldProjectKey, Project.NameKey newProjectKey)
throws OrmException {
for (AccountState a : accountQueryProvider.get().byWatchedProject(oldProjectKey)) {