Merge "Fix GitOverHttpServlet compilation on servlet API 2.5"
diff --git a/java/com/google/gerrit/pgm/init/GroupsOnInit.java b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
index 8e06aa1..584d8af 100644
--- a/java/com/google/gerrit/pgm/init/GroupsOnInit.java
+++ b/java/com/google/gerrit/pgm/init/GroupsOnInit.java
@@ -25,7 +25,6 @@
 import com.google.gerrit.pgm.init.api.InitFlags;
 import com.google.gerrit.reviewdb.client.Account;
 import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.GerritPersonIdentProvider;
 import com.google.gerrit.server.config.AllUsersName;
 import com.google.gerrit.server.config.GerritServerIdProvider;
@@ -37,7 +36,6 @@
 import com.google.gerrit.server.group.db.GroupConfig;
 import com.google.gerrit.server.group.db.GroupNameNotes;
 import com.google.gerrit.server.group.db.InternalGroupUpdate;
-import com.google.gwtorm.server.OrmException;
 import com.google.inject.Inject;
 import java.io.File;
 import java.io.IOException;
@@ -54,9 +52,8 @@
 /**
  * A database accessor for calls related to groups.
  *
- * <p>All calls which read or write group related details to the database <strong>during
- * init</strong> (either ReviewDb or NoteDb) are gathered here. For non-init cases, use {@code
- * Groups} or {@code GroupsUpdate} instead.
+ * <p>All calls which read or write group related details to the NoteDb <strong>during init</strong>
+ * are gathered here. For non-init cases, use {@code Groups} or {@code GroupsUpdate} instead.
  *
  * <p>All methods of this class refer to <em>internal</em> groups.
  */
@@ -76,16 +73,14 @@
   /**
    * Returns the {@code AccountGroup} for the specified {@code GroupReference}.
    *
-   * @param db the {@code ReviewDb} instance to use for lookups
    * @param groupReference the {@code GroupReference} of the group
    * @return the {@code InternalGroup} represented by the {@code GroupReference}
-   * @throws OrmException if the group couldn't be retrieved from ReviewDb
    * @throws IOException if an error occurs while reading from NoteDb
    * @throws ConfigInvalidException if the data in NoteDb is in an incorrect format
    * @throws NoSuchGroupException if a group with such a name doesn't exist
    */
-  public InternalGroup getExistingGroup(ReviewDb db, GroupReference groupReference)
-      throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
+  public InternalGroup getExistingGroup(GroupReference groupReference)
+      throws NoSuchGroupException, IOException, ConfigInvalidException {
     File allUsersRepoPath = getPathToAllUsersRepository();
     if (allUsersRepoPath != null) {
       try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
@@ -102,14 +97,11 @@
   /**
    * Returns {@code GroupReference}s for all internal groups.
    *
-   * @param db the {@code ReviewDb} instance to use for lookups
    * @return a stream of the {@code GroupReference}s of all internal groups
-   * @throws OrmException if an error occurs while reading from ReviewDb
    * @throws IOException if an error occurs while reading from NoteDb
    * @throws ConfigInvalidException if the data in NoteDb is in an incorrect format
    */
-  public Stream<GroupReference> getAllGroupReferences(ReviewDb db)
-      throws OrmException, IOException, ConfigInvalidException {
+  public Stream<GroupReference> getAllGroupReferences() throws IOException, ConfigInvalidException {
     File allUsersRepoPath = getPathToAllUsersRepository();
     if (allUsersRepoPath != null) {
       try (Repository allUsersRepo = new FileRepository(allUsersRepoPath)) {
@@ -126,14 +118,12 @@
    * <p><strong>Note</strong>: This method doesn't check whether the account exists! It also doesn't
    * update the account index!
    *
-   * @param db the {@code ReviewDb} instance to update
    * @param groupUuid the UUID of the group
    * @param account the account to add
-   * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
    * @throws NoSuchGroupException if the specified group doesn't exist
    */
-  public void addGroupMember(ReviewDb db, AccountGroup.UUID groupUuid, Account account)
-      throws OrmException, NoSuchGroupException, IOException, ConfigInvalidException {
+  public void addGroupMember(AccountGroup.UUID groupUuid, Account account)
+      throws NoSuchGroupException, IOException, ConfigInvalidException {
     File allUsersRepoPath = getPathToAllUsersRepository();
     if (allUsersRepoPath != null) {
       try (Repository repository = new FileRepository(allUsersRepoPath)) {
diff --git a/java/com/google/gerrit/pgm/init/InitAdminUser.java b/java/com/google/gerrit/pgm/init/InitAdminUser.java
index 4b435de..f19cf39 100644
--- a/java/com/google/gerrit/pgm/init/InitAdminUser.java
+++ b/java/com/google/gerrit/pgm/init/InitAdminUser.java
@@ -26,7 +26,6 @@
 import com.google.gerrit.pgm.init.api.InitStep;
 import com.google.gerrit.pgm.init.api.SequencesOnInit;
 import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.account.AccountSshKey;
 import com.google.gerrit.server.account.AccountState;
 import com.google.gerrit.server.account.externalids.ExternalId;
@@ -37,7 +36,6 @@
 import com.google.gerrit.server.index.group.GroupIndex;
 import com.google.gerrit.server.index.group.GroupIndexCollection;
 import com.google.gerrit.server.util.time.TimeUtil;
-import com.google.gwtorm.server.SchemaFactory;
 import com.google.inject.Inject;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -57,7 +55,6 @@
   private final ExternalIdsOnInit externalIds;
   private final SequencesOnInit sequencesOnInit;
   private final GroupsOnInit groupsOnInit;
-  private SchemaFactory<ReviewDb> dbFactory;
   private AccountIndexCollection accountIndexCollection;
   private GroupIndexCollection groupIndexCollection;
 
@@ -84,11 +81,6 @@
   @Override
   public void run() {}
 
-  @Inject(optional = true)
-  void set(SchemaFactory<ReviewDb> dbFactory) {
-    this.dbFactory = dbFactory;
-  }
-
   @Inject
   void set(AccountIndexCollection accountIndexCollection) {
     this.accountIndexCollection = accountIndexCollection;
@@ -106,58 +98,56 @@
       return;
     }
 
-    try (ReviewDb db = dbFactory.open()) {
-      if (!accounts.hasAnyAccount()) {
-        ui.header("Gerrit Administrator");
-        if (ui.yesno(true, "Create administrator user")) {
-          Account.Id id = new Account.Id(sequencesOnInit.nextAccountId());
-          String username = ui.readString("admin", "username");
-          String name = ui.readString("Administrator", "name");
-          String httpPassword = ui.readString("secret", "HTTP password");
-          AccountSshKey sshKey = readSshKey(id);
-          String email = readEmail(sshKey);
+    if (!accounts.hasAnyAccount()) {
+      ui.header("Gerrit Administrator");
+      if (ui.yesno(true, "Create administrator user")) {
+        Account.Id id = new Account.Id(sequencesOnInit.nextAccountId());
+        String username = ui.readString("admin", "username");
+        String name = ui.readString("Administrator", "name");
+        String httpPassword = ui.readString("secret", "HTTP password");
+        AccountSshKey sshKey = readSshKey(id);
+        String email = readEmail(sshKey);
 
-          List<ExternalId> extIds = new ArrayList<>(2);
-          extIds.add(ExternalId.createUsername(username, id, httpPassword));
+        List<ExternalId> extIds = new ArrayList<>(2);
+        extIds.add(ExternalId.createUsername(username, id, httpPassword));
 
-          if (email != null) {
-            extIds.add(ExternalId.createEmail(id, email));
-          }
-          externalIds.insert("Add external IDs for initial admin user", extIds);
+        if (email != null) {
+          extIds.add(ExternalId.createEmail(id, email));
+        }
+        externalIds.insert("Add external IDs for initial admin user", extIds);
 
-          Account a = new Account(id, TimeUtil.nowTs());
-          a.setFullName(name);
-          a.setPreferredEmail(email);
-          accounts.insert(a);
+        Account a = new Account(id, TimeUtil.nowTs());
+        a.setFullName(name);
+        a.setPreferredEmail(email);
+        accounts.insert(a);
 
-          // Only two groups should exist at this point in time and hence iterating over all of them
-          // is cheap.
-          Optional<GroupReference> adminGroupReference =
-              groupsOnInit
-                  .getAllGroupReferences(db)
-                  .filter(group -> group.getName().equals("Administrators"))
-                  .findAny();
-          if (!adminGroupReference.isPresent()) {
-            throw new NoSuchGroupException("Administrators");
-          }
-          GroupReference adminGroup = adminGroupReference.get();
-          groupsOnInit.addGroupMember(db, adminGroup.getUUID(), a);
+        // Only two groups should exist at this point in time and hence iterating over all of them
+        // is cheap.
+        Optional<GroupReference> adminGroupReference =
+            groupsOnInit
+                .getAllGroupReferences()
+                .filter(group -> group.getName().equals("Administrators"))
+                .findAny();
+        if (!adminGroupReference.isPresent()) {
+          throw new NoSuchGroupException("Administrators");
+        }
+        GroupReference adminGroup = adminGroupReference.get();
+        groupsOnInit.addGroupMember(adminGroup.getUUID(), a);
 
-          if (sshKey != null) {
-            VersionedAuthorizedKeysOnInit authorizedKeys = authorizedKeysFactory.create(id).load();
-            authorizedKeys.addKey(sshKey.sshPublicKey());
-            authorizedKeys.save("Add SSH key for initial admin user\n");
-          }
+        if (sshKey != null) {
+          VersionedAuthorizedKeysOnInit authorizedKeys = authorizedKeysFactory.create(id).load();
+          authorizedKeys.addKey(sshKey.sshPublicKey());
+          authorizedKeys.save("Add SSH key for initial admin user\n");
+        }
 
-          AccountState as = AccountState.forAccount(new AllUsersName(allUsers.get()), a, extIds);
-          for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
-            accountIndex.replace(as);
-          }
+        AccountState as = AccountState.forAccount(new AllUsersName(allUsers.get()), a, extIds);
+        for (AccountIndex accountIndex : accountIndexCollection.getWriteIndexes()) {
+          accountIndex.replace(as);
+        }
 
-          InternalGroup adminInternalGroup = groupsOnInit.getExistingGroup(db, adminGroup);
-          for (GroupIndex groupIndex : groupIndexCollection.getWriteIndexes()) {
-            groupIndex.replace(adminInternalGroup);
-          }
+        InternalGroup adminInternalGroup = groupsOnInit.getExistingGroup(adminGroup);
+        for (GroupIndex groupIndex : groupIndexCollection.getWriteIndexes()) {
+          groupIndex.replace(adminInternalGroup);
         }
       }
     }
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDb.java b/java/com/google/gerrit/reviewdb/server/ReviewDb.java
index 6668727..90cd066 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDb.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDb.java
@@ -14,7 +14,6 @@
 
 package com.google.gerrit.reviewdb.server;
 
-import com.google.gerrit.reviewdb.client.AccountGroup;
 import com.google.gerrit.reviewdb.client.Change;
 import com.google.gwtorm.server.OrmException;
 import com.google.gwtorm.server.Relation;
@@ -91,11 +90,6 @@
 
   int FIRST_GROUP_ID = 1;
 
-  /** Next unique id for a {@link AccountGroup}. */
-  @Sequence(startWith = FIRST_GROUP_ID)
-  @Deprecated
-  int nextAccountGroupId() throws OrmException;
-
   int FIRST_CHANGE_ID = 1;
 
   /**
diff --git a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
index 27a4e29..c420254 100644
--- a/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
+++ b/java/com/google/gerrit/reviewdb/server/ReviewDbWrapper.java
@@ -136,12 +136,6 @@
 
   @Override
   @SuppressWarnings("deprecation")
-  public int nextAccountGroupId() throws OrmException {
-    return delegate.nextAccountGroupId();
-  }
-
-  @Override
-  @SuppressWarnings("deprecation")
   public int nextChangeId() throws OrmException {
     return delegate.nextChangeId();
   }
diff --git a/java/com/google/gerrit/server/Sequences.java b/java/com/google/gerrit/server/Sequences.java
index fcf0759..70a02a8 100644
--- a/java/com/google/gerrit/server/Sequences.java
+++ b/java/com/google/gerrit/server/Sequences.java
@@ -93,11 +93,15 @@
         new RepoSequence(
             repoManager, gitRefUpdated, allProjects, NAME_CHANGES, changeSeed, changeBatchSize);
 
-    RepoSequence.Seed groupSeed = () -> nextGroupId(db.get());
     int groupBatchSize = 1;
     groupSeq =
         new RepoSequence(
-            repoManager, gitRefUpdated, allUsers, NAME_GROUPS, groupSeed, groupBatchSize);
+            repoManager,
+            gitRefUpdated,
+            allUsers,
+            NAME_GROUPS,
+            () -> ReviewDb.FIRST_GROUP_ID,
+            groupBatchSize);
 
     nextIdLatency =
         metrics.newTimer(
@@ -158,9 +162,4 @@
   private static int nextChangeId(ReviewDb db) throws OrmException {
     return db.nextChangeId();
   }
-
-  @SuppressWarnings("deprecation")
-  static int nextGroupId(ReviewDb db) throws OrmException {
-    return db.nextAccountGroupId();
-  }
 }
diff --git a/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java b/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
index bbe0c62..97beefd 100644
--- a/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
+++ b/java/com/google/gerrit/server/git/meta/MetaDataUpdate.java
@@ -22,6 +22,7 @@
 import com.google.gerrit.server.git.GitRepositoryManager;
 import com.google.inject.Inject;
 import com.google.inject.Provider;
+import com.google.inject.Singleton;
 import com.google.inject.assistedinject.Assisted;
 import java.io.IOException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
@@ -33,21 +34,22 @@
 
 /** Helps with the updating of a {@link VersionedMetaData}. */
 public class MetaDataUpdate implements AutoCloseable {
+  @Singleton
   public static class User {
     private final InternalFactory factory;
     private final GitRepositoryManager mgr;
-    private final PersonIdent serverIdent;
+    private final Provider<PersonIdent> serverIdentProvider;
     private final Provider<IdentifiedUser> identifiedUser;
 
     @Inject
     User(
         InternalFactory factory,
         GitRepositoryManager mgr,
-        @GerritPersonIdent PersonIdent serverIdent,
+        @GerritPersonIdent Provider<PersonIdent> serverIdentProvider,
         Provider<IdentifiedUser> identifiedUser) {
       this.factory = factory;
       this.mgr = mgr;
-      this.serverIdent = serverIdent;
+      this.serverIdentProvider = serverIdentProvider;
       this.identifiedUser = identifiedUser;
     }
 
@@ -126,29 +128,31 @@
     public MetaDataUpdate create(
         Project.NameKey name, Repository repository, IdentifiedUser user, BatchRefUpdate batch) {
       MetaDataUpdate md = factory.create(name, repository, batch);
-      md.getCommitBuilder().setCommitter(serverIdent);
+      md.getCommitBuilder().setCommitter(serverIdentProvider.get());
       md.setAuthor(user);
       return md;
     }
 
     private PersonIdent createPersonIdent(IdentifiedUser user) {
+      PersonIdent serverIdent = serverIdentProvider.get();
       return user.newCommitterIdent(serverIdent.getWhen(), serverIdent.getTimeZone());
     }
   }
 
+  @Singleton
   public static class Server {
     private final InternalFactory factory;
     private final GitRepositoryManager mgr;
-    private final PersonIdent serverIdent;
+    private final Provider<PersonIdent> serverIdentProvider;
 
     @Inject
     Server(
         InternalFactory factory,
         GitRepositoryManager mgr,
-        @GerritPersonIdent PersonIdent serverIdent) {
+        @GerritPersonIdent Provider<PersonIdent> serverIdentProvider) {
       this.factory = factory;
       this.mgr = mgr;
-      this.serverIdent = serverIdent;
+      this.serverIdentProvider = serverIdentProvider;
     }
 
     public MetaDataUpdate create(Project.NameKey name)
@@ -162,6 +166,7 @@
       Repository repo = mgr.openRepository(name);
       MetaDataUpdate md = factory.create(name, repo, batch);
       md.setCloseRepository(true);
+      PersonIdent serverIdent = serverIdentProvider.get();
       md.getCommitBuilder().setAuthor(serverIdent);
       md.getCommitBuilder().setCommitter(serverIdent);
       return md;
diff --git a/java/com/google/gerrit/server/schema/Schema_163.java b/java/com/google/gerrit/server/schema/Schema_163.java
index 9eb5d5e..4b3659de 100644
--- a/java/com/google/gerrit/server/schema/Schema_163.java
+++ b/java/com/google/gerrit/server/schema/Schema_163.java
@@ -40,15 +40,13 @@
 
   @Override
   protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
-    @SuppressWarnings("deprecation")
-    RepoSequence.Seed groupSeed = db::nextAccountGroupId;
     RepoSequence groupSeq =
         new RepoSequence(
             repoManager,
             GitReferenceUpdated.DISABLED,
             allUsersName,
             Sequences.NAME_GROUPS,
-            groupSeed,
+            () -> ReviewDb.FIRST_GROUP_ID,
             1);
 
     // consume one account ID to ensure that the group sequence is initialized in NoteDb
diff --git a/java/com/google/gerrit/testing/DisabledReviewDb.java b/java/com/google/gerrit/testing/DisabledReviewDb.java
index 037c452..d06beb9 100644
--- a/java/com/google/gerrit/testing/DisabledReviewDb.java
+++ b/java/com/google/gerrit/testing/DisabledReviewDb.java
@@ -95,11 +95,6 @@
   }
 
   @Override
-  public int nextAccountGroupId() {
-    throw new Disabled();
-  }
-
-  @Override
   public int nextChangeId() {
     throw new Disabled();
   }
diff --git a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
index 6f25d28..18eb37a 100644
--- a/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/group/GroupsIT.java
@@ -89,14 +89,13 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.Target;
 import java.sql.Timestamp;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.TimeUnit;
+import java.util.stream.Stream;
 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.CommitBuilder;
@@ -334,9 +333,6 @@
     String p = createUniqueGroup();
     String g1 = createUniqueGroup();
     String g2 = createUniqueGroup();
-    List<String> groups = new ArrayList<>();
-    groups.add(g1);
-    groups.add(g2);
     gApi.groups().id(p).addGroups(g1, g2);
     assertIncludes(p, g1, g2);
   }
@@ -952,8 +948,8 @@
   }
 
   /**
-   * @Sandboxed is used by this test because it deletes a group reference which introduces an
-   * inconsistency for the group storage. Once group deletion is supported, this test should be
+   * {@code @Sandboxed} is used by this test because it deletes a group reference which introduces
+   * an inconsistency for the group storage. Once group deletion is supported, this test should be
    * updated to use the API instead.
    */
   @Test
@@ -1001,8 +997,7 @@
     TestAccount groupOwner = accountCreator.user2();
     GroupInput in = new GroupInput();
     in.name = name("group");
-    in.members =
-        Collections.singleton(groupOwner).stream().map(u -> u.id.toString()).collect(toList());
+    in.members = Stream.of(groupOwner).map(u -> u.id.toString()).collect(toList());
     in.visibleToAll = true;
     GroupInfo group = gApi.groups().create(in).get();
 
@@ -1045,7 +1040,7 @@
 
   @Test
   public void pushToGroupsBranchForNonAllUsersRepo() throws Exception {
-    assertCreateGroupBranch(project, null);
+    assertCreateGroupBranch(project);
     String groupRef =
         RefNames.refsGroups(new AccountGroup.UUID(gApi.groups().create(name("foo")).get().id));
     createBranch(project, groupRef);
@@ -1054,7 +1049,7 @@
 
   @Test
   public void pushToDeletedGroupsBranchForNonAllUsersRepo() throws Exception {
-    assertCreateGroupBranch(project, null);
+    assertCreateGroupBranch(project);
     String groupRef =
         RefNames.refsDeletedGroups(
             new AccountGroup.UUID(gApi.groups().create(name("foo")).get().id));
@@ -1092,8 +1087,7 @@
     }
   }
 
-  private void assertCreateGroupBranch(Project.NameKey project, String expectedErrorOnCreate)
-      throws Exception {
+  private void assertCreateGroupBranch(Project.NameKey project) throws Exception {
     grant(project, RefNames.REFS_GROUPS + "*", Permission.CREATE, false, REGISTERED_USERS);
     grant(project, RefNames.REFS_GROUPS + "*", Permission.PUSH, false, REGISTERED_USERS);
     TestRepository<InMemoryRepository> repo = cloneProject(project);
@@ -1102,11 +1096,7 @@
             .create(db, admin.getIdent(), repo, "Update group", "arbitraryFile.txt", "some content")
             .setParents(ImmutableList.of())
             .to(RefNames.REFS_GROUPS + name("bar"));
-    if (expectedErrorOnCreate != null) {
-      r.assertErrorStatus(expectedErrorOnCreate);
-    } else {
-      r.assertOkStatus();
-    }
+    r.assertOkStatus();
   }
 
   @Test
@@ -1495,7 +1485,7 @@
   private void assertMembers(String group, TestAccount... expectedMembers) throws Exception {
     assertMembers(
         gApi.groups().id(group).members(),
-        TestAccount.names(expectedMembers).stream().toArray(String[]::new));
+        TestAccount.names(expectedMembers).toArray(new String[0]));
     assertAccountInfos(Arrays.asList(expectedMembers), gApi.groups().id(group).members());
   }