Directly add members to a group upon creation

Change-Id: I29af3508590e8c018a6d929cac9299d67a5ef792
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/CreateGroup.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/CreateGroup.java
index 261269e..1635d31 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/CreateGroup.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/CreateGroup.java
@@ -16,11 +16,11 @@
 
 import com.google.common.base.MoreObjects;
 import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableSet;
 import com.google.gerrit.common.TimeUtil;
 import com.google.gerrit.common.data.GlobalCapability;
 import com.google.gerrit.common.data.GroupDescription;
 import com.google.gerrit.common.data.GroupDescriptions;
-import com.google.gerrit.common.errors.NoSuchGroupException;
 import com.google.gerrit.extensions.annotations.RequiresCapability;
 import com.google.gerrit.extensions.api.groups.GroupInput;
 import com.google.gerrit.extensions.client.ListGroupsOption;
@@ -208,20 +208,14 @@
       group.setDescription(createGroupArgs.groupDescription);
     }
     try {
-      groupsUpdateProvider.get().addGroup(db, group);
+      groupsUpdateProvider
+          .get()
+          .addGroup(db, group, ImmutableSet.copyOf(createGroupArgs.initialMembers));
     } catch (OrmDuplicateKeyException e) {
       throw new ResourceConflictException(
           "group '" + createGroupArgs.getGroupName() + "' already exists");
     }
 
-    try {
-      addMembers.addMembers(uuid, createGroupArgs.initialMembers);
-    } catch (NoSuchGroupException e) {
-      throw new ResourceNotFoundException(String.format("Group %s not found", uuid));
-    }
-
-    groupCache.onCreateGroup(createGroupArgs.getGroup());
-
     return group;
   }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java
index bbf4eca..339a276 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java
@@ -14,6 +14,8 @@
 
 package com.google.gerrit.server.group;
 
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -120,19 +122,28 @@
   }
 
   /**
-   * Adds/Creates the specified group.
+   * Adds/Creates the specified group for the specified members (accounts).
    *
    * @param db the {@code ReviewDb} instance to update
    * @param group the group to add
+   * @param memberIds the IDs of the accounts which should be members of the created group
    * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
+   * @throws IOException if the cache entry of one of the new members couldn't be invalidated, or
+   *     the new group couldn't be indexed
    */
-  public void addGroup(ReviewDb db, AccountGroup group) throws OrmException {
+  public void addGroup(ReviewDb db, AccountGroup group, Set<Account.Id> memberIds)
+      throws OrmException, IOException {
     addNewGroup(db, group);
+    addNewGroupMembers(db, group, memberIds);
+    groupCache.onCreateGroup(group.getNameKey());
   }
 
   /**
    * Adds the specified group.
    *
+   * <p><strong>Note</strong>: This method doesn't update the index! It just adds the group to the
+   * database. Use this method with care.
+   *
    * @param db the {@code ReviewDb} instance to update
    * @param group the group to add
    * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
@@ -254,20 +265,30 @@
   public void addGroupMembers(ReviewDb db, AccountGroup.UUID groupUuid, Set<Account.Id> accountIds)
       throws OrmException, IOException, NoSuchGroupException {
     AccountGroup group = groups.getExistingGroup(db, groupUuid);
-    AccountGroup.Id groupId = group.getId();
-    Set<AccountGroupMember> newMembers = new HashSet<>();
+    Set<Account.Id> newMemberIds = new HashSet<>();
     for (Account.Id accountId : accountIds) {
       boolean isMember = groups.isMember(db, groupUuid, accountId);
       if (!isMember) {
-        AccountGroupMember.Key key = new AccountGroupMember.Key(accountId, groupId);
-        newMembers.add(new AccountGroupMember(key));
+        newMemberIds.add(accountId);
       }
     }
 
-    if (newMembers.isEmpty()) {
+    if (newMemberIds.isEmpty()) {
       return;
     }
 
+    addNewGroupMembers(db, group, newMemberIds);
+  }
+
+  private void addNewGroupMembers(ReviewDb db, AccountGroup group, Set<Account.Id> newMemberIds)
+      throws OrmException, IOException {
+    Set<AccountGroupMember> newMembers =
+        newMemberIds
+            .stream()
+            .map(accountId -> new AccountGroupMember.Key(accountId, group.getId()))
+            .map(AccountGroupMember::new)
+            .collect(toImmutableSet());
+
     if (currentUser != null) {
       auditService.dispatchAddAccountsToGroup(currentUser.getAccountId(), newMembers);
     }