From 319b073e66a68ceee397d52f19c73e016fc65554 Mon Sep 17 00:00:00 2001 From: Christoph Date: Thu, 16 Apr 2020 15:24:08 +0200 Subject: [PATCH] remove fontawesome + fix links + events modify cache + fix search --- .../{WebConfig.java => FormatterConfig.java} | 2 +- .../gruppen2/domain/event/AddMemberEvent.java | 6 + .../domain/event/CreateGroupEvent.java | 7 ++ .../domain/event/DestroyGroupEvent.java | 6 + .../mops/gruppen2/domain/event/Event.java | 12 +- .../domain/event/KickMemberEvent.java | 6 + .../domain/event/SetDescriptionEvent.java | 4 + .../domain/event/SetInviteLinkEvent.java | 7 ++ .../gruppen2/domain/event/SetLimitEvent.java | 4 + .../gruppen2/domain/event/SetParentEvent.java | 4 + .../gruppen2/domain/event/SetTitleEvent.java | 4 + .../gruppen2/domain/event/SetTypeEvent.java | 7 ++ .../domain/event/UpdateRoleEvent.java | 4 + .../domain/model/group/SortHelper.java | 4 +- .../domain/service/SearchService.java | 11 +- .../gruppen2/infrastructure/GroupCache.java | 117 ++++++++++++++---- .../controller/SearchAndInviteController.java | 2 +- .../resources/application-heroku.properties | 1 - .../templates/fragments/general.html | 2 +- 19 files changed, 165 insertions(+), 45 deletions(-) rename src/main/java/mops/gruppen2/config/{WebConfig.java => FormatterConfig.java} (88%) diff --git a/src/main/java/mops/gruppen2/config/WebConfig.java b/src/main/java/mops/gruppen2/config/FormatterConfig.java similarity index 88% rename from src/main/java/mops/gruppen2/config/WebConfig.java rename to src/main/java/mops/gruppen2/config/FormatterConfig.java index ab5607e..e5a2ba3 100644 --- a/src/main/java/mops/gruppen2/config/WebConfig.java +++ b/src/main/java/mops/gruppen2/config/FormatterConfig.java @@ -6,7 +6,7 @@ import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration -public class WebConfig implements WebMvcConfigurer { +public class FormatterConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { diff --git a/src/main/java/mops/gruppen2/domain/event/AddMemberEvent.java b/src/main/java/mops/gruppen2/domain/event/AddMemberEvent.java index b1c2bbe..e294cc1 100644 --- a/src/main/java/mops/gruppen2/domain/event/AddMemberEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/AddMemberEvent.java @@ -9,6 +9,7 @@ import mops.gruppen2.domain.exception.IdMismatchException; import mops.gruppen2.domain.exception.UserAlreadyExistsException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.User; +import mops.gruppen2.infrastructure.GroupCache; import java.util.UUID; @@ -32,6 +33,11 @@ public class AddMemberEvent extends Event { } } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.usersPut(target, group); + } + @Override protected void applyEvent(Group group) throws UserAlreadyExistsException, GroupFullException { group.addMember(target, user); diff --git a/src/main/java/mops/gruppen2/domain/event/CreateGroupEvent.java b/src/main/java/mops/gruppen2/domain/event/CreateGroupEvent.java index ac9c826..c3457cb 100644 --- a/src/main/java/mops/gruppen2/domain/event/CreateGroupEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/CreateGroupEvent.java @@ -6,6 +6,7 @@ import lombok.Value; import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.BadArgumentException; import mops.gruppen2.domain.model.group.Group; +import mops.gruppen2.infrastructure.GroupCache; import java.time.LocalDateTime; import java.util.UUID; @@ -23,6 +24,12 @@ public class CreateGroupEvent extends Event { this.date = date; } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.groupsPut(groupid, group); + cache.linksPut(group.getLink(), group); + } + @Override protected void applyEvent(Group group) throws BadArgumentException { group.setId(groupid); diff --git a/src/main/java/mops/gruppen2/domain/event/DestroyGroupEvent.java b/src/main/java/mops/gruppen2/domain/event/DestroyGroupEvent.java index 4c94aab..432c174 100644 --- a/src/main/java/mops/gruppen2/domain/event/DestroyGroupEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/DestroyGroupEvent.java @@ -5,6 +5,7 @@ import lombok.Value; import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; +import mops.gruppen2.infrastructure.GroupCache; import java.util.UUID; @@ -17,6 +18,11 @@ public class DestroyGroupEvent extends Event { super(groupId, exec, null); } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.groupsRemove(group); + } + @Override protected void applyEvent(Group group) throws NoAccessException { group.destroy(exec); diff --git a/src/main/java/mops/gruppen2/domain/event/Event.java b/src/main/java/mops/gruppen2/domain/event/Event.java index abb2ceb..af53a7e 100644 --- a/src/main/java/mops/gruppen2/domain/event/Event.java +++ b/src/main/java/mops/gruppen2/domain/event/Event.java @@ -69,8 +69,8 @@ public abstract class Event { checkGroupIdMatch(group.getId()); group.updateVersion(version); - applyEvent(group); updateCache(cache, group); + applyEvent(group); } private void checkGroupIdMatch(UUID groupid) throws IdMismatchException { @@ -84,15 +84,7 @@ public abstract class Event { } } - private void updateCache(GroupCache cache, Group group) { - if (this instanceof CreateGroupEvent) { - cache.put(group); - } - - if (this instanceof DestroyGroupEvent) { - cache.remove(group); - } - } + protected abstract void updateCache(GroupCache cache, Group group); protected abstract void applyEvent(Group group) throws EventException; diff --git a/src/main/java/mops/gruppen2/domain/event/KickMemberEvent.java b/src/main/java/mops/gruppen2/domain/event/KickMemberEvent.java index ad1d0f1..d5341d0 100644 --- a/src/main/java/mops/gruppen2/domain/event/KickMemberEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/KickMemberEvent.java @@ -6,6 +6,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.LastAdminException; import mops.gruppen2.domain.exception.UserNotFoundException; import mops.gruppen2.domain.model.group.Group; +import mops.gruppen2.infrastructure.GroupCache; import java.util.UUID; @@ -21,6 +22,11 @@ public class KickMemberEvent extends Event { super(groupId, exec, target); } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.usersRemove(target, group); + } + @Override protected void applyEvent(Group group) throws UserNotFoundException, LastAdminException { group.kickMember(target); diff --git a/src/main/java/mops/gruppen2/domain/event/SetDescriptionEvent.java b/src/main/java/mops/gruppen2/domain/event/SetDescriptionEvent.java index 9180808..f400d98 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetDescriptionEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetDescriptionEvent.java @@ -7,6 +7,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.wrapper.Description; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -27,6 +28,9 @@ public class SetDescriptionEvent extends Event { this.description = description; } + @Override + protected void updateCache(GroupCache cache, Group group) {} + @Override protected void applyEvent(Group group) throws NoAccessException { group.setDescription(exec, description); diff --git a/src/main/java/mops/gruppen2/domain/event/SetInviteLinkEvent.java b/src/main/java/mops/gruppen2/domain/event/SetInviteLinkEvent.java index 095bf6c..72979c4 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetInviteLinkEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetInviteLinkEvent.java @@ -7,6 +7,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.wrapper.Link; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -24,6 +25,12 @@ public class SetInviteLinkEvent extends Event { this.link = link; } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.linksRemove(group.getLink()); + cache.linksPut(link.getValue(), group); + } + @Override protected void applyEvent(Group group) throws NoAccessException { group.setLink(exec, link); diff --git a/src/main/java/mops/gruppen2/domain/event/SetLimitEvent.java b/src/main/java/mops/gruppen2/domain/event/SetLimitEvent.java index e6e4be0..f1b06eb 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetLimitEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetLimitEvent.java @@ -8,6 +8,7 @@ import mops.gruppen2.domain.exception.BadArgumentException; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.wrapper.Limit; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -25,6 +26,9 @@ public class SetLimitEvent extends Event { this.limit = limit; } + @Override + protected void updateCache(GroupCache cache, Group group) {} + @Override protected void applyEvent(Group group) throws BadArgumentException, NoAccessException { group.setLimit(exec, limit); diff --git a/src/main/java/mops/gruppen2/domain/event/SetParentEvent.java b/src/main/java/mops/gruppen2/domain/event/SetParentEvent.java index bed9a54..98f5fe9 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetParentEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetParentEvent.java @@ -7,6 +7,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.wrapper.Parent; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -24,6 +25,9 @@ public class SetParentEvent extends Event { this.parent = parent; } + @Override + protected void updateCache(GroupCache cache, Group group) {} + @Override protected void applyEvent(Group group) throws NoAccessException { group.setParent(exec, parent); diff --git a/src/main/java/mops/gruppen2/domain/event/SetTitleEvent.java b/src/main/java/mops/gruppen2/domain/event/SetTitleEvent.java index 11f9bd2..1a5acd6 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetTitleEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetTitleEvent.java @@ -7,6 +7,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.NoAccessException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.wrapper.Title; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -27,6 +28,9 @@ public class SetTitleEvent extends Event { this.title = title; } + @Override + protected void updateCache(GroupCache cache, Group group) {} + @Override protected void applyEvent(Group group) throws NoAccessException { group.setTitle(exec, title); diff --git a/src/main/java/mops/gruppen2/domain/event/SetTypeEvent.java b/src/main/java/mops/gruppen2/domain/event/SetTypeEvent.java index 0bd5b43..b62e09d 100644 --- a/src/main/java/mops/gruppen2/domain/event/SetTypeEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/SetTypeEvent.java @@ -7,6 +7,7 @@ import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.EventException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.Type; +import mops.gruppen2.infrastructure.GroupCache; import javax.validation.Valid; import java.util.UUID; @@ -25,6 +26,12 @@ public class SetTypeEvent extends Event { this.type = type; } + @Override + protected void updateCache(GroupCache cache, Group group) { + cache.typesRemove(group); + cache.typesPut(type, group); + } + @Override protected void applyEvent(Group group) throws EventException { group.setType(exec, type); diff --git a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java index 7aee184..4df2fc8 100644 --- a/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java +++ b/src/main/java/mops/gruppen2/domain/event/UpdateRoleEvent.java @@ -8,6 +8,7 @@ import mops.gruppen2.domain.exception.LastAdminException; import mops.gruppen2.domain.exception.UserNotFoundException; import mops.gruppen2.domain.model.group.Group; import mops.gruppen2.domain.model.group.Role; +import mops.gruppen2.infrastructure.GroupCache; import java.util.UUID; @@ -27,6 +28,9 @@ public class UpdateRoleEvent extends Event { this.role = role; } + @Override + protected void updateCache(GroupCache cache, Group group) {} + @Override protected void applyEvent(Group group) throws UserNotFoundException, LastAdminException { group.memberPutRole(target, role); diff --git a/src/main/java/mops/gruppen2/domain/model/group/SortHelper.java b/src/main/java/mops/gruppen2/domain/model/group/SortHelper.java index f1f2e36..808f12c 100644 --- a/src/main/java/mops/gruppen2/domain/model/group/SortHelper.java +++ b/src/main/java/mops/gruppen2/domain/model/group/SortHelper.java @@ -13,7 +13,7 @@ public final class SortHelper { * * @param groups Die Liste von Gruppen die sortiert werden soll */ - public static List sortByGroupType(List groups) { + public static void sortByGroupType(List groups) { groups.sort((Group g1, Group g2) -> { if (g1.getType() == Type.LECTURE) { return -1; @@ -24,8 +24,6 @@ public final class SortHelper { return 0; }); - - return groups; } public static List sortByMemberRole(List memberships) { diff --git a/src/main/java/mops/gruppen2/domain/service/SearchService.java b/src/main/java/mops/gruppen2/domain/service/SearchService.java index f87bf1b..d2bedeb 100644 --- a/src/main/java/mops/gruppen2/domain/service/SearchService.java +++ b/src/main/java/mops/gruppen2/domain/service/SearchService.java @@ -4,9 +4,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.EventException; import mops.gruppen2.domain.model.group.Group; +import mops.gruppen2.domain.model.group.SortHelper; import mops.gruppen2.infrastructure.GroupCache; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -29,10 +31,12 @@ public class SearchService { * @throws EventException Projektionsfehler */ //TODO: search in lectures - public List searchPublicGroups(String search, String principal) { - List groups = groupCache.publics(); - + public List search(String search, String principal) { + List groups = new ArrayList<>(); + groups.addAll(groupCache.publics()); + groups.addAll(groupCache.lectures()); groups = removeUserGroups(groups, principal); + SortHelper.sortByGroupType(groups); if (search.isEmpty()) { return groups; @@ -50,5 +54,4 @@ public class SearchService { .filter(group -> !group.isMember(principal)) .collect(Collectors.toList()); } - } diff --git a/src/main/java/mops/gruppen2/infrastructure/GroupCache.java b/src/main/java/mops/gruppen2/infrastructure/GroupCache.java index baef40f..ef23274 100644 --- a/src/main/java/mops/gruppen2/infrastructure/GroupCache.java +++ b/src/main/java/mops/gruppen2/infrastructure/GroupCache.java @@ -1,19 +1,24 @@ package mops.gruppen2.infrastructure; import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; import mops.gruppen2.domain.exception.GroupNotFoundException; import mops.gruppen2.domain.model.group.Group; +import mops.gruppen2.domain.model.group.Type; import mops.gruppen2.domain.service.EventStoreService; import mops.gruppen2.domain.service.helper.ProjectionHelper; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; -import java.util.stream.Collectors; +@Log4j2 @RequiredArgsConstructor @Component @Scope("singleton") @@ -22,20 +27,21 @@ public class GroupCache { private final EventStoreService eventStoreService; private final Map groups = new HashMap<>(); + private final Map links = new HashMap<>(); + private final Map> users = new HashMap<>(); + private final Map> types = new EnumMap<>(Type.class); + + + // ######################################## CACHE ########################################### + public void init() { ProjectionHelper.project(groups, eventStoreService.findAllEvents(), this); } - public void put(Group group) { - groups.put(group.getId(), group); - } - public void remove(Group group) { - groups.remove(group.getId()); - } + // ########################################### GETTERS ####################################### - // Getters public Group group(UUID groupid) { if (!groups.containsKey(groupid)) { @@ -46,33 +52,96 @@ public class GroupCache { } public Group group(String link) { - return groups.values().stream() - .filter(group -> group.getLink().equals(link)) - .findFirst() - .orElseThrow(() -> new GroupNotFoundException("Link nicht im Cache.")); + if (!links.containsKey(link)) { + throw new GroupNotFoundException("Link ist nicht im Cache."); + } + + return links.get(link); } public List userGroups(String userid) { - return groups.values().stream() - .filter(group -> group.isMember(userid)) - .collect(Collectors.toUnmodifiableList()); + if (!users.containsKey(userid)) { + return Collections.emptyList(); + } + + return Collections.unmodifiableList(users.get(userid)); } public List publics() { - return groups.values().stream() - .filter(Group::isPublic) - .collect(Collectors.toUnmodifiableList()); + if (!types.containsKey(Type.PUBLIC)) { + return Collections.emptyList(); + } + + return Collections.unmodifiableList(types.get(Type.PUBLIC)); } public List privates() { - return groups.values().stream() - .filter(Group::isPrivate) - .collect(Collectors.toUnmodifiableList()); + if (!types.containsKey(Type.PRIVATE)) { + return Collections.emptyList(); + } + + return Collections.unmodifiableList(types.get(Type.PRIVATE)); } public List lectures() { - return groups.values().stream() - .filter(Group::isLecture) - .collect(Collectors.toUnmodifiableList()); + if (!types.containsKey(Type.LECTURE)) { + return Collections.emptyList(); + } + + return Collections.unmodifiableList(types.get(Type.LECTURE)); + } + + + // ######################################## SETTERS ########################################## + + + public void usersPut(String userid, Group group) { + if (!users.containsKey(userid)) { + users.put(userid, new ArrayList<>()); + log.debug("Ein User wurde dem Cache hinzugefügt."); + } + + users.get(userid).add(group); + } + + public void usersRemove(String target, Group group) { + if (!users.containsKey(target)) { + return; + } + + users.get(target).remove(group); + } + + public void groupsPut(UUID groupid, Group group) { + groups.put(groupid, group); + } + + public void groupsRemove(Group group) { + groups.remove(group.getId()); + } + + public void linksPut(String link, Group group) { + links.put(link, group); + } + + public void linksRemove(String link) { + links.remove(link); + } + + public void typesPut(Type type, Group group) { + if (!types.containsKey(type)) { + types.put(type, new ArrayList<>()); + log.debug("Ein Typ wurde dem Cache hinzugefügt."); + } + + types.get(type).add(group); + } + + public void typesRemove(Group group) { + if (!types.containsKey(group.getType())) { + return; + } + + types.get(group.getType()).remove(group); } } diff --git a/src/main/java/mops/gruppen2/infrastructure/controller/SearchAndInviteController.java b/src/main/java/mops/gruppen2/infrastructure/controller/SearchAndInviteController.java index e9e9e16..6a8b90e 100644 --- a/src/main/java/mops/gruppen2/infrastructure/controller/SearchAndInviteController.java +++ b/src/main/java/mops/gruppen2/infrastructure/controller/SearchAndInviteController.java @@ -48,7 +48,7 @@ public class SearchAndInviteController { @RequestParam("string") String search) { String principal = token.getName(); - List groups = searchService.searchPublicGroups(search, principal); + List groups = searchService.search(search, principal); model.addAttribute("groups", groups); diff --git a/src/main/resources/application-heroku.properties b/src/main/resources/application-heroku.properties index 2ddb9d8..a2a87c7 100644 --- a/src/main/resources/application-heroku.properties +++ b/src/main/resources/application-heroku.properties @@ -10,7 +10,6 @@ spring.datasource.url = mysql://b4b665d39d0670:cc933ff7@eu spring.datasource.username = b4b665d39d0670 spring.datasource.password = cc933ff7 - # Misc management.endpoints.web.exposure.include = info,health server.error.include-stacktrace = always diff --git a/src/main/resources/templates/fragments/general.html b/src/main/resources/templates/fragments/general.html index 5b8f402..34e4b56 100644 --- a/src/main/resources/templates/fragments/general.html +++ b/src/main/resources/templates/fragments/general.html @@ -7,7 +7,7 @@ - +