Merge branch 'stable-2.16' into stable-3.0

* stable-2.16:
  ExportReviewNotes: Use @CommandMetaData to define command name and description

Change-Id: I9b6e2c52c3ca63a6af485c24fd86c616868bb0a2
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
index d2a8c1d..903aa9c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/CreateReviewNotes.java
@@ -18,18 +18,18 @@
 import com.google.gerrit.common.data.LabelType;
 import com.google.gerrit.common.data.LabelTypes;
 import com.google.gerrit.extensions.registration.DynamicItem;
+import com.google.gerrit.git.LockFailureException;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.PatchSet;
 import com.google.gerrit.reviewdb.client.PatchSetApproval;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.ApprovalsUtil;
 import com.google.gerrit.server.GerritPersonIdent;
+import com.google.gerrit.server.PatchSetUtil;
 import com.google.gerrit.server.account.AccountCache;
 import com.google.gerrit.server.account.AccountState;
 import com.google.gerrit.server.config.AnonymousCowardName;
 import com.google.gerrit.server.config.UrlFormatter;
-import com.google.gerrit.server.git.LockFailureException;
 import com.google.gerrit.server.git.NotesBranchUtil;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.project.NoSuchChangeException;
@@ -37,7 +37,6 @@
 import com.google.gerrit.server.project.ProjectState;
 import com.google.gerrit.server.query.change.ChangeData;
 import com.google.gerrit.server.query.change.InternalChangeQuery;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
 import com.google.inject.assistedinject.Assisted;
@@ -62,7 +61,7 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   interface Factory {
-    CreateReviewNotes create(ReviewDb reviewDb, Project.NameKey project, Repository git);
+    CreateReviewNotes create(Project.NameKey project, Repository git);
   }
 
   private static final String REFS_NOTES_REVIEW = "refs/notes/review";
@@ -76,7 +75,7 @@
   private final NotesBranchUtil.Factory notesBranchUtilFactory;
   private final Provider<InternalChangeQuery> queryProvider;
   private final DynamicItem<UrlFormatter> urlFormatter;
-  private final ReviewDb reviewDb;
+  private final PatchSetUtil psUtil;
   private final Project.NameKey project;
   private final Repository git;
 
@@ -95,7 +94,7 @@
       NotesBranchUtil.Factory notesBranchUtilFactory,
       Provider<InternalChangeQuery> queryProvider,
       DynamicItem<UrlFormatter> urlFormatter,
-      @Assisted ReviewDb reviewDb,
+      PatchSetUtil psUtil,
       @Assisted Project.NameKey project,
       @Assisted Repository git) {
     this.gerritServerIdent = gerritIdent;
@@ -116,14 +115,14 @@
     this.notesBranchUtilFactory = notesBranchUtilFactory;
     this.queryProvider = queryProvider;
     this.urlFormatter = urlFormatter;
-    this.reviewDb = reviewDb;
+    this.psUtil = psUtil;
     this.project = project;
     this.git = git;
   }
 
   void createNotes(
       String branch, ObjectId oldObjectId, ObjectId newObjectId, ProgressMonitor monitor)
-      throws OrmException, IOException {
+      throws IOException {
     if (ObjectId.zeroId().equals(newObjectId)) {
       return;
     }
@@ -149,7 +148,7 @@
       for (RevCommit c : rw) {
         PatchSet ps = loadPatchSet(c, branch);
         if (ps != null) {
-          ChangeNotes notes = notesFactory.create(reviewDb, project, ps.getId().getParentKey());
+          ChangeNotes notes = notesFactory.create(project, ps.getId().changeId());
           ObjectId content = createNoteContent(notes, ps);
           if (content != null) {
             monitor.update(1);
@@ -164,8 +163,7 @@
     }
   }
 
-  void createNotes(List<ChangeNotes> notes, ProgressMonitor monitor)
-      throws OrmException, IOException {
+  void createNotes(List<ChangeNotes> notes, ProgressMonitor monitor) throws IOException {
     try (RevWalk rw = new RevWalk(git)) {
       if (monitor == null) {
         monitor = NullProgressMonitor.INSTANCE;
@@ -173,7 +171,7 @@
 
       for (ChangeNotes cn : notes) {
         monitor.update(1);
-        PatchSet ps = reviewDb.patchSets().get(cn.getChange().currentPatchSetId());
+        PatchSet ps = psUtil.current(cn);
         ObjectId commitId = ObjectId.fromString(ps.getRevision().get());
         RevCommit commit = rw.parseCommit(commitId);
         getNotes().set(commitId, createNoteContent(cn, ps));
@@ -223,8 +221,7 @@
     }
   }
 
-  private ObjectId createNoteContent(ChangeNotes notes, PatchSet ps)
-      throws OrmException, IOException {
+  private ObjectId createNoteContent(ChangeNotes notes, PatchSet ps) throws IOException {
     HeaderFormatter fmt = new HeaderFormatter(gerritServerIdent.getTimeZone(), anonymousCowardName);
     if (ps != null) {
       try {
@@ -237,7 +234,7 @@
     return null;
   }
 
-  private PatchSet loadPatchSet(RevCommit c, String destBranch) throws OrmException {
+  private PatchSet loadPatchSet(RevCommit c, String destBranch) {
     String hash = c.name();
     for (ChangeData cd : queryProvider.get().byBranchCommit(project.get(), destBranch, hash)) {
       for (PatchSet ps : cd.patchSets()) {
@@ -250,7 +247,7 @@
   }
 
   private void createCodeReviewNote(ChangeNotes notes, PatchSet ps, HeaderFormatter fmt)
-      throws OrmException, NoSuchChangeException {
+      throws NoSuchChangeException {
     // This races with the label normalization/writeback done by MergeOp. It may
     // repeat some work, but results should be identical except in the case of
     // an additional race with a permissions change.
@@ -258,7 +255,7 @@
     // commit time so we will be able to skip this normalization step.
     Change change = notes.getChange();
     PatchSetApproval submit = null;
-    for (PatchSetApproval a : approvalsUtil.byPatchSet(reviewDb, notes, ps.getId(), null, null)) {
+    for (PatchSetApproval a : approvalsUtil.byPatchSet(notes, ps.getId(), null, null)) {
       if (a.getValue() == 0) {
         // Ignore 0 values.
       } else if (a.isLegacySubmit()) {
@@ -283,10 +280,10 @@
 
     UrlFormatter uf = urlFormatter.get();
     if (uf != null && uf.getWebUrl().isPresent()) {
-      fmt.appendReviewedOn(uf, notes.getChange().getProject(), ps.getId().getParentKey());
+      fmt.appendReviewedOn(uf, notes.getChange().getProject(), ps.getId().changeId());
     }
     fmt.appendProject(project.get());
-    fmt.appendBranch(change.getDest().get());
+    fmt.appendBranch(change.getDest().branch());
   }
 
   private ObjectInserter getInserter() {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
index b714a73..1d512c6 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/ExportReviewNotes.java
@@ -21,17 +21,13 @@
 import com.google.common.collect.Maps;
 import com.google.common.collect.MultimapBuilder;
 import com.google.gerrit.extensions.restapi.RestApiException;
-import com.google.gerrit.reviewdb.client.Change;
 import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.notedb.ChangeNotes;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.UpdateException;
 import com.google.gerrit.sshd.CommandMetaData;
 import com.google.gerrit.sshd.SshCommand;
-import com.google.gwtorm.server.OrmException;
-import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
 import java.io.IOException;
 import java.util.List;
@@ -52,8 +48,6 @@
 
   @Inject private GitRepositoryManager gitManager;
 
-  @Inject private SchemaFactory<ReviewDb> database;
-
   @Inject private CreateReviewNotes.Factory reviewNotesFactory;
 
   @Inject private ChangeNotes.Factory notesFactory;
@@ -82,24 +76,22 @@
   }
 
   private ListMultimap<Project.NameKey, ChangeNotes> mergedChanges() {
-    try (ReviewDb db = database.open()) {
+    try {
       return MultimapBuilder.hashKeys()
           .arrayListValues()
-          .build(
-              notesFactory.create(
-                  db, notes -> notes.getChange().getStatus() == Change.Status.MERGED));
-    } catch (OrmException | IOException e) {
+          .build(notesFactory.create(notes -> notes.getChange().isMerged()));
+    } catch (IOException e) {
       stderr.println("Cannot read changes from database " + e.getMessage());
       return ImmutableListMultimap.of();
     }
   }
 
-  private void export(ReviewDb db, Project.NameKey project, List<ChangeNotes> notes)
+  private void export(Project.NameKey project, List<ChangeNotes> notes)
       throws RestApiException, UpdateException {
     retryHelper.execute(
         updateFactory -> {
           try (Repository git = gitManager.openRepository(project)) {
-            CreateReviewNotes crn = reviewNotesFactory.create(db, project, git);
+            CreateReviewNotes crn = reviewNotesFactory.create(project, git);
             crn.createNotes(notes, monitor);
             crn.commitNotes();
           } catch (RepositoryNotFoundException e) {
@@ -132,12 +124,12 @@
   private class Worker extends Thread {
     @Override
     public void run() {
-      try (ReviewDb db = database.open()) {
+      try {
         for (; ; ) {
           Map.Entry<Project.NameKey, List<ChangeNotes>> next = next();
           if (next != null) {
             try {
-              export(db, next.getKey(), next.getValue());
+              export(next.getKey(), next.getValue());
             } catch (RestApiException | UpdateException e) {
               stderr.println(e.getMessage());
             }
@@ -145,8 +137,6 @@
             break;
           }
         }
-      } catch (OrmException e) {
-        stderr.println(e.getMessage());
       } finally {
         monitor.endWorker();
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
index d8e0e83..3365abe 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewnotes/RefUpdateListener.java
@@ -19,14 +19,12 @@
 import com.google.gerrit.extensions.restapi.RestApiException;
 import com.google.gerrit.reviewdb.client.Project;
 import com.google.gerrit.reviewdb.client.RefNames;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.config.GerritServerConfig;
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.gerrit.server.git.ProjectRunnable;
 import com.google.gerrit.server.git.WorkQueue;
 import com.google.gerrit.server.update.RetryHelper;
 import com.google.gerrit.server.update.UpdateException;
-import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
 import java.util.concurrent.Future;
 import org.eclipse.jgit.lib.Config;
@@ -37,7 +35,6 @@
   private static final FluentLogger logger = FluentLogger.forEnclosingClass();
 
   private final CreateReviewNotes.Factory reviewNotesFactory;
-  private final SchemaFactory<ReviewDb> schema;
   private final GitRepositoryManager repoManager;
   private final WorkQueue workQueue;
   private final RetryHelper retryHelper;
@@ -46,13 +43,11 @@
   @Inject
   RefUpdateListener(
       CreateReviewNotes.Factory reviewNotesFactory,
-      SchemaFactory<ReviewDb> schema,
       GitRepositoryManager repoManager,
       WorkQueue workQueue,
       RetryHelper retryHelper,
       @GerritServerConfig Config config) {
     this.reviewNotesFactory = reviewNotesFactory;
-    this.schema = schema;
     this.repoManager = repoManager;
     this.workQueue = workQueue;
     this.retryHelper = retryHelper;
@@ -70,7 +65,7 @@
 
           @Override
           public Project.NameKey getProjectNameKey() {
-            return new Project.NameKey(e.getProjectName());
+            return Project.nameKey(e.getProjectName());
           }
 
           @Override
@@ -103,10 +98,9 @@
     try {
       retryHelper.execute(
           updateFactory -> {
-            Project.NameKey projectName = new Project.NameKey(e.getProjectName());
-            try (Repository git = repoManager.openRepository(projectName);
-                ReviewDb reviewDb = schema.open()) {
-              CreateReviewNotes crn = reviewNotesFactory.create(reviewDb, projectName, git);
+            Project.NameKey projectName = Project.nameKey(e.getProjectName());
+            try (Repository git = repoManager.openRepository(projectName)) {
+              CreateReviewNotes crn = reviewNotesFactory.create(projectName, git);
               crn.createNotes(
                   e.getRefName(),
                   ObjectId.fromString(e.getOldObjectId()),
diff --git a/src/main/resources/Documentation/cmd-export.md b/src/main/resources/Documentation/cmd-export.md
index 011e51a..1472578 100644
--- a/src/main/resources/Documentation/cmd-export.md
+++ b/src/main/resources/Documentation/cmd-export.md
@@ -19,8 +19,7 @@
 each merged change.
 
 This task can take quite some time, but can run in the background
-concurrently to the server if the database is MySQL or PostgreSQL.
-If the database is H2, this task must be run by itself.
+concurrently to the server.
 
 ACCESS
 ------