| // Copyright (C) 2018 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.acceptance.testsuite.group; |
| |
| import static com.google.common.base.Preconditions.checkState; |
| |
| import com.google.gerrit.entities.AccountGroup; |
| import com.google.gerrit.entities.InternalGroup; |
| import com.google.gerrit.exceptions.DuplicateKeyException; |
| import com.google.gerrit.exceptions.NoSuchGroupException; |
| import com.google.gerrit.server.GerritPersonIdent; |
| import com.google.gerrit.server.ServerInitiated; |
| import com.google.gerrit.server.account.GroupUuid; |
| import com.google.gerrit.server.group.db.GroupDelta; |
| import com.google.gerrit.server.group.db.Groups; |
| import com.google.gerrit.server.group.db.GroupsUpdate; |
| import com.google.gerrit.server.group.db.InternalGroupCreation; |
| import com.google.gerrit.server.notedb.Sequences; |
| import com.google.inject.Inject; |
| import java.io.IOException; |
| import java.util.Optional; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.PersonIdent; |
| |
| /** |
| * The implementation of {@code GroupOperations}. |
| * |
| * <p>There is only one implementation of {@code GroupOperations}. Nevertheless, we keep the |
| * separation between interface and implementation to enhance clarity. |
| */ |
| public class GroupOperationsImpl implements GroupOperations { |
| private final Groups groups; |
| private final GroupsUpdate groupsUpdate; |
| private final Sequences seq; |
| private final PersonIdent serverIdent; |
| |
| @Inject |
| public GroupOperationsImpl( |
| Groups groups, |
| @ServerInitiated GroupsUpdate groupsUpdate, |
| Sequences seq, |
| @GerritPersonIdent PersonIdent serverIdent) { |
| this.groups = groups; |
| this.groupsUpdate = groupsUpdate; |
| this.seq = seq; |
| this.serverIdent = serverIdent; |
| } |
| |
| @Override |
| public PerGroupOperations group(AccountGroup.UUID groupUuid) { |
| return new PerGroupOperationsImpl(groupUuid); |
| } |
| |
| @Override |
| public TestGroupCreation.Builder newGroup() { |
| return TestGroupCreation.builder(this::createNewGroup); |
| } |
| |
| private AccountGroup.UUID createNewGroup(TestGroupCreation groupCreation) |
| throws ConfigInvalidException, IOException { |
| InternalGroupCreation internalGroupCreation = toInternalGroupCreation(groupCreation); |
| GroupDelta groupDelta = toGroupDelta(groupCreation); |
| InternalGroup internalGroup = groupsUpdate.createGroup(internalGroupCreation, groupDelta); |
| return internalGroup.getGroupUUID(); |
| } |
| |
| private InternalGroupCreation toInternalGroupCreation(TestGroupCreation groupCreation) { |
| AccountGroup.Id groupId = AccountGroup.id(seq.nextGroupId()); |
| String groupName = groupCreation.name().orElse("group-with-id-" + groupId.get()); |
| AccountGroup.UUID groupUuid = GroupUuid.make(groupName, serverIdent); |
| AccountGroup.NameKey nameKey = AccountGroup.nameKey(groupName); |
| return InternalGroupCreation.builder() |
| .setId(groupId) |
| .setGroupUUID(groupUuid) |
| .setNameKey(nameKey) |
| .build(); |
| } |
| |
| private static GroupDelta toGroupDelta(TestGroupCreation groupCreation) { |
| GroupDelta.Builder builder = GroupDelta.builder(); |
| groupCreation.description().ifPresent(builder::setDescription); |
| groupCreation.ownerGroupUuid().ifPresent(builder::setOwnerGroupUUID); |
| groupCreation.visibleToAll().ifPresent(builder::setVisibleToAll); |
| builder.setMemberModification(originalMembers -> groupCreation.members()); |
| builder.setSubgroupModification(originalSubgroups -> groupCreation.subgroups()); |
| return builder.build(); |
| } |
| |
| private class PerGroupOperationsImpl implements PerGroupOperations { |
| private final AccountGroup.UUID groupUuid; |
| |
| PerGroupOperationsImpl(AccountGroup.UUID groupUuid) { |
| this.groupUuid = groupUuid; |
| } |
| |
| @Override |
| public boolean exists() { |
| return getGroup(groupUuid).isPresent(); |
| } |
| |
| @Override |
| public TestGroup get() { |
| Optional<InternalGroup> group = getGroup(groupUuid); |
| checkState(group.isPresent(), "Tried to get non-existing test group"); |
| return toTestGroup(group.get()); |
| } |
| |
| private Optional<InternalGroup> getGroup(AccountGroup.UUID groupUuid) { |
| try { |
| return groups.getGroup(groupUuid); |
| } catch (IOException | ConfigInvalidException e) { |
| throw new IllegalStateException(e); |
| } |
| } |
| |
| private TestGroup toTestGroup(InternalGroup internalGroup) { |
| return TestGroup.builder() |
| .groupUuid(internalGroup.getGroupUUID()) |
| .groupId(internalGroup.getId()) |
| .nameKey(internalGroup.getNameKey()) |
| .description(Optional.ofNullable(internalGroup.getDescription())) |
| .ownerGroupUuid(internalGroup.getOwnerGroupUUID()) |
| .visibleToAll(internalGroup.isVisibleToAll()) |
| .createdOn(internalGroup.getCreatedOn()) |
| .members(internalGroup.getMembers()) |
| .subgroups(internalGroup.getSubgroups()) |
| .build(); |
| } |
| |
| @Override |
| public TestGroupUpdate.Builder forUpdate() { |
| return TestGroupUpdate.builder(this::updateGroup); |
| } |
| |
| private void updateGroup(TestGroupUpdate groupUpdate) |
| throws DuplicateKeyException, NoSuchGroupException, ConfigInvalidException, IOException { |
| GroupDelta groupDelta = toGroupDelta(groupUpdate); |
| groupsUpdate.updateGroup(groupUuid, groupDelta); |
| } |
| |
| private GroupDelta toGroupDelta(TestGroupUpdate groupUpdate) { |
| GroupDelta.Builder builder = GroupDelta.builder(); |
| groupUpdate.name().map(AccountGroup::nameKey).ifPresent(builder::setName); |
| groupUpdate.description().ifPresent(builder::setDescription); |
| groupUpdate.ownerGroupUuid().ifPresent(builder::setOwnerGroupUUID); |
| groupUpdate.visibleToAll().ifPresent(builder::setVisibleToAll); |
| builder.setMemberModification(groupUpdate.memberModification()::apply); |
| builder.setSubgroupModification(groupUpdate.subgroupModification()::apply); |
| return builder.build(); |
| } |
| } |
| } |