1

finish up group service?

This commit is contained in:
Christoph
2020-04-07 21:53:04 +02:00
parent fbe25deda1
commit 8d88ef4346
18 changed files with 169 additions and 147 deletions

View File

@ -3,6 +3,7 @@ package mops.gruppen2.controller;
import mops.gruppen2.domain.Account; import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType; import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.User;
import mops.gruppen2.service.ControllerService; import mops.gruppen2.service.ControllerService;
import mops.gruppen2.service.CsvService; import mops.gruppen2.service.CsvService;
import mops.gruppen2.service.GroupService; import mops.gruppen2.service.GroupService;
@ -74,8 +75,9 @@ public class GroupCreationController {
validationService.checkFields(description, title, userLimit, isInfinite); validationService.checkFields(description, title, userLimit, isInfinite);
Account account = new Account(token); Account account = new Account(token);
User user = new User(account);
UUID parentUUID = IdService.stringToUUID(parent); UUID parentUUID = IdService.stringToUUID(parent);
Group group = groupService.createGroup(account, Group group = groupService.createGroup(user,
title, title,
description, description,
getVisibility(isPrivate), getVisibility(isPrivate),
@ -83,7 +85,7 @@ public class GroupCreationController {
getUserLimit(isInfinite, userLimit), getUserLimit(isInfinite, userLimit),
parentUUID); parentUUID);
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, account); groupService.addUsersToGroup(CsvService.readCsvFile(file), group, user);
return "redirect:/gruppen2/details/" + uuidToString(group.getId()); return "redirect:/gruppen2/details/" + uuidToString(group.getId());
} }
@ -113,8 +115,9 @@ public class GroupCreationController {
validationService.checkFields(description, title, userLimit, isInfinite); validationService.checkFields(description, title, userLimit, isInfinite);
Account account = new Account(token); Account account = new Account(token);
User user = new User(account);
UUID parentUUID = IdService.stringToUUID(parent); UUID parentUUID = IdService.stringToUUID(parent);
Group group = groupService.createGroup(account, Group group = groupService.createGroup(user,
title, title,
description, description,
getVisibility(isPrivate), getVisibility(isPrivate),

View File

@ -80,7 +80,7 @@ public class GroupDetailsController {
model.addAttribute("private", Visibility.PRIVATE); model.addAttribute("private", Visibility.PRIVATE);
if (validationService.checkIfAdmin(group, user)) { if (validationService.checkIfAdmin(group, user)) {
model.addAttribute("link", serverURL + "gruppen2/acceptinvite/" + inviteService.getLinkByGroupId(group.getId())); model.addAttribute("link", serverURL + "gruppen2/acceptinvite/" + inviteService.getLinkByGroup(group.getId()));
} }
return "detailsMember"; return "detailsMember";
@ -124,8 +124,8 @@ public class GroupDetailsController {
validationService.throwIfNoAdmin(group, user); validationService.throwIfNoAdmin(group, user);
validationService.checkFields(title, description); validationService.checkFields(title, description);
groupService.updateTitle(account, IdService.stringToUUID(groupId), title); groupService.updateTitle(user, group, title);
groupService.updateDescription(account, IdService.stringToUUID(groupId), description); groupService.updateDescription(user, group, description);
return "redirect:/gruppen2/details/" + groupId; return "redirect:/gruppen2/details/" + groupId;
} }
@ -160,13 +160,10 @@ public class GroupDetailsController {
Account account = new Account(token); Account account = new Account(token);
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId)); Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
User principle = new User(account); User principle = new User(account);
User user = new User(userId, "", "", ""); User user = new User(userId);
validationService.throwIfNoAdmin(group, principle); validationService.throwIfNoAdmin(group, principle);
groupService.toggleMemberRole(user, group);
//TODO: checkIfAdmin checkt nicht, dass die rolle geändert wurde. oder die rolle wird nicht geändert
groupService.changeRole(account, user, group);
if (!validationService.checkIfAdmin(group, principle)) { if (!validationService.checkIfAdmin(group, principle)) {
return "redirect:/gruppen2/details/" + groupId; return "redirect:/gruppen2/details/" + groupId;
@ -183,11 +180,12 @@ public class GroupDetailsController {
@RequestParam("group_id") String groupId) { @RequestParam("group_id") String groupId) {
Account account = new Account(token); Account account = new Account(token);
User user = new User(account);
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId)); Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
validationService.throwIfNewUserLimitIsValid(userLimit, group); validationService.throwIfNewUserLimitIsValid(userLimit, group);
groupService.updateUserLimit(account, group, userLimit); groupService.updateUserLimit(user, group, userLimit);
return "redirect:/gruppen2/details/members/" + groupId; return "redirect:/gruppen2/details/members/" + groupId;
} }
@ -206,7 +204,7 @@ public class GroupDetailsController {
validationService.throwIfNoAdmin(group, principle); validationService.throwIfNoAdmin(group, principle);
groupService.deleteUser(account, user, group); groupService.deleteUser(user, group);
if (!validationService.checkIfUserInGroup(group, principle)) { if (!validationService.checkIfUserInGroup(group, principle)) {
return "redirect:/gruppen2"; return "redirect:/gruppen2";
@ -229,7 +227,7 @@ public class GroupDetailsController {
validationService.throwIfUserAlreadyInGroup(group, user); validationService.throwIfUserAlreadyInGroup(group, user);
validationService.throwIfGroupFull(group); validationService.throwIfGroupFull(group);
groupService.addUser(account, UUID.fromString(groupId)); groupService.addUser(user, group);
model.addAttribute("account", account); model.addAttribute("account", account);
@ -246,7 +244,7 @@ public class GroupDetailsController {
User user = new User(account); User user = new User(account);
Group group = projectionService.projectSingleGroup(UUID.fromString(groupId)); Group group = projectionService.projectSingleGroup(UUID.fromString(groupId));
groupService.deleteUser(account, user, group); groupService.deleteUser(user, group);
return "redirect:/gruppen2"; return "redirect:/gruppen2";
} }
@ -263,7 +261,7 @@ public class GroupDetailsController {
validationService.throwIfNoAdmin(group, user); validationService.throwIfNoAdmin(group, user);
groupService.deleteGroup(user.getId(), UUID.fromString(groupId)); groupService.deleteGroup(user, group);
return "redirect:/gruppen2"; return "redirect:/gruppen2";
} }
@ -276,9 +274,10 @@ public class GroupDetailsController {
@RequestParam(value = "file", required = false) MultipartFile file) { @RequestParam(value = "file", required = false) MultipartFile file) {
Account account = new Account(token); Account account = new Account(token);
User user = new User(account);
Group group = projectionService.projectSingleGroup(IdService.stringToUUID(groupId)); Group group = projectionService.projectSingleGroup(IdService.stringToUUID(groupId));
groupService.addUsersToGroup(CsvService.readCsvFile(file), group, account); groupService.addUsersToGroup(CsvService.readCsvFile(file), group, user);
return "redirect:/gruppen2/details/members/" + groupId; return "redirect:/gruppen2/details/members/" + groupId;
} }

View File

@ -115,7 +115,7 @@ public class SearchAndInviteController {
validationService.throwIfUserAlreadyInGroup(group, user); validationService.throwIfUserAlreadyInGroup(group, user);
validationService.throwIfGroupFull(group); validationService.throwIfGroupFull(group);
groupService.addUser(account, UUID.fromString(groupId)); groupService.addUser(user, group);
return "redirect:/gruppen2/details/" + groupId; return "redirect:/gruppen2/details/" + groupId;
} }

View File

@ -2,5 +2,9 @@ package mops.gruppen2.domain;
public enum Role { public enum Role {
ADMIN, ADMIN,
MEMBER MEMBER;
public Role toggle() {
return this == ADMIN ? MEMBER : ADMIN;
}
} }

View File

@ -36,6 +36,13 @@ public class AddUserEvent extends Event {
email = user.getEmail(); email = user.getEmail();
} }
public AddUserEvent(Group group, User user) {
super(group.getId(), user.getId());
givenname = user.getGivenname();
familyname = user.getFamilyname();
email = user.getEmail();
}
@Override @Override
protected void applyEvent(Group group) throws EventException { protected void applyEvent(Group group) throws EventException {
User user = new User(userId, givenname, familyname, email); User user = new User(userId, givenname, familyname, email);

View File

@ -3,6 +3,7 @@ package mops.gruppen2.domain.event;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import java.util.UUID; import java.util.UUID;
@ -14,6 +15,10 @@ public class DeleteGroupEvent extends Event {
super(groupId, userId); super(groupId, userId);
} }
public DeleteGroupEvent(Group group, User user) {
super(group.getId(), user.getId());
}
@Override @Override
protected void applyEvent(Group group) { protected void applyEvent(Group group) {
group.getRoles().clear(); group.getRoles().clear();

View File

@ -20,15 +20,19 @@ public class DeleteUserEvent extends Event {
super(groupId, userId); super(groupId, userId);
} }
public DeleteUserEvent(Group group, User user) {
super(group.getId(), user.getId());
}
@Override @Override
protected void applyEvent(Group group) throws EventException { protected void applyEvent(Group group) throws EventException {
for (User user : group.getMembers()) { for (User user : group.getMembers()) {
if (user.getId().equals(this.userId)) { if (user.getId().equals(userId)) {
group.getMembers().remove(user); group.getMembers().remove(user);
group.getRoles().remove(user.getId()); group.getRoles().remove(user.getId());
return; return;
} }
} }
throw new UserNotFoundException(this.getClass().toString()); throw new UserNotFoundException(getClass().toString());
} }
} }

View File

@ -3,6 +3,7 @@ package mops.gruppen2.domain.event;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.BadParameterException; import mops.gruppen2.domain.exception.BadParameterException;
import java.util.UUID; import java.util.UUID;
@ -21,6 +22,11 @@ public class UpdateGroupDescriptionEvent extends Event {
this.newGroupDescription = newGroupDescription.trim(); this.newGroupDescription = newGroupDescription.trim();
} }
public UpdateGroupDescriptionEvent(Group group, User user, String newGroupDescription) {
super(group.getId(), user.getId());
this.newGroupDescription = newGroupDescription.trim();
}
@Override @Override
protected void applyEvent(Group group) { protected void applyEvent(Group group) {
if (newGroupDescription.isEmpty()) { if (newGroupDescription.isEmpty()) {

View File

@ -3,6 +3,7 @@ package mops.gruppen2.domain.event;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.BadParameterException; import mops.gruppen2.domain.exception.BadParameterException;
import java.util.UUID; import java.util.UUID;
@ -21,6 +22,11 @@ public class UpdateGroupTitleEvent extends Event {
this.newGroupTitle = newGroupTitle.trim(); this.newGroupTitle = newGroupTitle.trim();
} }
public UpdateGroupTitleEvent(Group group, User user, String newGroupTitle) {
super(group.getId(), user.getId());
this.newGroupTitle = newGroupTitle.trim();
}
@Override @Override
protected void applyEvent(Group group) { protected void applyEvent(Group group) {
if (newGroupTitle.isEmpty()) { if (newGroupTitle.isEmpty()) {

View File

@ -4,6 +4,7 @@ import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Role;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.UserNotFoundException; import mops.gruppen2.domain.exception.UserNotFoundException;
import java.util.UUID; import java.util.UUID;
@ -22,6 +23,11 @@ public class UpdateRoleEvent extends Event {
this.newRole = newRole; this.newRole = newRole;
} }
public UpdateRoleEvent(Group group, User user, Role newRole) {
super(group.getId(), user.getId());
this.newRole = newRole;
}
@Override @Override
protected void applyEvent(Group group) throws UserNotFoundException { protected void applyEvent(Group group) throws UserNotFoundException {
if (group.getRoles().containsKey(userId)) { if (group.getRoles().containsKey(userId)) {

View File

@ -3,6 +3,7 @@ package mops.gruppen2.domain.event;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.exception.BadParameterException; import mops.gruppen2.domain.exception.BadParameterException;
import mops.gruppen2.domain.exception.EventException; import mops.gruppen2.domain.exception.EventException;
@ -19,6 +20,11 @@ public class UpdateUserLimitEvent extends Event {
this.userLimit = userLimit; this.userLimit = userLimit;
} }
public UpdateUserLimitEvent(Group group, User user, long userLimit) {
super(group.getId(), user.getId());
this.userLimit = userLimit;
}
@Override @Override
protected void applyEvent(Group group) throws EventException { protected void applyEvent(Group group) throws EventException {
if (userLimit <= 0 || userLimit < group.getMembers().size()) { if (userLimit <= 0 || userLimit < group.getMembers().size()) {

View File

@ -32,8 +32,9 @@ public final class CsvService {
return userList.stream() return userList.stream()
.distinct() .distinct()
.collect(Collectors.toList()); //filter duplicates from list .collect(Collectors.toList()); //filter duplicates from list
} catch (IOException ex) { } catch (IOException e) {
log.error("File konnte nicht gelesen werden:\n{}", ex.getMessage()); log.error("File konnte nicht gelesen werden:\n{}", e.getMessage());
e.printStackTrace();
throw new WrongFileException(file.getOriginalFilename()); throw new WrongFileException(file.getOriginalFilename());
} }
} }

View File

@ -38,14 +38,12 @@ public class EventStoreService {
*/ */
public void saveEvent(Event event) { public void saveEvent(Event event) {
eventStore.save(getDTOFromEvent(event)); eventStore.save(getDTOFromEvent(event));
log.trace("Ein Event wurde gespeichert!");
} }
public void saveAll(Event... events) { public void saveAll(Event... events) {
for (Event event : events) { for (Event event : events) {
eventStore.save(getDTOFromEvent(event)); eventStore.save(getDTOFromEvent(event));
} }
log.trace("{} Events wurden gespeichert!", events.length);
} }
/** /**
@ -59,7 +57,6 @@ public class EventStoreService {
for (Event event : eventlist) { for (Event event : eventlist) {
eventStore.save(getDTOFromEvent(event)); eventStore.save(getDTOFromEvent(event));
} }
log.trace("{} Events wurden gespeichert!", eventlist.size());
} }
} }
@ -90,6 +87,7 @@ public class EventStoreService {
payload); payload);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Event ({}) konnte nicht serialisiert werden!", e.getMessage()); log.error("Event ({}) konnte nicht serialisiert werden!", e.getMessage());
e.printStackTrace();
throw new BadPayloadException(EventStoreService.class.toString()); throw new BadPayloadException(EventStoreService.class.toString());
} }
} }
@ -112,6 +110,7 @@ public class EventStoreService {
return JsonService.deserializeEvent(dto.getEvent_payload()); return JsonService.deserializeEvent(dto.getEvent_payload());
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Payload\n {}\n konnte nicht deserialisiert werden!", e.getMessage()); log.error("Payload\n {}\n konnte nicht deserialisiert werden!", e.getMessage());
e.printStackTrace();
throw new BadPayloadException(EventStoreService.class.toString()); throw new BadPayloadException(EventStoreService.class.toString());
} }
} }
@ -213,6 +212,7 @@ public class EventStoreService {
return eventStore.findMaxEventId(); return eventStore.findMaxEventId();
} catch (NullPointerException e) { } catch (NullPointerException e) {
log.trace("Eine maxId von 0 wurde zurückgegeben, da keine Events vorhanden sind."); log.trace("Eine maxId von 0 wurde zurückgegeben, da keine Events vorhanden sind.");
e.printStackTrace();
return 0; return 0;
} }
} }

View File

@ -1,7 +1,6 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import mops.gruppen2.domain.Account;
import mops.gruppen2.domain.Group; import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.GroupType; import mops.gruppen2.domain.GroupType;
import mops.gruppen2.domain.Role; import mops.gruppen2.domain.Role;
@ -24,8 +23,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; 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. * Es werden übergebene Gruppen bearbeitet und dementsprechend Events erzeugt und gespeichert.
@ -38,13 +35,11 @@ public class GroupService {
private final EventStoreService eventStoreService; private final EventStoreService eventStoreService;
private final ValidationService validationService; private final ValidationService validationService;
private final InviteService inviteService; private final InviteService inviteService;
private final ProjectionService projectionService;
public GroupService(EventStoreService eventStoreService, ValidationService validationService, InviteService inviteService, ProjectionService projectionService) { public GroupService(EventStoreService eventStoreService, ValidationService validationService, InviteService inviteService) {
this.eventStoreService = eventStoreService; this.eventStoreService = eventStoreService;
this.validationService = validationService; this.validationService = validationService;
this.inviteService = inviteService; this.inviteService = inviteService;
this.projectionService = projectionService;
} }
@ -56,11 +51,11 @@ public class GroupService {
* Zudem wird der Gruppentitel und die Gruppenbeschreibung erzeugt, welche vorher der Methode übergeben wurden. * Zudem wird der Gruppentitel und die Gruppenbeschreibung erzeugt, welche vorher der Methode übergeben wurden.
* Aus diesen Event-Objekten wird eine Liste erzeugt, welche daraufhin mithilfe des EventServices gesichert wird. * Aus diesen Event-Objekten wird eine Liste erzeugt, welche daraufhin mithilfe des EventServices gesichert wird.
* *
* @param account Keycloak-Account * @param user Keycloak-Account
* @param title Gruppentitel * @param title Gruppentitel
* @param description Gruppenbeschreibung * @param description Gruppenbeschreibung
*/ */
public Group createGroup(Account account, public Group createGroup(User user,
String title, String title,
String description, String description,
Visibility visibility, Visibility visibility,
@ -73,19 +68,21 @@ public class GroupService {
//TODO: etwas auslagern? //TODO: etwas auslagern?
events.add(new CreateGroupEvent(groupId, events.add(new CreateGroupEvent(groupId,
account.getName(), user.getId(),
parent, parent,
groupType, groupType,
visibility, visibility,
userLimit)); userLimit));
events.add(new AddUserEvent(groupId, new User(account))); events.add(new AddUserEvent(groupId, user));
events.add(new UpdateGroupTitleEvent(groupId, account.getName(), title)); events.add(new UpdateGroupTitleEvent(groupId, user.getId(), title));
events.add(new UpdateGroupDescriptionEvent(groupId, account.getName(), description)); events.add(new UpdateGroupDescriptionEvent(groupId, user.getId(), description));
events.add(new UpdateRoleEvent(groupId, account.getName(), ADMIN)); events.add(new UpdateRoleEvent(groupId, user.getId(), Role.ADMIN));
inviteService.createLink(groupId); inviteService.createLink(groupId);
eventStoreService.saveAll(events); eventStoreService.saveAll(events);
log.trace("Es wurde eine Gruppe erstellt. ({})", visibility);
return ProjectionService.projectSingleGroup(events); return ProjectionService.projectSingleGroup(events);
} }
@ -100,84 +97,19 @@ public class GroupService {
* *
* @param newUsers Userliste * @param newUsers Userliste
* @param group Gruppe * @param group Gruppe
* @param account Ausführender User * @param user Ausführender User
*/ */
public void addUsersToGroup(List<User> newUsers, Group group, Account account) { public void addUsersToGroup(List<User> newUsers, Group group, User user) {
updateUserLimit(account, group, getAdjustedUserLimit(newUsers, group)); updateUserLimit(user, group, getAdjustedUserLimit(newUsers, group));
List<Event> events = newUsers.stream() List<Event> events = newUsers.stream()
.filter(user -> !group.getMembers().contains(user)) .filter(newUser -> !group.getMembers().contains(newUser))
.map(user -> new AddUserEvent(group.getId(), user)) .map(newUser -> new AddUserEvent(group.getId(), newUser))
.collect(Collectors.toList()); .collect(Collectors.toList());
eventStoreService.saveAll(events); eventStoreService.saveAll(events);
} }
void toggleMemberRole(User user, UUID groupId) throws EventException {
UpdateRoleEvent updateRoleEvent;
Group group = projectionService.projectSingleGroup(groupId);
validationService.throwIfNotInGroup(group, user);
if (group.getRoles().get(user.getId()) == ADMIN) {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), Role.MEMBER);
} else {
updateRoleEvent = new UpdateRoleEvent(group.getId(), user.getId(), ADMIN);
}
eventStoreService.saveEvent(updateRoleEvent);
}
public void deleteUser(Account account, User user, Group group) throws EventException {
changeRoleIfLastAdmin(account, group);
validationService.throwIfNotInGroup(group, user);
deleteUser(user, group.getId());
if (validationService.checkIfGroupEmpty(group.getId())) {
deleteGroup(user.getId(), group.getId());
}
}
private void promoteVeteranMember(Account account, Group group) {
if (validationService.checkIfLastAdmin(account, group)) {
User newAdmin = getVeteranMember(account, group);
toggleMemberRole(newAdmin, group.getId());
}
}
public void changeRoleIfLastAdmin(Account account, Group group) {
if (group.getMembers().size() <= 1) {
return;
}
promoteVeteranMember(account, group);
}
public void changeRole(Account account, User user, Group group) {
if (user.getId().equals(account.getName())) {
if (group.getMembers().size() <= 1) {
validationService.throwIfLastAdmin(account, group);
}
promoteVeteranMember(account, group);
}
toggleMemberRole(user, group.getId());
}
// ############################### GRUPEN ANFRAGEN ###########################################
static User getVeteranMember(Account account, Group group) {
List<User> members = group.getMembers();
String newAdminId;
if (members.get(0).getId().equals(account.getName())) {
newAdminId = members.get(1).getId();
} else {
newAdminId = members.get(0).getId();
}
return new User(newAdminId);
}
/** /**
* Ermittelt ein passendes Teilnehmermaximum. * Ermittelt ein passendes Teilnehmermaximum.
* Reicht das alte Maximum, wird dieses zurückgegeben. * Reicht das alte Maximum, wird dieses zurückgegeben.
@ -188,50 +120,74 @@ public class GroupService {
* *
* @return Das neue Teilnehmermaximum * @return Das neue Teilnehmermaximum
*/ */
static long getAdjustedUserLimit(List<User> newUsers, Group group) { private static long getAdjustedUserLimit(List<User> newUsers, Group group) {
return Math.max(group.getMembers().size() + newUsers.size(), return Math.max(group.getMembers().size() + newUsers.size(), group.getMembers().size());
group.getMembers().size()); }
/**
* Wechselt die Rolle eines Teilnehmers von Admin zu Member oder andersherum.
*
* @param user Teilnehmer, welcher geändert wird
* @param group Gruppe, in welcher sih der Teilnehmer befindet
*
* @throws EventException Falls der User nicht gefunden wird
*/
public void toggleMemberRole(User user, Group group) throws EventException {
validationService.throwIfNotInGroup(group, user);
Role role = group.getRoles().get(user.getId());
Event updateRoleEvent = new UpdateRoleEvent(group, user, role.toggle());
eventStoreService.saveEvent(updateRoleEvent);
} }
// ################################# SINGLE EVENTS ########################################### // ################################# SINGLE EVENTS ###########################################
public void deleteUser(User user, UUID groupId) { public void addUser(User user, Group group) {
DeleteUserEvent event = new DeleteUserEvent(groupId, user.getId()); validationService.throwIfUserAlreadyInGroup(group, user);
AddUserEvent event = new AddUserEvent(group, user);
eventStoreService.saveEvent(event); eventStoreService.saveEvent(event);
} }
public void deleteGroup(String userId, UUID groupId) { public void deleteUser(User user, Group group) throws EventException {
DeleteGroupEvent event = new DeleteGroupEvent(groupId, userId); validationService.throwIfNotInGroup(group, user);
inviteService.destroyLink(groupId); validationService.throwIfLastAdmin(user, group);
DeleteUserEvent event = new DeleteUserEvent(group, user);
eventStoreService.saveEvent(event);
if (validationService.checkIfGroupEmpty(group)) {
deleteGroup(user, group);
}
}
public void deleteGroup(User user, Group group) {
inviteService.destroyLink(group);
DeleteGroupEvent event = new DeleteGroupEvent(group, user);
eventStoreService.saveEvent(event);
log.trace("Eine Gruppe wurde gelöscht ({})", group);
}
//TODO: Validate title
public void updateTitle(User user, Group group, String title) {
UpdateGroupTitleEvent event = new UpdateGroupTitleEvent(group, user, title);
eventStoreService.saveEvent(event); eventStoreService.saveEvent(event);
} }
public void updateDescription(Account account, UUID groupId, String description) { //TODO: Validate description
UpdateGroupDescriptionEvent event = new UpdateGroupDescriptionEvent(groupId, public void updateDescription(User user, Group group, String description) {
account.getName(), UpdateGroupDescriptionEvent event = new UpdateGroupDescriptionEvent(group, user, description);
description);
eventStoreService.saveEvent(event); eventStoreService.saveEvent(event);
} }
public void updateUserLimit(Account account, Group group, long userLimit) { //TODO: Validate limit
UpdateUserLimitEvent event = new UpdateUserLimitEvent(group.getId(), public void updateUserLimit(User user, Group group, long userLimit) {
account.getName(), UpdateUserLimitEvent event = new UpdateUserLimitEvent(group, user, userLimit);
userLimit);
eventStoreService.saveEvent(event); eventStoreService.saveEvent(event);
} }
public void addUser(Account account, UUID groupId) {
AddUserEvent event = new AddUserEvent(groupId, new User(account));
eventStoreService.saveEvent(event);
}
public void updateTitle(Account account, UUID groupId, String title) {
UpdateGroupTitleEvent event = new UpdateGroupTitleEvent(groupId,
account.getName(),
title);
eventStoreService.saveEvent(event);
}
} }

View File

@ -1,6 +1,7 @@
package mops.gruppen2.service; package mops.gruppen2.service;
import lombok.extern.log4j.Log4j2; import lombok.extern.log4j.Log4j2;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.dto.InviteLinkDTO; import mops.gruppen2.domain.dto.InviteLinkDTO;
import mops.gruppen2.domain.exception.InvalidInviteException; import mops.gruppen2.domain.exception.InvalidInviteException;
import mops.gruppen2.domain.exception.NoInviteExistException; import mops.gruppen2.domain.exception.NoInviteExistException;
@ -20,27 +21,35 @@ public class InviteService {
} }
void createLink(UUID groupId) { void createLink(UUID groupId) {
inviteRepository.save(new InviteLinkDTO(null, groupId.toString(), UUID.randomUUID().toString())); inviteRepository.save(new InviteLinkDTO(null,
groupId.toString(),
UUID.randomUUID().toString()));
} }
void destroyLink(UUID groupId) { void destroyLink(UUID groupId) {
inviteRepository.deleteLinkOfGroup(groupId.toString()); inviteRepository.deleteLinkOfGroup(groupId.toString());
} }
void destroyLink(Group group) {
inviteRepository.deleteLinkOfGroup(group.getId().toString());
}
public UUID getGroupIdFromLink(String link) { public UUID getGroupIdFromLink(String link) {
try { try {
return UUID.fromString(inviteRepository.findGroupIdByLink(link)); return UUID.fromString(inviteRepository.findGroupIdByLink(link));
} catch (Exception e) { } catch (Exception e) {
log.error("Gruppe zu Link ({}) konnte nicht gefunden werden!", link); log.error("Gruppe zu Link ({}) konnte nicht gefunden werden!", link);
e.printStackTrace();
throw new InvalidInviteException(link); throw new InvalidInviteException(link);
} }
} }
public String getLinkByGroupId(UUID groupId) { public String getLinkByGroup(UUID groupId) {
try { try {
return inviteRepository.findLinkByGroupId(groupId.toString()); return inviteRepository.findLinkByGroupId(groupId.toString());
} catch (Exception e) { } catch (Exception e) {
log.error("Link zu Gruppe ({}) konnte nicht gefunden werden!", groupId); log.error("Link zu Gruppe ({}) konnte nicht gefunden werden!", groupId);
e.printStackTrace();
throw new NoInviteExistException(groupId.toString()); throw new NoInviteExistException(groupId.toString());
} }
} }

View File

@ -48,7 +48,6 @@ public class ProjectionService {
Map<UUID, Group> groupMap = new HashMap<>(); Map<UUID, Group> groupMap = new HashMap<>();
events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupId()))); events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupId())));
log.trace("{} Events wurden projiziert!", events.size());
return new ArrayList<>(groupMap.values()); return new ArrayList<>(groupMap.values());
} }
@ -66,7 +65,6 @@ public class ProjectionService {
Group group = new Group(); Group group = new Group();
events.forEach(event -> event.apply(group)); events.forEach(event -> event.apply(group));
log.trace("{} Events wurden projiziert!", events.size());
return group; return group;
} }
@ -175,6 +173,7 @@ public class ProjectionService {
/** /**
* Gibt die Gruppe zurück, die zu der übergebenen Id passt. * Gibt die Gruppe zurück, die zu der übergebenen Id passt.
* Enthält alle verfügbaren Informationen, also auch User (langsam). * Enthält alle verfügbaren Informationen, also auch User (langsam).
* Gibt eine leere Gruppe zurück, falls die Id leer ist.
* *
* @param groupId Die Id der gesuchten Gruppe * @param groupId Die Id der gesuchten Gruppe
* *
@ -183,11 +182,16 @@ public class ProjectionService {
* @throws GroupNotFoundException Wenn die Gruppe nicht gefunden wird * @throws GroupNotFoundException Wenn die Gruppe nicht gefunden wird
*/ */
public Group projectSingleGroup(UUID groupId) throws GroupNotFoundException { public Group projectSingleGroup(UUID groupId) throws GroupNotFoundException {
if (IdService.idIsEmpty(groupId)) {
return new Group();
}
try { try {
List<Event> events = eventStoreService.findGroupEvents(groupId); List<Event> events = eventStoreService.findGroupEvents(groupId);
return projectGroups(events).get(0); return projectGroups(events).get(0);
} catch (IndexOutOfBoundsException e) { } catch (IndexOutOfBoundsException e) {
log.error("Gruppe {} wurde nicht gefunden!", groupId.toString()); log.error("Gruppe {} wurde nicht gefunden!", groupId.toString());
e.printStackTrace();
throw new GroupNotFoundException(ProjectionService.class.toString()); throw new GroupNotFoundException(ProjectionService.class.toString());
} }
} }

View File

@ -41,6 +41,7 @@ public class ValidationService {
return groups; return groups;
} }
//TODO: what the fuck
public void throwIfGroupNotExisting(String title) { public void throwIfGroupNotExisting(String title) {
if (title == null) { if (title == null) {
throw new GroupNotFoundException("@details"); throw new GroupNotFoundException("@details");
@ -69,10 +70,15 @@ public class ValidationService {
} }
} }
//TODO: necessary?
boolean checkIfGroupEmpty(UUID groupId) { boolean checkIfGroupEmpty(UUID groupId) {
return projectionService.projectSingleGroup(groupId).getMembers().isEmpty(); return projectionService.projectSingleGroup(groupId).getMembers().isEmpty();
} }
boolean checkIfGroupEmpty(Group group) {
return group.getMembers().isEmpty();
}
public void throwIfNoAdmin(Group group, User user) { public void throwIfNoAdmin(Group group, User user) {
throwIfNoAccessToPrivate(group, user); throwIfNoAccessToPrivate(group, user);
if (group.getRoles().get(user.getId()) != ADMIN) { if (group.getRoles().get(user.getId()) != ADMIN) {
@ -93,15 +99,15 @@ public class ValidationService {
return false; return false;
} }
void throwIfLastAdmin(Account account, Group group) { void throwIfLastAdmin(User user, Group group) {
if (checkIfLastAdmin(account, group)) { if (checkIfLastAdmin(user, group)) {
throw new NoAdminAfterActionException("Du bist letzter Admin!"); throw new NoAdminAfterActionException("Du bist letzter Admin!");
} }
} }
boolean checkIfLastAdmin(Account account, Group group) { boolean checkIfLastAdmin(User user, Group group) {
for (Map.Entry<String, Role> entry : group.getRoles().entrySet()) { for (Map.Entry<String, Role> entry : group.getRoles().entrySet()) {
if (entry.getValue() == ADMIN && !(entry.getKey().equals(account.getName()))) { if (entry.getValue() == ADMIN && !(entry.getKey().equals(user.getId()))) {
return false; return false;
} }
} }

View File

@ -58,7 +58,7 @@ class GroupServiceTest {
@BeforeEach @BeforeEach
void setUp() { void setUp() {
groupService = new GroupService(eventStoreService, validationService, inviteService, projectionService); groupService = new GroupService(eventStoreService, validationService, inviteService);
eventRepository.deleteAll(); eventRepository.deleteAll();
//noinspection SqlResolve //noinspection SqlResolve
template.execute("ALTER TABLE event ALTER COLUMN event_id RESTART WITH 1"); template.execute("ALTER TABLE event ALTER COLUMN event_id RESTART WITH 1");