Resolve changes by project and number in AddReviewers

When a new change is pushed and change indexing runs asynchronously
(`index.indexChangesAsync = true`), the `reviewers` plugin immediately
runs `AddReviewers` to assign reviewers from `reviewers.config`. Because
`AddReviewers` looks up the change by change number alone
(`gApi.changes().id(changeInfo._number)`), Gerrit has to query the
change index to find which project the change belongs to. On Patchset 1,
if background indexing has not finished yet, the lookup fails with
`ResourceNotFoundException` and no reviewers are added.

Pass both the project name and change number
(`gApi.changes().id(changeInfo.project, changeInfo._number)`) in
`AddReviewers` so Gerrit reads the change directly from primary storage
(NoteDb) instead of querying the change index. This follows the
deprecation of `Changes#id(int)` in favor of `Changes#id(String, int)`
(see I7ddde61db, I0ccd90cf6, and I305ff2d2c).

Change-Id: Ia2df288f0a82fc3adec6712695e2cbe55a07b7ae
diff --git a/src/main/java/com/googlesource/gerrit/plugins/reviewers/AddReviewers.java b/src/main/java/com/googlesource/gerrit/plugins/reviewers/AddReviewers.java
index 099db37..3e4f8c7 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/reviewers/AddReviewers.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/reviewers/AddReviewers.java
@@ -74,7 +74,7 @@
       // TODO(davido): Switch back to using changes API again,
       // when it supports batch mode for adding reviewers
       Set<Account.Id> existingReviewers =
-          gApi.changes().id(changeInfo._number).reviewers().stream()
+          gApi.changes().id(changeInfo.project, changeInfo._number).reviewers().stream()
               .map(r -> Account.id(r._accountId))
               .collect(Collectors.toSet());
       /* Don't add, or change state of, already existing reviewers. */
@@ -105,7 +105,7 @@
         input.reviewer = account.toString();
         in.reviewers.add(input);
       }
-      gApi.changes().id(changeInfo._number).current().review(in);
+      gApi.changes().id(changeInfo.project, changeInfo._number).current().review(in);
     } catch (RestApiException e) {
       logger.atSevere().withCause(e).log("Couldn't add reviewers to the change");
     }
diff --git a/src/test/java/com/googlesource/gerrit/plugins/reviewers/ReviewersIT.java b/src/test/java/com/googlesource/gerrit/plugins/reviewers/ReviewersIT.java
index 6e4df58..48c61b2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/reviewers/ReviewersIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/reviewers/ReviewersIT.java
@@ -55,6 +55,25 @@
   }
 
   @Test
+  public void addReviewersWhenChangeNotYetIndexed() throws Exception {
+    TestAccount user2 = accountCreator.user2();
+    PushOneCommit.Result r = createChange();
+    String changeId = project.get() + "~" + r.getChange().getId().get();
+    ChangeInfo changeInfo =
+        gApi.changes().id(project.get(), r.getChange().getId().get()).get();
+    indexer.delete(project, r.getChange().getId());
+
+    plugin
+        .getSysInjector()
+        .getInstance(AddReviewers.Factory.class)
+        .create(changeInfo, ImmutableSet.of(user.id()), ImmutableSet.of(user2.id()))
+        .run();
+
+    assertThat(reviewersFor(changeId)).containsExactly(user.id());
+    assertThat(ccsFor(changeId)).containsExactly(user2.id());
+  }
+
+  @Test
   public void addReviewerMatchingReviewerAndCc() throws Exception {
     TestAccount user2 = accountCreator.user2();
     createFilters(filter("*").cc(user).cc(user2), filter("^a.txt").reviewer(user2));