1

renamings + rework group creation process + remove most wrapper types

This commit is contained in:
Christoph
2020-04-07 20:27:35 +02:00
parent 897722fbd7
commit fbe25deda1
29 changed files with 225 additions and 286 deletions

View File

@ -39,7 +39,7 @@ public class APIController {
@Secured("ROLE_api_user")
@ApiOperation("Gibt alle Gruppen zurück, in denen sich etwas geändert hat")
public GroupRequestWrapper updateGroups(@ApiParam("Letzter Status des Anfragestellers")
@PathVariable Long lastEventId) throws EventException {
@PathVariable long lastEventId) throws EventException {
return APIService.wrap(eventStoreService.findMaxEventId(),
projectionService.projectNewGroups(lastEventId));
}
@ -49,7 +49,7 @@ public class APIController {
@ApiOperation("Gibt alle Gruppen zurück, in denen sich ein Teilnehmer befindet")
public List<String> getGroupIdsOfUser(@ApiParam("Teilnehmer dessen groupIds zurückgegeben werden sollen")
@PathVariable String userId) {
return IdService.uuidsToString(eventStoreService.findExistingUserGroups(userId));
return IdService.uuidToString(eventStoreService.findExistingUserGroups(userId));
}
@GetMapping("/getGroup/{groupId}")

View File

@ -1,8 +1,10 @@
package mops.gruppen2.controller;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType;
import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.CsvService;
import mops.gruppen2.service.GroupService;
import mops.gruppen2.service.IdService;
import mops.gruppen2.service.ProjectionService;
@ -22,8 +24,9 @@ import javax.annotation.security.RolesAllowed;
import java.util.UUID;
import static mops.gruppen2.service.ControllerService.getGroupType;
import static mops.gruppen2.service.ControllerService.getUserMaximum;
import static mops.gruppen2.service.ControllerService.getUserLimit;
import static mops.gruppen2.service.ControllerService.getVisibility;
import static mops.gruppen2.service.IdService.uuidToString;
@Controller
@SessionScope
@ -64,25 +67,25 @@ public class GroupCreationController {
@RequestParam("visibility") boolean isPrivate,
@RequestParam("lecture") boolean isLecture,
@RequestParam("maxInfiniteUsers") boolean isInfinite,
@RequestParam("userMaximum") long maxUsers,
@RequestParam("userMaximum") long userLimit,
@RequestParam(value = "parent", required = false) String parent,
@RequestParam(value = "file", required = false) MultipartFile file) {
validationService.checkFields(description, title, userLimit, isInfinite);
Account account = new Account(token);
UUID parentUUID = IdService.stringToUUID(parent);
Group group = groupService.createGroup(account,
title,
description,
getVisibility(isPrivate),
getGroupType(isLecture),
getUserLimit(isInfinite, userLimit),
parentUUID);
validationService.checkFields(description, title, maxUsers, isInfinite);
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, account);
groupService.createGroupAsOrga(account,
title,
description,
getVisibility(isPrivate),
getGroupType(isLecture),
getUserMaximum(isInfinite, maxUsers),
parentUUID,
file);
return "redirect:/gruppen2";
return "redirect:/gruppen2/details/" + uuidToString(group.getId());
}
@RolesAllowed("ROLE_studentin")
@ -90,9 +93,7 @@ public class GroupCreationController {
public String createGroupAsStudent(KeycloakAuthenticationToken token,
Model model) {
Account account = new Account(token);
model.addAttribute("account", account);
model.addAttribute("account", new Account(token));
model.addAttribute("lectures", projectionService.projectLectures());
return "createStudent";
@ -106,22 +107,21 @@ public class GroupCreationController {
@RequestParam("description") String description,
@RequestParam("visibility") boolean isPrivate,
@RequestParam("maxInfiniteUsers") boolean isInfinite,
@RequestParam("userMaximum") long maxUsers,
@RequestParam("userMaximum") long userLimit,
@RequestParam(value = "parent", required = false) String parent) {
validationService.checkFields(description, title, userLimit, isInfinite);
Account account = new Account(token);
UUID parentUUID = IdService.stringToUUID(parent);
Group group = groupService.createGroup(account,
title,
description,
getVisibility(isPrivate),
GroupType.SIMPLE,
getUserLimit(isInfinite, userLimit),
parentUUID);
validationService.checkFields(description, title, maxUsers, isInfinite);
groupService.createGroup(account,
title,
description,
getVisibility(isPrivate),
GroupType.SIMPLE,
getUserMaximum(isInfinite, maxUsers),
parentUUID);
return "redirect:/gruppen2";
return "redirect:/gruppen2/details/" + uuidToString(group.getId());
}
}

View File

@ -5,7 +5,9 @@ import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.Visibility;
import mops.gruppen2.service.CsvService;
import mops.gruppen2.service.GroupService;
import mops.gruppen2.service.IdService;
import mops.gruppen2.service.InviteService;
import mops.gruppen2.service.ProjectionService;
import mops.gruppen2.service.ValidationService;
@ -55,7 +57,7 @@ public class GroupDetailsController {
UUID parentId = group.getParent();
String actualURL = request.getRequestURL().toString();
String serverURL = actualURL.substring(0, actualURL.indexOf("gruppen2/"));
Group parent = groupService.getParent(parentId);
Group parent = projectionService.projectSingleGroup(parentId);
validationService.throwIfGroupNotExisting(group.getTitle());
@ -122,7 +124,8 @@ public class GroupDetailsController {
validationService.throwIfNoAdmin(group, user);
validationService.checkFields(title, description);
groupService.changeMetaData(account, group, title, description);
groupService.updateTitle(account, IdService.stringToUUID(groupId), title);
groupService.updateDescription(account, IdService.stringToUUID(groupId), description);
return "redirect:/gruppen2/details/" + groupId;
}
@ -176,15 +179,15 @@ public class GroupDetailsController {
@PostMapping("/details/members/changeMaximum")
@CacheEvict(value = "groups", allEntries = true)
public String changeMaxSize(KeycloakAuthenticationToken token,
@RequestParam("maximum") Long maximum,
@RequestParam("maximum") long userLimit,
@RequestParam("group_id") String groupId) {
Account account = new Account(token);
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
validationService.throwIfNewMaximumIsValid(maximum, group);
validationService.throwIfNewUserLimitIsValid(userLimit, group);
groupService.updateMaxUser(account, UUID.fromString(groupId), maximum);
groupService.updateUserLimit(account, group, userLimit);
return "redirect:/gruppen2/details/members/" + groupId;
}
@ -260,7 +263,7 @@ public class GroupDetailsController {
validationService.throwIfNoAdmin(group, user);
groupService.deleteGroupEvent(user.getId(), UUID.fromString(groupId));
groupService.deleteGroup(user.getId(), UUID.fromString(groupId));
return "redirect:/gruppen2";
}
@ -273,7 +276,9 @@ public class GroupDetailsController {
@RequestParam(value = "file", required = false) MultipartFile file) {
Account account = new Account(token);
groupService.addUsersFromCsv(account, file, groupId);
Group group = projectionService.projectSingleGroup(IdService.stringToUUID(groupId));
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, account);
return "redirect:/gruppen2/details/members/" + groupId;
}

View File

@ -67,7 +67,7 @@ public class SearchAndInviteController {
Account account = new Account(token);
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
UUID parentId = group.getParent();
Group parent = groupService.getParent(parentId);
Group parent = projectionService.projectSingleGroup(parentId);
User user = new User(account);
model.addAttribute("account", account);

View File

@ -27,7 +27,7 @@ public class Group {
private String title;
private String description;
private Long userMaximum;
private long userLimit;
//TODO: List to Hashmap
private final List<User> members = new ArrayList<>();

View File

@ -13,6 +13,6 @@ import java.util.List;
@Getter
public class GroupRequestWrapper {
private final Long status;
private final long status;
private final List<Group> groupList;
}

View File

@ -44,7 +44,7 @@ public class AddUserEvent extends Event {
throw new UserAlreadyExistsException(getClass().toString());
}
if (group.getMembers().size() >= group.getUserMaximum()) {
if (group.getMembers().size() >= group.getUserLimit()) {
throw new GroupFullException(getClass().toString());
}

View File

@ -15,14 +15,14 @@ public class CreateGroupEvent extends Event {
private Visibility groupVisibility;
private UUID groupParent;
private GroupType groupType;
private Long groupUserMaximum;
private long groupUserLimit;
public CreateGroupEvent(UUID groupId, String userId, UUID parent, GroupType type, Visibility visibility, Long userMaximum) {
public CreateGroupEvent(UUID groupId, String userId, UUID parent, GroupType type, Visibility visibility, long userLimit) {
super(groupId, userId);
groupParent = parent;
groupType = type;
groupVisibility = visibility;
groupUserMaximum = userMaximum;
groupUserLimit = userLimit;
}
@Override
@ -31,6 +31,6 @@ public class CreateGroupEvent extends Event {
group.setParent(groupParent);
group.setType(groupType);
group.setVisibility(groupVisibility);
group.setUserMaximum(groupUserMaximum);
group.setUserLimit(groupUserLimit);
}
}

View File

@ -23,6 +23,6 @@ public class DeleteGroupEvent extends Event {
group.setVisibility(null);
group.setType(null);
group.setParent(null);
group.setUserMaximum(0L);
group.setUserLimit(0L);
}
}

View File

@ -24,7 +24,7 @@ import java.util.UUID;
@JsonSubTypes.Type(value = UpdateGroupTitleEvent.class, name = "UpdateGroupTitleEvent"),
@JsonSubTypes.Type(value = UpdateRoleEvent.class, name = "UpdateRoleEvent"),
@JsonSubTypes.Type(value = DeleteGroupEvent.class, name = "DeleteGroupEvent"),
@JsonSubTypes.Type(value = UpdateUserMaxEvent.class, name = "UpdateUserMaxEvent")
@JsonSubTypes.Type(value = UpdateUserLimitEvent.class, name = "UpdateUserLimitEvent")
})
@Getter
@NoArgsConstructor

View File

@ -10,21 +10,21 @@ import java.util.UUID;
@Getter
@NoArgsConstructor
public class UpdateUserMaxEvent extends Event {
public class UpdateUserLimitEvent extends Event {
private Long userMaximum;
private long userLimit;
public UpdateUserMaxEvent(UUID groupId, String userId, Long userMaximum) {
public UpdateUserLimitEvent(UUID groupId, String userId, long userLimit) {
super(groupId, userId);
this.userMaximum = userMaximum;
this.userLimit = userLimit;
}
@Override
protected void applyEvent(Group group) throws EventException {
if (userMaximum <= 0 || userMaximum < group.getMembers().size()) {
if (userLimit <= 0 || userLimit < group.getMembers().size()) {
throw new BadParameterException("Usermaximum zu klein.");
}
group.setUserMaximum(userMaximum);
group.setUserLimit(userLimit);
}
}

View File

@ -20,7 +20,7 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
@Query("SELECT DISTINCT group_id FROM event"
+ " WHERE event_id > :status")
List<String> findGroupIdsWhereEventIdGreaterThanStatus(@Param("status") Long status);
List<String> findGroupIdsWhereEventIdGreaterThanStatus(@Param("status") long status);
// ####################################### EVENT DTOs ########################################
@ -68,15 +68,4 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
@Query("SELECT MAX(event_id) FROM event")
Long findMaxEventId();
@Query("SELECT COUNT(*) FROM event"
+ " WHERE event_type = :type AND group_id = :groupId")
Long countEventDTOsByGroupAndType(@Param("type") String type,
@Param("groupId") String groupId);
@Query("SELECT COUNT(*) FROM event"
+ " WHERE group_id = :groupId AND user_id = :userId AND event_type = :type")
Long countEventDTOsByGroupIdAndUserAndType(@Param("groupId") String groupId,
@Param("userId") String userId,
@Param("type") String type);
}

View File

@ -24,13 +24,13 @@ public final class ControllerService {
* Wenn die maximale Useranzahl unendlich ist, wird das Maximum auf 100000 gesetzt.
* Praktisch gibt es also maximal 100000 Nutzer pro Gruppe.
*
* @param isInfinite Gibt an, ob es unendlich viele User geben soll
* @param userMaximum Das Maximum an Usern, falls es eins gibt
* @param isInfinite Gibt an, ob es unendlich viele User geben soll
* @param userLimit Das Maximum an Usern, falls es eins gibt
*
* @return Maximum an Usern
*/
public static long getUserMaximum(boolean isInfinite, long userMaximum) {
return isInfinite ? Long.MAX_VALUE : userMaximum;
public static long getUserLimit(boolean isInfinite, long userLimit) {
return isInfinite ? Long.MAX_VALUE : userLimit;
}
}

View File

@ -22,16 +22,7 @@ public final class CsvService {
private CsvService() {}
static List<User> read(InputStream stream) throws IOException {
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(User.class).withHeader().withColumnReordering(true);
ObjectReader reader = mapper.readerFor(User.class).with(schema);
return reader.<User>readValues(stream).readAll();
}
static List<User> readCsvFile(MultipartFile file) throws EventException {
public static List<User> readCsvFile(MultipartFile file) throws EventException {
if (file == null) {
return Collections.emptyList();
}
@ -48,4 +39,13 @@ public final class CsvService {
}
return Collections.emptyList();
}
private static List<User> read(InputStream stream) throws IOException {
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(User.class).withHeader().withColumnReordering(true);
ObjectReader reader = mapper.readerFor(User.class).with(schema);
return reader.<User>readValues(stream).readAll();
}
}

View File

@ -161,7 +161,7 @@ public class EventStoreService {
*
* @return Liste von neuen und alten Events
*/
List<Event> findChangedGroupEvents(Long status) {
List<Event> findChangedGroupEvents(long status) {
List<String> changedGroupIds = eventStore.findGroupIdsWhereEventIdGreaterThanStatus(status);
List<EventDTO> groupEventDTOS = eventStore.findEventDTOsByGroup(changedGroupIds);
@ -227,7 +227,7 @@ public class EventStoreService {
List<Event> findEventsByGroupAndType(List<UUID> groupIds, String... types) {
return getEventsFromDTOs(eventStore.findEventDTOsByGroupAndType(Arrays.asList(types),
IdService.uuidsToString(groupIds)));
IdService.uuidToString(groupIds)));
}
/**

View File

@ -11,22 +11,26 @@ import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.DeleteGroupEvent;
import mops.gruppen2.domain.event.DeleteUserEvent;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.event.UpdateGroupDescriptionEvent;
import mops.gruppen2.domain.event.UpdateGroupTitleEvent;
import mops.gruppen2.domain.event.UpdateRoleEvent;
import mops.gruppen2.domain.event.UpdateUserMaxEvent;
import mops.gruppen2.domain.event.UpdateUserLimitEvent;
import mops.gruppen2.domain.exception.EventException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import static mops.gruppen2.domain.Role.ADMIN;
/**
* Behandelt Aufgaben, welche sich auf eine Gruppe beziehen
* Behandelt Aufgaben, welche sich auf eine Gruppe beziehen.
* Es werden übergebene Gruppen bearbeitet und dementsprechend Events erzeugt und gespeichert.
*/
//TODO: Der GroupService sollte im Endeffekt größtenteils auf einer übergebenen Gruppe arbeiten.
@Service
@Log4j2
public class GroupService {
@ -47,45 +51,6 @@ public class GroupService {
// ################################# GRUPPE ERSTELLEN ########################################
/**
* Wie createGroup, nur das hier die Gruppe auch als Veranstaltung gesetzt werden kann und CSV Dateien mit Nutzern
* eingelesen werden können.
*
* @param account Der Nutzer der die Gruppe erstellt
* @param title Parameter für die neue Gruppe
* @param description Parameter für die neue Gruppe
* @param visibility Parameter für die neue Gruppe
* @param userMaximum Parameter für die neue Gruppe
* @param parent Parameter für die neue Gruppe
* @param file Parameter für die neue Gruppe
*/
//TODO: add wrapper (GroupMeta)?
//TODO: auslagern teilweise -> EventBuilderService
public void createGroupAsOrga(Account account,
String title,
String description,
Visibility visibility,
GroupType groupType,
long userMaximum,
UUID parent,
MultipartFile file) {
// CSV-Import
List<User> newUsers = CsvService.readCsvFile(file);
newUsers.remove(new User(account));
long newUserMaximum = adjustUserMaximum(newUsers.size(), 1L, userMaximum);
UUID groupId = createGroup(account,
title,
description,
visibility,
groupType,
newUserMaximum,
parent);
addUserList(newUsers, groupId);
}
/**
* Erzeugt eine neue Gruppe, fügt den User, der die Gruppe erstellt hat, hinzu und setzt seine Rolle als Admin fest.
* Zudem wird der Gruppentitel und die Gruppenbeschreibung erzeugt, welche vorher der Methode übergeben wurden.
@ -95,59 +60,60 @@ public class GroupService {
* @param title Gruppentitel
* @param description Gruppenbeschreibung
*/
//TODO: add wrapper?
//TODO: auslagern teilweise -> EventBuilderService
public UUID createGroup(Account account,
String title,
String description,
Visibility visibility,
GroupType groupType,
Long userMaximum,
UUID parent) {
public Group createGroup(Account account,
String title,
String description,
Visibility visibility,
GroupType groupType,
long userLimit,
UUID parent) {
UUID groupId = UUID.randomUUID();
List<Event> events = new ArrayList<>();
CreateGroupEvent createGroupEvent = new CreateGroupEvent(groupId,
account.getName(),
parent,
groupType,
visibility,
userMaximum);
eventStoreService.saveEvent(createGroupEvent);
//TODO: etwas auslagern?
events.add(new CreateGroupEvent(groupId,
account.getName(),
parent,
groupType,
visibility,
userLimit));
events.add(new AddUserEvent(groupId, new User(account)));
events.add(new UpdateGroupTitleEvent(groupId, account.getName(), title));
events.add(new UpdateGroupDescriptionEvent(groupId, account.getName(), description));
events.add(new UpdateRoleEvent(groupId, account.getName(), ADMIN));
inviteService.createLink(groupId);
eventStoreService.saveAll(events);
User user = new User(account);
addUser(account, groupId);
updateTitle(account, groupId, title);
updateDescription(account, groupId, description);
updateRole(user, groupId);
return groupId;
return ProjectionService.projectSingleGroup(events);
}
// ################################ GRUPPENMANIPULATION ######################################
// ################################### GRUPPEN ÄNDERN ########################################
//TODO: GroupService/eventbuilderservice
void addUserList(List<User> newUsers, UUID groupId) {
Group group = projectionService.projectSingleGroup(groupId);
/**
* Fügt eine Liste von Usern zu einer Gruppe hinzu (in der Datenbank).
* Duplikate werden übersprungen, die erzeugten Events werden gespeichert.
* Dabei wird das Teilnehmermaximum eventuell angehoben.
*
* @param newUsers Userliste
* @param group Gruppe
* @param account Ausführender User
*/
public void addUsersToGroup(List<User> newUsers, Group group, Account account) {
updateUserLimit(account, group, getAdjustedUserLimit(newUsers, group));
for (User user : newUsers) {
if (group.getMembers().contains(user)) {
log.info("Benutzer {} ist bereits in Gruppe", user.getId());
} else {
AddUserEvent addUserEvent = new AddUserEvent(groupId, user);
eventStoreService.saveEvent(addUserEvent);
}
}
List<Event> events = newUsers.stream()
.filter(user -> !group.getMembers().contains(user))
.map(user -> new AddUserEvent(group.getId(), user))
.collect(Collectors.toList());
eventStoreService.saveAll(events);
}
//TODO: GroupService/eventbuilderservice
public void updateRole(User user, UUID groupId) throws EventException {
void toggleMemberRole(User user, UUID groupId) throws EventException {
UpdateRoleEvent updateRoleEvent;
Group group = projectionService.projectSingleGroup(groupId);
validationService.throwIfNotInGroup(group, user);
@ -157,62 +123,29 @@ public class GroupService {
} else {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), ADMIN);
}
eventStoreService.saveEvent(updateRoleEvent);
}
//TODO: GroupService
public void addUsersFromCsv(Account account, MultipartFile file, String groupId) {
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
List<User> newUserList = CsvService.readCsvFile(file);
removeOldUsersFromNewUsers(group.getMembers(), newUserList);
UUID groupUUID = IdService.stringToUUID(groupId);
Long newUserMaximum = adjustUserMaximum(newUserList.size(),
group.getMembers().size(),
group.getUserMaximum());
if (newUserMaximum > group.getUserMaximum()) {
updateMaxUser(account, groupUUID, newUserMaximum);
}
addUserList(newUserList, groupUUID);
}
//TODO: GroupService
public void changeMetaData(Account account, Group group, String title, String description) {
if (!title.equals(group.getTitle())) {
updateTitle(account, group.getId(), title);
}
if (!description.equals(group.getDescription())) {
updateDescription(account, group.getId(), description);
}
}
//TODO: GroupService
public void deleteUser(Account account, User user, Group group) throws EventException {
changeRoleIfLastAdmin(account, group);
validationService.throwIfNotInGroup(group, user);
deleteUserEvent(user, group.getId());
deleteUser(user, group.getId());
if (validationService.checkIfGroupEmpty(group.getId())) {
deleteGroupEvent(user.getId(), group.getId());
deleteGroup(user.getId(), group.getId());
}
}
//TODO: GroupService
private void promoteVeteranMember(Account account, Group group) {
if (validationService.checkIfLastAdmin(account, group)) {
User newAdmin = getVeteranMember(account, group);
updateRole(newAdmin, group.getId());
toggleMemberRole(newAdmin, group.getId());
}
}
//TODO: GroupService
public void changeRoleIfLastAdmin(Account account, Group group) {
if (group.getMembers().size() <= 1) {
return;
@ -220,7 +153,6 @@ public class GroupService {
promoteVeteranMember(account, group);
}
//TODO: GroupService
public void changeRole(Account account, User user, Group group) {
if (user.getId().equals(account.getName())) {
if (group.getMembers().size() <= 1) {
@ -228,7 +160,7 @@ public class GroupService {
}
promoteVeteranMember(account, group);
}
updateRole(user, group.getId());
toggleMemberRole(user, group.getId());
}
@ -246,66 +178,60 @@ public class GroupService {
return new User(newAdminId);
}
static long adjustUserMaximum(long newUsers, long oldUsers, long maxUsers) {
return Math.max(oldUsers + newUsers, maxUsers);
}
private static void removeOldUsersFromNewUsers(List<User> oldUsers, List<User> newUsers) {
for (User oldUser : oldUsers) {
newUsers.remove(oldUser);
}
/**
* Ermittelt ein passendes Teilnehmermaximum.
* Reicht das alte Maximum, wird dieses zurückgegeben.
* Ansonsten wird ein erhöhtes Maximum zurückgegeben.
*
* @param newUsers Neue Teilnehmer
* @param group Bestehende Gruppe, welche verändert wird
*
* @return Das neue Teilnehmermaximum
*/
static long getAdjustedUserLimit(List<User> newUsers, Group group) {
return Math.max(group.getMembers().size() + newUsers.size(),
group.getMembers().size());
}
//TODO: GroupService oder in Group?
public Group getParent(UUID parentId) {
Group parent = new Group();
if (!IdService.idIsEmpty(parentId)) {
parent = projectionService.projectSingleGroup(parentId);
}
return parent;
// ################################# SINGLE EVENTS ###########################################
public void deleteUser(User user, UUID groupId) {
DeleteUserEvent event = new DeleteUserEvent(groupId, user.getId());
eventStoreService.saveEvent(event);
}
//TODO: Eventbuilderservice
// ################################### EVENTS ################################################
//TODO: GroupService/eventbuilderservice
private void deleteUserEvent(User user, UUID groupId) {
DeleteUserEvent deleteUserEvent = new DeleteUserEvent(groupId, user.getId());
eventStoreService.saveEvent(deleteUserEvent);
}
//TODO: GroupService/eventbuilderservice
public void deleteGroupEvent(String userId, UUID groupId) {
DeleteGroupEvent deleteGroupEvent = new DeleteGroupEvent(groupId, userId);
public void deleteGroup(String userId, UUID groupId) {
DeleteGroupEvent event = new DeleteGroupEvent(groupId, userId);
inviteService.destroyLink(groupId);
eventStoreService.saveEvent(deleteGroupEvent);
eventStoreService.saveEvent(event);
}
//TODO: GroupService/eventbuilderservice
void updateDescription(Account account, UUID groupId, String description) {
UpdateGroupDescriptionEvent updateGroupDescriptionEvent = new UpdateGroupDescriptionEvent(groupId, account.getName(), description);
eventStoreService.saveEvent(updateGroupDescriptionEvent);
public void updateDescription(Account account, UUID groupId, String description) {
UpdateGroupDescriptionEvent event = new UpdateGroupDescriptionEvent(groupId,
account.getName(),
description);
eventStoreService.saveEvent(event);
}
//TODO: GroupService/eventbuilderservice
public void updateMaxUser(Account account, UUID groupId, Long userMaximum) {
UpdateUserMaxEvent updateUserMaxEvent = new UpdateUserMaxEvent(groupId, account.getName(), userMaximum);
eventStoreService.saveEvent(updateUserMaxEvent);
public void updateUserLimit(Account account, Group group, long userLimit) {
UpdateUserLimitEvent event = new UpdateUserLimitEvent(group.getId(),
account.getName(),
userLimit);
eventStoreService.saveEvent(event);
}
//TODO: GroupService/eventbuilderservice
public void addUser(Account account, UUID groupId) {
AddUserEvent addUserEvent = new AddUserEvent(groupId, account.getName(), account.getGivenname(), account.getFamilyname(), account.getEmail());
eventStoreService.saveEvent(addUserEvent);
AddUserEvent event = new AddUserEvent(groupId, new User(account));
eventStoreService.saveEvent(event);
}
//TODO: GroupService/eventbuilderservice
void updateTitle(Account account, UUID groupId, String title) {
UpdateGroupTitleEvent updateGroupTitleEvent = new UpdateGroupTitleEvent(groupId, account.getName(), title);
eventStoreService.saveEvent(updateGroupTitleEvent);
public void updateTitle(Account account, UUID groupId, String title) {
UpdateGroupTitleEvent event = new UpdateGroupTitleEvent(groupId,
account.getName(),
title);
eventStoreService.saveEvent(event);
}
}

View File

@ -35,13 +35,13 @@ public final class IdService {
return UUID.fromString(groupId);
}
public static List<String> uuidsToString(List<UUID> groupIds) {
public static List<String> uuidToString(List<UUID> groupIds) {
return groupIds.stream()
.map(UUID::toString)
.collect(Collectors.toList());
}
public static String uuidsToString(UUID groupId) {
public static String uuidToString(UUID groupId) {
return groupId.toString();
}

View File

@ -34,6 +34,7 @@ public class ProjectionService {
// ################################## STATISCHE PROJEKTIONEN #################################
/**
* Konstruiert Gruppen aus einer Liste von Events.
*
@ -43,7 +44,7 @@ public class ProjectionService {
*
* @throws EventException Projektionsfehler
*/
static List<Group> projectEventList(List<Event> events) throws EventException {
static List<Group> projectGroups(List<Event> events) throws EventException {
Map<UUID, Group> groupMap = new HashMap<>();
events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupId())));
@ -52,6 +53,24 @@ public class ProjectionService {
return new ArrayList<>(groupMap.values());
}
/**
* Projiziert Events, geht aber davon aus, dass alle zu derselben Gruppe gehören.
*
* @param events Eventliste
*
* @return Eine projizierte Gruppe
*
* @throws EventException Projektionsfehler, z.B. falls Events von verschiedenen Gruppen übergeben werden
*/
static Group projectSingleGroup(List<Event> events) throws EventException {
Group group = new Group();
events.forEach(event -> event.apply(group));
log.trace("{} Events wurden projiziert!", events.size());
return group;
}
/**
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
* wird die Gruppe erstellt und der Map hizugefügt.
@ -84,7 +103,7 @@ public class ProjectionService {
public List<Group> projectNewGroups(long status) {
List<Event> events = eventStoreService.findChangedGroupEvents(status);
return projectEventList(events);
return projectGroups(events);
}
/**
@ -106,7 +125,7 @@ public class ProjectionService {
"UpdateGroupTitleEvent",
"UpdateUserMaxEvent");
List<Group> groups = projectEventList(events);
List<Group> groups = projectGroups(events);
return groups.stream()
.filter(group -> group.getVisibility() == Visibility.PUBLIC)
@ -126,7 +145,7 @@ public class ProjectionService {
"CreateGroupEvent",
"UpdateGroupTitleEvent");
List<Group> lectures = projectEventList(events);
List<Group> lectures = projectGroups(events);
return lectures.stream()
.filter(group -> group.getType() == GroupType.LECTURE)
@ -150,7 +169,7 @@ public class ProjectionService {
"UpdateGroupDescriptionEvent",
"DeleteGroupEvent");
return projectEventList(groupEvents);
return projectGroups(groupEvents);
}
/**
@ -166,7 +185,7 @@ public class ProjectionService {
public Group projectSingleGroup(UUID groupId) throws GroupNotFoundException {
try {
List<Event> events = eventStoreService.findGroupEvents(groupId);
return projectEventList(events).get(0);
return projectGroups(events).get(0);
} catch (IndexOutOfBoundsException e) {
log.error("Gruppe {} wurde nicht gefunden!", groupId.toString());
throw new GroupNotFoundException(ProjectionService.class.toString());

View File

@ -64,7 +64,7 @@ public class ValidationService {
}
public void throwIfGroupFull(Group group) {
if (group.getUserMaximum() < group.getMembers().size() + 1) {
if (group.getUserLimit() < group.getMembers().size() + 1) {
throw new GroupFullException("Du kannst der Gruppe daher leider nicht beitreten.");
}
}
@ -109,13 +109,13 @@ public class ValidationService {
}
/**
* Überprüft ob alle Felder richtig gesetzt sind.
* Überprüft, ob alle Felder richtig gesetzt sind.
*
* @param description Die Beschreibung der Gruppe
* @param title Der Titel der Gruppe
* @param userMaximum Das user Limit der Gruppe
* @param userLimit Das user Limit der Gruppe
*/
public void checkFields(String title, String description, Long userMaximum, Boolean maxInfiniteUsers) {
public void checkFields(String title, String description, Long userLimit, Boolean maxInfiniteUsers) {
if (description == null || description.trim().isEmpty()) {
throw new BadParameterException("Die Beschreibung wurde nicht korrekt angegeben");
}
@ -124,11 +124,11 @@ public class ValidationService {
throw new BadParameterException("Der Titel wurde nicht korrekt angegeben");
}
if (userMaximum == null && maxInfiniteUsers == null) {
if (userLimit == null && maxInfiniteUsers == null) {
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
}
if (userMaximum != null && (userMaximum < 1 || userMaximum > 10000L)) {
if (userLimit != null && (userLimit < 1 || userLimit > 100_000L)) {
throw new BadParameterException("Teilnehmeranzahl wurde nicht korrekt angegeben");
}
}
@ -143,16 +143,16 @@ public class ValidationService {
}
}
public void throwIfNewMaximumIsValid(Long newUserMaximum, Group group) {
if (newUserMaximum == null) {
public void throwIfNewUserLimitIsValid(Long newUserLimit, Group group) {
if (newUserLimit == null) {
throw new BadParameterException("Es wurde keine neue maximale Teilnehmeranzahl angegeben!");
}
if (newUserMaximum < 1 || newUserMaximum > 10000L) {
if (newUserLimit < 1 || newUserLimit > 100_000L) {
throw new BadParameterException("Die neue maximale Teilnehmeranzahl wurde nicht korrekt angegeben!");
}
if (group.getMembers().size() > newUserMaximum) {
if (group.getMembers().size() > newUserLimit) {
throw new BadParameterException("Die neue maximale Teilnehmeranzahl ist kleiner als die aktuelle Teilnehmeranzahl!");
}
}

View File

@ -100,11 +100,11 @@
</div>
<div class="col-4" style="white-space: nowrap; float: right; background: white; display: inline-block; margin-bottom: 100px; margin-top: -8px">
<h2>Mitglieder</h2>
<div th:switch="${group.getUserMaximum() != 100000}">
<div th:switch="${group.getUserLimit() != 100000}">
<h4 th:case="${true}">
<a th:text="${group.getMembers().size()}"></a>
<a>von maximal</a>
<a th:text="${group.getUserMaximum()}"></a>
<a th:text="${group.getUserLimit()}"></a>
<a>Benutzern.</a>
</h4>
<h4 th:case="${false}"> unbegrenzte Teilnehmeranzahl</h4>

View File

@ -65,11 +65,11 @@
<div class="col-3" style="white-space: nowrap">
<div style="display: inline-block; margin: 0">
<h2>Mitglieder</h2>
<div th:switch="${group.getUserMaximum() != 100000}">
<div th:switch="${group.getUserLimit() != 100000}">
<h4 th:case="${true}">
<a th:text="${group.getMembers().size()}"></a>
<a>von maximal</a>
<a th:text="${group.getUserMaximum()}"></a>
<a th:text="${group.getUserLimit()}"></a>
<a>Benutzern.</a>
</h4>
<h4 th:case="false">unbegrenzte Teilnehmeranzahl</h4>

View File

@ -37,11 +37,11 @@
<div class="row">
<div class="col-10">
<h1>Mitglieder bearbeiten</h1>
<div th:switch="${group.getUserMaximum() != 100000}">
<div th:switch="${group.getUserLimit() != 100000}">
<h5 th:case="${true}">
<a th:text="${group.getMembers().size()}"></a>
<a>von maximal</a>
<a th:text="${group.getUserMaximum()}"></a>
<a th:text="${group.getUserLimit()}"></a>
<a>Benutzern.</a>
</h5>
<h5 th:case="${false}"> unbegrenzte Teilnehmeranzahl</h5>

View File

@ -63,11 +63,11 @@
<div class="col-3" style="white-space: nowrap">
<div style="display: inline-block; margin: 0">
<h2>Mitglieder</h2>
<div th:switch="${group.getUserMaximum() != 100000}">
<div th:switch="${group.getUserLimit() != 100000}">
<h4 th:case="${true}">
<a th:text="${group.getMembers().size()}"></a>
<a>von maximal</a>
<a th:text="${group.getUserMaximum()}"></a>
<a th:text="${group.getUserLimit()}"></a>
<a>Benutzern.</a>
</h4>
<h4 th:case="false">unbegrenzte Teilnehmeranzahl</h4>

View File

@ -65,7 +65,7 @@
</tr>
</thead>
<tbody>
<tr th:each="gruppe : ${gruppen}" th:switch="${gruppe.getUserMaximum() != 100000}">
<tr th:each="gruppe : ${gruppen}" th:switch="${gruppe.getUserLimit() != 100000}">
<th scope="row">
<span class="badge badge-pill badge-success"
style="background: lightseagreen; margin-right: 25px;"
@ -77,7 +77,7 @@
Beschreibung
</td>
<td th:case="${true}">
<a th:text="${gruppe.getUserMaximum()}"></a>
<a th:text="${gruppe.getUserLimit()}"></a>
</td>
<td th:case="${false}">unbegrenzt</td>
</tr>

View File

@ -44,7 +44,7 @@ class AddUserEventTest {
@Test
void applyEvent_groupFull() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event maxSizeEvent = new UpdateUserMaxEvent(uuidMock(0), "A", 2L);
Event maxSizeEvent = new UpdateUserLimitEvent(uuidMock(0), "A", 2L);
Event addEventA = addUserEvent(uuidMock(0), "A");
Event addEventB = addUserEvent(uuidMock(0), "B");
Event addEventC = addUserEvent(uuidMock(0), "C");

View File

@ -25,7 +25,7 @@ class CreateGroupEventTest {
assertThat(group.getMembers()).hasSize(0);
assertThat(group.getType()).isEqualTo(GroupType.SIMPLE);
assertThat(group.getVisibility()).isEqualTo(Visibility.PUBLIC);
assertThat(group.getUserMaximum()).isEqualTo(100);
assertThat(group.getUserLimit()).isEqualTo(100);
assertThat(group.getId()).isEqualTo(uuidMock(0));
assertThat(group.getParent()).isEqualTo(uuidMock(1));
}

View File

@ -26,7 +26,7 @@ class DeleteGroupEventTest {
assertThat(group.getMembers()).isEmpty();
assertThat(group.getType()).isEqualTo(null);
assertThat(group.getVisibility()).isEqualTo(null);
assertThat(group.getUserMaximum()).isEqualTo(0);
assertThat(group.getUserLimit()).isEqualTo(0);
assertThat(group.getId()).isEqualTo(uuidMock(0));
assertThat(group.getParent()).isEqualTo(null);
}

View File

@ -11,22 +11,22 @@ import static mops.gruppen2.TestBuilder.uuidMock;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertThrows;
class UpdateUserMaxEventTest {
class UpdateUserLimitEventTest {
@Test
void applyEvent() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateUserMaxEvent(uuidMock(0), "A", 5L);
Event updateEvent = new UpdateUserLimitEvent(uuidMock(0), "A", 5L);
Group group = apply(createEvent, updateEvent);
assertThat(group.getUserMaximum()).isEqualTo(5);
assertThat(group.getUserLimit()).isEqualTo(5);
}
@Test
void applyEvent_badParameter_negative() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEvent = new UpdateUserMaxEvent(uuidMock(0), "A", -5L);
Event updateEvent = new UpdateUserLimitEvent(uuidMock(0), "A", -5L);
Group group = apply(createEvent);
@ -36,11 +36,11 @@ class UpdateUserMaxEventTest {
@Test
void applyEvent_badParameter_tooSmall() {
Event createEvent = createPublicGroupEvent(uuidMock(0));
Event updateEventA = new UpdateUserMaxEvent(uuidMock(0), "A", 5L);
Event updateEventA = new UpdateUserLimitEvent(uuidMock(0), "A", 5L);
Event addEventA = addUserEvent(uuidMock(0));
Event addEventB = addUserEvent(uuidMock(0));
Event addEventC = addUserEvent(uuidMock(0));
Event updateEventB = new UpdateUserMaxEvent(uuidMock(0), "A", 2L);
Event updateEventB = new UpdateUserLimitEvent(uuidMock(0), "A", 2L);
Group group = apply(createEvent, updateEventA, addEventA, addEventB, addEventC);

View File

@ -70,7 +70,7 @@ class GroupServiceTest {
void rightClassForSuccessfulGroup() {
List<Event> eventList = completePrivateGroup(1);
List<Group> groups = ProjectionService.projectEventList(eventList);
List<Group> groups = ProjectionService.projectGroups(eventList);
assertThat(groups.get(0)).isInstanceOf(Group.class);
}
@ -79,7 +79,7 @@ class GroupServiceTest {
void projectEventList_SingleGroup() {
List<Event> eventList = completePrivateGroup(5);
List<Group> groups = ProjectionService.projectEventList(eventList);
List<Group> groups = ProjectionService.projectGroups(eventList);
assertThat(groups).hasSize(1);
assertThat(groups.get(0).getMembers()).hasSize(5);
@ -92,7 +92,7 @@ class GroupServiceTest {
List<Event> eventList = completePrivateGroups(10, 2);
eventList.addAll(completePublicGroups(10, 5));
List<Group> groups = ProjectionService.projectEventList(eventList);
List<Group> groups = ProjectionService.projectGroups(eventList);
assertThat(groups).hasSize(20);
assertThat(groups.stream().map(group -> group.getMembers().size()).reduce(Integer::sum).get()).isEqualTo(70);