summaryrefslogtreecommitdiffstats
path: root/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java
diff options
context:
space:
mode:
Diffstat (limited to 'gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java')
-rw-r--r--gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java413
1 files changed, 0 insertions, 413 deletions
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
deleted file mode 100644
index ad475b32d3..0000000000
--- a/gerrit-server/src/main/java/com/google/gerrit/server/group/GroupsUpdate.java
+++ /dev/null
@@ -1,413 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.group;
-
-import static com.google.common.collect.ImmutableSet.toImmutableSet;
-import static com.google.gerrit.server.group.Groups.getExistingGroupFromReviewDb;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.gerrit.audit.AuditService;
-import com.google.gerrit.common.Nullable;
-import com.google.gerrit.common.errors.NameAlreadyUsedException;
-import com.google.gerrit.common.errors.NoSuchGroupException;
-import com.google.gerrit.reviewdb.client.Account;
-import com.google.gerrit.reviewdb.client.AccountGroup;
-import com.google.gerrit.reviewdb.client.AccountGroupById;
-import com.google.gerrit.reviewdb.client.AccountGroupMember;
-import com.google.gerrit.reviewdb.client.AccountGroupName;
-import com.google.gerrit.reviewdb.server.ReviewDb;
-import com.google.gerrit.server.GerritPersonIdent;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.account.GroupCache;
-import com.google.gerrit.server.account.GroupIncludeCache;
-import com.google.gerrit.server.git.RenameGroupOp;
-import com.google.gwtorm.server.OrmException;
-import com.google.inject.Inject;
-import com.google.inject.assistedinject.Assisted;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-import org.eclipse.jgit.lib.PersonIdent;
-
-/**
- * A database accessor for write calls related to groups.
- *
- * <p>All calls which write group related details to the database (either ReviewDb or NoteDb) are
- * gathered here. Other classes should always use this class instead of accessing the database
- * directly. There are a few exceptions though: schema classes, wrapper classes, and classes
- * executed during init. The latter ones should use {@code GroupsOnInit} instead.
- *
- * <p>If not explicitly stated, all methods of this class refer to <em>internal</em> groups.
- */
-public class GroupsUpdate {
- public interface Factory {
- /**
- * Creates a {@code GroupsUpdate} which uses the identity of the specified user to mark database
- * modifications executed by it. For NoteDb, this identity is used as author and committer for
- * all related commits.
- *
- * <p><strong>Note</strong>: Please use this method with care and rather consider to use the
- * correct annotation on the provider of a {@code GroupsUpdate} instead.
- *
- * @param currentUser the user to which modifications should be attributed, or {@code null} if
- * the Gerrit server identity should be used
- */
- GroupsUpdate create(@Nullable IdentifiedUser currentUser);
- }
-
- private final Groups groups;
- private final GroupCache groupCache;
- private final GroupIncludeCache groupIncludeCache;
- private final AuditService auditService;
- private final RenameGroupOp.Factory renameGroupOpFactory;
- @Nullable private final IdentifiedUser currentUser;
- private final PersonIdent committerIdent;
-
- @Inject
- GroupsUpdate(
- Groups groups,
- GroupCache groupCache,
- GroupIncludeCache groupIncludeCache,
- AuditService auditService,
- RenameGroupOp.Factory renameGroupOpFactory,
- @GerritPersonIdent PersonIdent serverIdent,
- @Assisted @Nullable IdentifiedUser currentUser) {
- this.groups = groups;
- this.groupCache = groupCache;
- this.groupIncludeCache = groupIncludeCache;
- this.auditService = auditService;
- this.renameGroupOpFactory = renameGroupOpFactory;
- this.currentUser = currentUser;
- committerIdent = getCommitterIdent(serverIdent, currentUser);
- }
-
- private static PersonIdent getCommitterIdent(
- PersonIdent serverIdent, @Nullable IdentifiedUser currentUser) {
- return currentUser != null ? createPersonIdent(serverIdent, currentUser) : serverIdent;
- }
-
- private static PersonIdent createPersonIdent(PersonIdent ident, IdentifiedUser user) {
- return user.newCommitterIdent(ident.getWhen(), ident.getTimeZone());
- }
-
- /**
- * 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, Set<Account.Id> memberIds)
- throws OrmException, IOException {
- addNewGroup(db, group);
- addNewGroupMembers(db, group, memberIds);
- groupCache.onCreateGroup(group);
- }
-
- /**
- * 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
- */
- public static void addNewGroup(ReviewDb db, AccountGroup group) throws OrmException {
- AccountGroupName gn = new AccountGroupName(group);
- // first insert the group name to validate that the group name hasn't
- // already been used to create another group
- db.accountGroupNames().insert(ImmutableList.of(gn));
- db.accountGroups().insert(ImmutableList.of(group));
- }
-
- /**
- * Updates the specified group.
- *
- * @param db the {@code ReviewDb} instance to update
- * @param groupUuid the UUID of the group to update
- * @param groupConsumer a {@code Consumer} which performs the desired updates on the group
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the cache entry for the group couldn't be invalidated
- * @throws NoSuchGroupException if the specified group doesn't exist
- */
- public void updateGroup(
- ReviewDb db, AccountGroup.UUID groupUuid, Consumer<AccountGroup> groupConsumer)
- throws OrmException, IOException, NoSuchGroupException {
- AccountGroup updatedGroup = updateGroupInDb(db, groupUuid, groupConsumer);
- groupCache.evict(updatedGroup.getGroupUUID(), updatedGroup.getId(), updatedGroup.getNameKey());
- }
-
- @VisibleForTesting
- public AccountGroup updateGroupInDb(
- ReviewDb db, AccountGroup.UUID groupUuid, Consumer<AccountGroup> groupConsumer)
- throws OrmException, NoSuchGroupException {
- AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid);
- groupConsumer.accept(group);
- db.accountGroups().update(ImmutableList.of(group));
- return group;
- }
-
- /**
- * Renames the specified group.
- *
- * @param db the {@code ReviewDb} instance to update
- * @param groupUuid the UUID of the group to rename
- * @param newName the new name of the group
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the cache entry for the group couldn't be invalidated
- * @throws NoSuchGroupException if the specified group doesn't exist
- * @throws NameAlreadyUsedException if another group has the name {@code newName}
- */
- public void renameGroup(ReviewDb db, AccountGroup.UUID groupUuid, AccountGroup.NameKey newName)
- throws OrmException, IOException, NameAlreadyUsedException, NoSuchGroupException {
- AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid);
- AccountGroup.NameKey oldName = group.getNameKey();
-
- try {
- AccountGroupName id = new AccountGroupName(newName, group.getId());
- db.accountGroupNames().insert(ImmutableList.of(id));
- } catch (OrmException e) {
- AccountGroupName other = db.accountGroupNames().get(newName);
- if (other != null) {
- // If we are using this identity, don't report the exception.
- if (other.getId().equals(group.getId())) {
- return;
- }
-
- // Otherwise, someone else has this identity.
- throw new NameAlreadyUsedException("group with name " + newName + " already exists");
- }
- throw e;
- }
-
- group.setNameKey(newName);
- db.accountGroups().update(ImmutableList.of(group));
-
- db.accountGroupNames().deleteKeys(ImmutableList.of(oldName));
-
- groupCache.evictAfterRename(oldName);
- groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
-
- @SuppressWarnings("unused")
- Future<?> possiblyIgnoredError =
- renameGroupOpFactory
- .create(committerIdent, groupUuid, oldName.get(), newName.get())
- .start(0, TimeUnit.MILLISECONDS);
- }
-
- /**
- * Adds an account as member to a group. The account is only added as a new member if it isn't
- * already a member of the group.
- *
- * <p><strong>Note</strong>: This method doesn't check whether the account exists!
- *
- * @param db the {@code ReviewDb} instance to update
- * @param groupUuid the UUID of the group
- * @param accountId the ID of the account to add
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the cache entry of the new member couldn't be invalidated
- * @throws NoSuchGroupException if the specified group doesn't exist
- */
- public void addGroupMember(ReviewDb db, AccountGroup.UUID groupUuid, Account.Id accountId)
- throws OrmException, IOException, NoSuchGroupException {
- addGroupMembers(db, groupUuid, ImmutableSet.of(accountId));
- }
-
- /**
- * Adds several accounts as members to a group. Only accounts which currently aren't members of
- * the group are added.
- *
- * <p><strong>Note</strong>: This method doesn't check whether the accounts exist!
- *
- * @param db the {@code ReviewDb} instance to update
- * @param groupUuid the UUID of the group
- * @param accountIds a set of IDs of accounts to add
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the group or one of the new members couldn't be indexed
- * @throws NoSuchGroupException if the specified group doesn't exist
- */
- public void addGroupMembers(ReviewDb db, AccountGroup.UUID groupUuid, Set<Account.Id> accountIds)
- throws OrmException, IOException, NoSuchGroupException {
- AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid);
- Set<Account.Id> newMemberIds = new HashSet<>();
- for (Account.Id accountId : accountIds) {
- boolean isMember = groups.isMember(db, groupUuid, accountId);
- if (!isMember) {
- newMemberIds.add(accountId);
- }
- }
-
- 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);
- }
- db.accountGroupMembers().insert(newMembers);
- groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
- for (AccountGroupMember newMember : newMembers) {
- groupIncludeCache.evictGroupsWithMember(newMember.getAccountId());
- }
- }
-
- /**
- * Removes several members (accounts) from a group. Only accounts which currently are members of
- * the group are removed.
- *
- * @param db the {@code ReviewDb} instance to update
- * @param groupUuid the UUID of the group
- * @param accountIds a set of IDs of accounts to remove
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the group or one of the removed members couldn't be indexed
- * @throws NoSuchGroupException if the specified group doesn't exist
- */
- public void removeGroupMembers(
- ReviewDb db, AccountGroup.UUID groupUuid, Set<Account.Id> accountIds)
- throws OrmException, IOException, NoSuchGroupException {
- AccountGroup group = getExistingGroupFromReviewDb(db, groupUuid);
- AccountGroup.Id groupId = group.getId();
- Set<AccountGroupMember> membersToRemove = new HashSet<>();
- for (Account.Id accountId : accountIds) {
- boolean isMember = groups.isMember(db, groupUuid, accountId);
- if (isMember) {
- AccountGroupMember.Key key = new AccountGroupMember.Key(accountId, groupId);
- membersToRemove.add(new AccountGroupMember(key));
- }
- }
-
- if (membersToRemove.isEmpty()) {
- return;
- }
-
- if (currentUser != null) {
- auditService.dispatchDeleteAccountsFromGroup(currentUser.getAccountId(), membersToRemove);
- }
- db.accountGroupMembers().delete(membersToRemove);
- groupCache.evict(group.getGroupUUID(), group.getId(), group.getNameKey());
- for (AccountGroupMember member : membersToRemove) {
- groupIncludeCache.evictGroupsWithMember(member.getAccountId());
- }
- }
-
- /**
- * Adds several groups as subgroups to a group. Only groups which currently aren't subgroups of
- * the group are added.
- *
- * <p>The parent group must be an internal group whereas the subgroups can either be internal or
- * external groups.
- *
- * <p><strong>Note</strong>: This method doesn't check whether the subgroups exist!
- *
- * @param db the {@code ReviewDb} instance to update
- * @param parentGroupUuid the UUID of the parent group
- * @param subgroupUuids a set of IDs of the groups to add as subgroups
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the parent group couldn't be indexed
- * @throws NoSuchGroupException if the specified parent group doesn't exist
- */
- public void addSubgroups(
- ReviewDb db, AccountGroup.UUID parentGroupUuid, Set<AccountGroup.UUID> subgroupUuids)
- throws OrmException, NoSuchGroupException, IOException {
- AccountGroup parentGroup = getExistingGroupFromReviewDb(db, parentGroupUuid);
- AccountGroup.Id parentGroupId = parentGroup.getId();
- Set<AccountGroupById> newSubgroups = new HashSet<>();
- for (AccountGroup.UUID includedGroupUuid : subgroupUuids) {
- boolean isSubgroup = groups.isSubgroup(db, parentGroupUuid, includedGroupUuid);
- if (!isSubgroup) {
- AccountGroupById.Key key = new AccountGroupById.Key(parentGroupId, includedGroupUuid);
- newSubgroups.add(new AccountGroupById(key));
- }
- }
-
- if (newSubgroups.isEmpty()) {
- return;
- }
-
- if (currentUser != null) {
- auditService.dispatchAddGroupsToGroup(currentUser.getAccountId(), newSubgroups);
- }
- db.accountGroupById().insert(newSubgroups);
- groupCache.evict(parentGroup.getGroupUUID(), parentGroup.getId(), parentGroup.getNameKey());
- for (AccountGroupById newIncludedGroup : newSubgroups) {
- groupIncludeCache.evictParentGroupsOf(newIncludedGroup.getIncludeUUID());
- }
- groupIncludeCache.evictSubgroupsOf(parentGroupUuid);
- }
-
- /**
- * Removes several subgroups from a parent group. Only groups which currently are subgroups of the
- * group are removed.
- *
- * <p>The parent group must be an internal group whereas the subgroups can either be internal or
- * external groups.
- *
- * @param db the {@code ReviewDb} instance to update
- * @param parentGroupUuid the UUID of the parent group
- * @param subgroupUuids a set of IDs of the subgroups to remove from the parent group
- * @throws OrmException if an error occurs while reading/writing from/to ReviewDb
- * @throws IOException if the parent group couldn't be indexed
- * @throws NoSuchGroupException if the specified parent group doesn't exist
- */
- public void removeSubgroups(
- ReviewDb db, AccountGroup.UUID parentGroupUuid, Set<AccountGroup.UUID> subgroupUuids)
- throws OrmException, NoSuchGroupException, IOException {
- AccountGroup parentGroup = getExistingGroupFromReviewDb(db, parentGroupUuid);
- AccountGroup.Id parentGroupId = parentGroup.getId();
- Set<AccountGroupById> subgroupsToRemove = new HashSet<>();
- for (AccountGroup.UUID subgroupUuid : subgroupUuids) {
- boolean isSubgroup = groups.isSubgroup(db, parentGroupUuid, subgroupUuid);
- if (isSubgroup) {
- AccountGroupById.Key key = new AccountGroupById.Key(parentGroupId, subgroupUuid);
- subgroupsToRemove.add(new AccountGroupById(key));
- }
- }
-
- if (subgroupsToRemove.isEmpty()) {
- return;
- }
-
- if (currentUser != null) {
- auditService.dispatchDeleteGroupsFromGroup(currentUser.getAccountId(), subgroupsToRemove);
- }
- db.accountGroupById().delete(subgroupsToRemove);
- groupCache.evict(parentGroup.getGroupUUID(), parentGroup.getId(), parentGroup.getNameKey());
- for (AccountGroupById groupToRemove : subgroupsToRemove) {
- groupIncludeCache.evictParentGroupsOf(groupToRemove.getIncludeUUID());
- }
- groupIncludeCache.evictSubgroupsOf(parentGroupUuid);
- }
-}