use of cz.metacentrum.perun.audit.events.GroupManagerEvents.GroupMoved in project perun by CESNET.
the class GroupsManagerBlImpl method moveGroup.
@Override
public void moveGroup(PerunSession sess, Group destinationGroup, Group movingGroup) throws GroupMoveNotAllowedException, WrongAttributeValueException, WrongReferenceAttributeValueException {
// check if moving group is null
if (movingGroup == null) {
throw new GroupMoveNotAllowedException("Moving group: cannot be null.", null, destinationGroup);
}
// check if moving group is members group
if (movingGroup.getName().equals(VosManager.MEMBERS_GROUP)) {
throw new GroupMoveNotAllowedException("It is not possible to move Members group.", movingGroup, destinationGroup);
}
Map<Integer, Map<Integer, MemberGroupStatus>> previousStatuses = new HashMap<>();
// check if had parent group
Group previousParent;
try {
previousParent = getParentGroup(sess, movingGroup);
previousStatuses = getPreviousStatuses(sess, movingGroup, getGroupMembers(sess, movingGroup));
} catch (ParentGroupNotExistsException e) {
previousParent = null;
}
// if destination group is null, it means group will be moved as top level group
if (destinationGroup != null) {
// check if both groups are from same VO
if (destinationGroup.getVoId() != movingGroup.getVoId()) {
throw new GroupMoveNotAllowedException("Groups are not from same VO. Moving group: " + movingGroup + " has VO:" + movingGroup.getVoId() + " and destination group: " + destinationGroup + " has VO:" + movingGroup.getVoId() + ".", movingGroup, destinationGroup);
}
// check if moving group is the same as destination group
if (destinationGroup.getId() == movingGroup.getId()) {
throw new GroupMoveNotAllowedException("Moving group: " + movingGroup + " cannot be the same as destination group: " + destinationGroup + ".", movingGroup, destinationGroup);
}
// check if destination group is members group
if (destinationGroup.getName().equals(VosManager.MEMBERS_GROUP)) {
throw new GroupMoveNotAllowedException("It is not possible to move group under Members group.", movingGroup, destinationGroup);
}
// check if moving group is already under destination group
if (movingGroup.getParentGroupId() != null && destinationGroup.getId() == movingGroup.getParentGroupId()) {
throw new GroupMoveNotAllowedException("Moving group: " + movingGroup + " is already under destination group: " + destinationGroup + " as subGroup.", movingGroup, destinationGroup);
}
List<Group> movingGroupAllSubGroups = getAllSubGroups(sess, movingGroup);
// check if destination group exists as subGroup in moving group subGroups
if (movingGroupAllSubGroups.contains(destinationGroup)) {
throw new GroupMoveNotAllowedException("Destination group: " + destinationGroup + " is subGroup of Moving group: " + movingGroup + ".", movingGroup, destinationGroup);
}
// check if this operation would create cycle
if (checkGroupsCycle(sess, destinationGroup.getId(), movingGroup.getId())) {
throw new GroupMoveNotAllowedException("There would be cycle created after moving group: " + movingGroup + " under destination group: " + destinationGroup + ".", movingGroup, destinationGroup);
}
List<Group> destinationGroupSubGroups = getSubGroups(sess, destinationGroup);
// check if under destination group is group with same short name as Moving group short name
for (Group group : destinationGroupSubGroups) {
if (movingGroup.getShortName().equals(group.getShortName())) {
throw new GroupMoveNotAllowedException("Under destination group: " + destinationGroup + " is group with the same name as moving group: " + movingGroup + ".", movingGroup, destinationGroup);
}
}
// check if there is union between destination group and moving group
if (groupsManagerImpl.isOneWayRelationBetweenGroups(destinationGroup, movingGroup)) {
throw new GroupMoveNotAllowedException("There is already group union between moving group: " + movingGroup + " and destination group: " + destinationGroup + ".", movingGroup, destinationGroup);
}
// prevent existence forbidden unions between groups after moving
// example: there are groups "A", "A:B" and "C", where "C" is included into "A" (there is a union), if we move "C" under "A:B", existing union will change to forbidden one
// Get all unions for moving group and all of its subgroups
Set<Group> movingGroupStructureUnions = new HashSet<>();
movingGroupStructureUnions.addAll(getGroupUnions(sess, movingGroup, true));
for (Group subGroup : getAllSubGroups(sess, movingGroup)) {
movingGroupStructureUnions.addAll(getGroupUnions(sess, subGroup, true));
}
// prevent wrong exception in situation like "A", "A:B", "A:C" and moving "A:C" under "A:B", which is correct
if (movingGroup.getParentGroupId() != null) {
try {
Group parentGroupOfMovingGroup = getParentGroup(sess, movingGroup);
movingGroupStructureUnions.remove(parentGroupOfMovingGroup);
} catch (ParentGroupNotExistsException ex) {
throw new InternalErrorException("Can't find parentGroup for " + movingGroup);
}
}
// Get all group stucture of destination group (destination group and all its parent groups)
Set<Group> destinationGroupStructure = new HashSet<>();
destinationGroupStructure.add(destinationGroup);
destinationGroupStructure.addAll(getParentGroups(sess, destinationGroup));
movingGroupStructureUnions.retainAll(destinationGroupStructure);
if (!movingGroupStructureUnions.isEmpty()) {
throw new GroupMoveNotAllowedException("After moving of moving group: " + movingGroup + " under destination group: " + destinationGroup + " there will exist forbidden indirect relationship.", movingGroup, destinationGroup);
}
processRelationsWhileMovingGroup(sess, destinationGroup, movingGroup);
// We have to set group attributes so we can update it in database
movingGroup.setParentGroupId(destinationGroup.getId());
String finalGroupName = destinationGroup.getName() + ":" + movingGroup.getShortName();
movingGroup.setName(finalGroupName);
} else {
// check if moving group is already top level group
if (movingGroup.getParentGroupId() == null) {
throw new GroupMoveNotAllowedException("Moving group: " + movingGroup + " is already top level group.", movingGroup, null);
}
List<Group> destinationGroupSubGroups = getGroups(sess, getVo(sess, movingGroup));
// check if there is top level group with same short name as Moving group short name
for (Group group : destinationGroupSubGroups) {
if (movingGroup.getShortName().equals(group.getName())) {
throw new GroupMoveNotAllowedException("There is already top level group with the same name as moving group: " + movingGroup + ".", movingGroup, null);
}
}
processRelationsWhileMovingGroup(sess, null, movingGroup);
// We have to set group attributes so we can update it in database
movingGroup.setParentGroupId(null);
movingGroup.setName(movingGroup.getShortName());
}
// we have to update group name in database
getGroupsManagerImpl().updateGroupName(sess, movingGroup);
// We have to properly set all subGroups names level by level
setSubGroupsNames(sess, getSubGroups(sess, movingGroup), movingGroup);
// Remove movingGroup-resource autoassignments where destination group is not subgroup of assignment's source group
fixMovedTreeAutoassignments(sess, destinationGroup, movingGroup);
// And finally update parentGroupId for moving group in database
this.updateParentGroupId(sess, movingGroup);
List<Member> movingGroupMembers = getGroupMembers(sess, movingGroup);
for (Member member : movingGroupMembers) {
if (previousParent != null) {
// calculate new member-group statuses for members from previous moving group parent
recalculateMemberGroupStatusRecursively(sess, member, previousParent, previousStatuses);
}
}
getPerunBl().getAuditer().log(sess, new GroupMoved(movingGroup));
// Check if moved group should be autoassigned to destination's group resource
if (destinationGroup != null) {
autoassignMovedTree(sess, destinationGroup, movingGroup);
}
}
Aggregations