@ -1,6 +1,5 @@
|
|||||||
package mops.gruppen2.config;
|
package mops.gruppen2.config;
|
||||||
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Profile;
|
import org.springframework.context.annotation.Profile;
|
||||||
@ -16,7 +15,6 @@ import java.util.Collections;
|
|||||||
|
|
||||||
@Profile("dev")
|
@Profile("dev")
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableCaching
|
|
||||||
@EnableSwagger2
|
@EnableSwagger2
|
||||||
public class SwaggerConfig {
|
public class SwaggerConfig {
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import mops.gruppen2.domain.exception.BadArgumentException;
|
|||||||
import mops.gruppen2.domain.exception.EventException;
|
import mops.gruppen2.domain.exception.EventException;
|
||||||
import mops.gruppen2.domain.exception.IdMismatchException;
|
import mops.gruppen2.domain.exception.IdMismatchException;
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -31,7 +32,6 @@ import java.util.UUID;
|
|||||||
@NoArgsConstructor // Lombok needs a default constructor in the base class
|
@NoArgsConstructor // Lombok needs a default constructor in the base class
|
||||||
public abstract class Event {
|
public abstract class Event {
|
||||||
|
|
||||||
|
|
||||||
@JsonProperty("groupid")
|
@JsonProperty("groupid")
|
||||||
protected UUID groupid;
|
protected UUID groupid;
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ public abstract class Event {
|
|||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Group apply(Group group) throws EventException {
|
public void apply(Group group, GroupCache cache) throws EventException {
|
||||||
log.trace("Event wird angewendet:\t{}", this);
|
log.trace("Event wird angewendet:\t{}", this);
|
||||||
|
|
||||||
if (version == 0) {
|
if (version == 0) {
|
||||||
@ -68,23 +68,32 @@ public abstract class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
checkGroupIdMatch(group.getId());
|
checkGroupIdMatch(group.getId());
|
||||||
group.update(version);
|
group.updateVersion(version);
|
||||||
applyEvent(group);
|
applyEvent(group);
|
||||||
|
updateCache(cache, group);
|
||||||
return group;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGroupIdMatch(UUID groupId) throws IdMismatchException {
|
private void checkGroupIdMatch(UUID groupid) throws IdMismatchException {
|
||||||
// CreateGroupEvents müssen die Id erst initialisieren
|
// CreateGroupEvents müssen die Id erst initialisieren
|
||||||
if (this instanceof CreateGroupEvent) {
|
if (this instanceof CreateGroupEvent) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!groupid.equals(groupId)) {
|
if (!this.groupid.equals(groupid)) {
|
||||||
throw new IdMismatchException("Das Event gehört zu einer anderen Gruppe");
|
throw new IdMismatchException("Das Event gehört zu einer anderen Gruppe");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateCache(GroupCache cache, Group group) {
|
||||||
|
if (this instanceof CreateGroupEvent) {
|
||||||
|
cache.put(group);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this instanceof DestroyGroupEvent) {
|
||||||
|
cache.remove(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void applyEvent(Group group) throws EventException;
|
protected abstract void applyEvent(Group group) throws EventException;
|
||||||
|
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
@ -10,14 +10,14 @@ import mops.gruppen2.domain.exception.LastAdminException;
|
|||||||
import mops.gruppen2.domain.exception.NoAccessException;
|
import mops.gruppen2.domain.exception.NoAccessException;
|
||||||
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
|
import mops.gruppen2.domain.exception.UserAlreadyExistsException;
|
||||||
import mops.gruppen2.domain.exception.UserNotFoundException;
|
import mops.gruppen2.domain.exception.UserNotFoundException;
|
||||||
import mops.gruppen2.domain.helper.CommonHelper;
|
|
||||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Body;
|
import mops.gruppen2.domain.model.group.wrapper.Body;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Description;
|
import mops.gruppen2.domain.model.group.wrapper.Description;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Limit;
|
import mops.gruppen2.domain.model.group.wrapper.Limit;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Link;
|
import mops.gruppen2.domain.model.group.wrapper.Link;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Title;
|
import mops.gruppen2.domain.model.group.wrapper.Title;
|
||||||
|
import mops.gruppen2.domain.service.helper.CommonHelper;
|
||||||
|
import mops.gruppen2.domain.service.helper.ValidationHelper;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -73,6 +73,7 @@ public class Group {
|
|||||||
|
|
||||||
// ####################################### Members ###########################################
|
// ####################################### Members ###########################################
|
||||||
|
|
||||||
|
|
||||||
public List<User> getMembers() {
|
public List<User> getMembers() {
|
||||||
return SortHelper.sortByMemberRole(new ArrayList<>(memberships.values())).stream()
|
return SortHelper.sortByMemberRole(new ArrayList<>(memberships.values())).stream()
|
||||||
.map(Membership::getUser)
|
.map(Membership::getUser)
|
||||||
@ -210,6 +211,10 @@ public class Group {
|
|||||||
return type == Type.LECTURE;
|
return type == Type.LECTURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasParent() {
|
||||||
|
return !parent.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ######################################## Setters ##########################################
|
// ######################################## Setters ##########################################
|
||||||
|
|
||||||
@ -262,7 +267,7 @@ public class Group {
|
|||||||
this.link = link;
|
this.link = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void update(long version) throws IdMismatchException {
|
public void updateVersion(long version) throws IdMismatchException {
|
||||||
meta = meta.setVersion(version);
|
meta = meta.setVersion(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,4 +315,8 @@ public class Group {
|
|||||||
+ (meta == null ? "meta: null" : meta.toString())
|
+ (meta == null ? "meta: null" : meta.toString())
|
||||||
+ ")";
|
+ ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Group EMPTY() {
|
||||||
|
return new Group();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,4 +56,8 @@ public class User {
|
|||||||
public String format() {
|
public String format() {
|
||||||
return givenname + " " + familyname;
|
return givenname + " " + familyname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMember(Group group) {
|
||||||
|
return group.getMembers().contains(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
|
|||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.Value;
|
import lombok.Value;
|
||||||
import mops.gruppen2.domain.helper.CommonHelper;
|
import mops.gruppen2.domain.service.helper.CommonHelper;
|
||||||
|
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
@ -3,39 +3,26 @@ package mops.gruppen2.domain.service;
|
|||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
|
||||||
import mops.gruppen2.domain.event.AddMemberEvent;
|
import mops.gruppen2.domain.event.AddMemberEvent;
|
||||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
|
||||||
import mops.gruppen2.domain.event.Event;
|
import mops.gruppen2.domain.event.Event;
|
||||||
import mops.gruppen2.domain.event.EventType;
|
import mops.gruppen2.domain.event.EventType;
|
||||||
import mops.gruppen2.domain.event.SetTypeEvent;
|
|
||||||
import mops.gruppen2.domain.exception.BadPayloadException;
|
import mops.gruppen2.domain.exception.BadPayloadException;
|
||||||
import mops.gruppen2.domain.exception.InvalidInviteException;
|
import mops.gruppen2.domain.service.helper.JsonHelper;
|
||||||
import mops.gruppen2.domain.helper.CommonHelper;
|
|
||||||
import mops.gruppen2.domain.helper.JsonHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Type;
|
|
||||||
import mops.gruppen2.persistance.EventRepository;
|
import mops.gruppen2.persistance.EventRepository;
|
||||||
import mops.gruppen2.persistance.dto.EventDTO;
|
import mops.gruppen2.persistance.dto.EventDTO;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
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.event.EventType.CREATEGROUP;
|
|
||||||
import static mops.gruppen2.domain.event.EventType.DESTROYGROUP;
|
import static mops.gruppen2.domain.event.EventType.DESTROYGROUP;
|
||||||
import static mops.gruppen2.domain.event.EventType.SETLINK;
|
import static mops.gruppen2.domain.service.helper.CommonHelper.eventTypesToString;
|
||||||
import static mops.gruppen2.domain.event.EventType.SETTYPE;
|
|
||||||
import static mops.gruppen2.domain.helper.CommonHelper.eventTypesToString;
|
|
||||||
import static mops.gruppen2.domain.helper.CommonHelper.uuidsToString;
|
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
@TraceMethodCalls
|
|
||||||
public class EventStoreService {
|
public class EventStoreService {
|
||||||
|
|
||||||
private final EventRepository eventStore;
|
private final EventRepository eventStore;
|
||||||
@ -77,12 +64,6 @@ public class EventStoreService {
|
|||||||
//########################################### DTOs ###########################################
|
//########################################### DTOs ###########################################
|
||||||
|
|
||||||
|
|
||||||
private static List<EventDTO> getDTOsFromEvents(List<Event> events) {
|
|
||||||
return events.stream()
|
|
||||||
.map(EventStoreService::getDTOFromEvent)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erzeugt aus einem Event Objekt ein EventDTO Objekt.
|
* Erzeugt aus einem Event Objekt ein EventDTO Objekt.
|
||||||
*
|
*
|
||||||
@ -132,81 +113,6 @@ public class EventStoreService {
|
|||||||
// ######################################## QUERIES ##########################################
|
// ######################################## QUERIES ##########################################
|
||||||
|
|
||||||
|
|
||||||
List<Event> findGroupEvents(UUID groupId) {
|
|
||||||
return getEventsFromDTOs(eventStore.findEventDTOsByGroup(Collections.singletonList(groupId.toString())));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sucht alle Events, welche zu einer der übergebenen Gruppen gehören.
|
|
||||||
*
|
|
||||||
* @param groupIds Liste an IDs
|
|
||||||
*
|
|
||||||
* @return Liste an Events
|
|
||||||
*/
|
|
||||||
List<Event> findGroupEvents(List<UUID> groupIds) {
|
|
||||||
List<EventDTO> eventDTOS = new ArrayList<>();
|
|
||||||
|
|
||||||
for (UUID groupId : groupIds) {
|
|
||||||
eventDTOS.addAll(eventStore.findEventDTOsByGroup(Collections.singletonList(groupId.toString())));
|
|
||||||
}
|
|
||||||
|
|
||||||
return getEventsFromDTOs(eventDTOS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Findet alle Events zu Gruppen, welche seit dem neuen Status verändert wurden.
|
|
||||||
*
|
|
||||||
* @param status Die Id des zuletzt gespeicherten Events
|
|
||||||
*
|
|
||||||
* @return Liste von neuen und alten Events
|
|
||||||
*/
|
|
||||||
List<UUID> findChangedGroups(long status) {
|
|
||||||
List<String> changedGroupIds = eventStore.findGroupIdsWhereEventIdGreaterThanStatus(status);
|
|
||||||
|
|
||||||
log.debug("Seit Event {} haben sich {} Gruppen geändert!", status, changedGroupIds.size());
|
|
||||||
|
|
||||||
return CommonHelper.stringsToUUID(changedGroupIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen.
|
|
||||||
*
|
|
||||||
* @return GruppenIds (UUID) als Liste
|
|
||||||
*/
|
|
||||||
List<UUID> findExistingGroupIds() {
|
|
||||||
List<Event> createEvents = findLatestEventsFromGroupsByType(CREATEGROUP,
|
|
||||||
DESTROYGROUP);
|
|
||||||
|
|
||||||
return createEvents.stream()
|
|
||||||
.filter(event -> event instanceof CreateGroupEvent)
|
|
||||||
.map(Event::getGroupid)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UUID> findPublicGroupIds() {
|
|
||||||
List<UUID> groups = findExistingGroupIds();
|
|
||||||
List<Event> typeEvents = findLatestEventsFromGroupsByType(SETTYPE);
|
|
||||||
|
|
||||||
typeEvents.removeIf(event -> ((SetTypeEvent) event).getType() == Type.PRIVATE);
|
|
||||||
typeEvents.removeIf(event -> !groups.contains(event.getGroupid()));
|
|
||||||
|
|
||||||
return typeEvents.stream()
|
|
||||||
.map(Event::getGroupid)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<UUID> findLectureGroupIds() {
|
|
||||||
List<UUID> groups = findExistingGroupIds();
|
|
||||||
List<Event> typeEvents = findLatestEventsFromGroupsByType(SETTYPE);
|
|
||||||
|
|
||||||
typeEvents.removeIf(event -> ((SetTypeEvent) event).getType() != Type.LECTURE);
|
|
||||||
typeEvents.removeIf(event -> !groups.contains(event.getGroupid()));
|
|
||||||
|
|
||||||
return typeEvents.stream()
|
|
||||||
.map(Event::getGroupid)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen, in welchen der User teilnimmt.
|
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen, in welchen der User teilnimmt.
|
||||||
*
|
*
|
||||||
@ -234,20 +140,6 @@ public class EventStoreService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID findGroupByLink(String link) {
|
|
||||||
List<Event> groupEvents = findEventsByType(eventTypesToString(SETLINK));
|
|
||||||
|
|
||||||
if (groupEvents.size() > 1) {
|
|
||||||
throw new InvalidInviteException("Es existieren mehrere Gruppen mit demselben Link.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (groupEvents.isEmpty()) {
|
|
||||||
throw new InvalidInviteException("Link nicht gefunden.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return groupEvents.get(0).getGroupid();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #################################### SIMPLE QUERIES #######################################
|
// #################################### SIMPLE QUERIES #######################################
|
||||||
|
|
||||||
@ -262,23 +154,10 @@ public class EventStoreService {
|
|||||||
return eventStore.findMaxEventId();
|
return eventStore.findMaxEventId();
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
log.debug("Keine Events vorhanden!");
|
log.debug("Keine Events vorhanden!");
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Event> findEventsByType(String... types) {
|
|
||||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(Arrays.asList(types)));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Event> findEventsByType(String type) {
|
|
||||||
return getEventsFromDTOs(eventStore.findEventDTOsByType(Collections.singletonList(type)));
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Event> findEventsByGroupAndType(List<UUID> groupIds, String... types) {
|
|
||||||
return getEventsFromDTOs(eventStore.findEventDTOsByGroupAndType(uuidsToString(groupIds),
|
|
||||||
Arrays.asList(types)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sucht zu jeder Gruppe das letzte Add- oder DeleteUserEvent heraus, welches den übergebenen User betrifft.
|
* Sucht zu jeder Gruppe das letzte Add- oder DeleteUserEvent heraus, welches den übergebenen User betrifft.
|
||||||
*
|
*
|
||||||
@ -301,4 +180,12 @@ public class EventStoreService {
|
|||||||
private List<Event> findLatestEventsFromGroupsByType(EventType... types) {
|
private List<Event> findLatestEventsFromGroupsByType(EventType... types) {
|
||||||
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(Arrays.asList(eventTypesToString(types))));
|
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(Arrays.asList(eventTypesToString(types))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Event> findAllEvents() {
|
||||||
|
return getEventsFromDTOs(eventStore.findAllEvents());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Event> findNewEvents(long version, long maxid) {
|
||||||
|
return getEventsFromDTOs(eventStore.findNewEvents(version, maxid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package mops.gruppen2.domain.service;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
|
||||||
import mops.gruppen2.domain.event.AddMemberEvent;
|
import mops.gruppen2.domain.event.AddMemberEvent;
|
||||||
import mops.gruppen2.domain.event.CreateGroupEvent;
|
import mops.gruppen2.domain.event.CreateGroupEvent;
|
||||||
import mops.gruppen2.domain.event.DestroyGroupEvent;
|
import mops.gruppen2.domain.event.DestroyGroupEvent;
|
||||||
@ -16,7 +15,6 @@ import mops.gruppen2.domain.event.SetTitleEvent;
|
|||||||
import mops.gruppen2.domain.event.SetTypeEvent;
|
import mops.gruppen2.domain.event.SetTypeEvent;
|
||||||
import mops.gruppen2.domain.event.UpdateRoleEvent;
|
import mops.gruppen2.domain.event.UpdateRoleEvent;
|
||||||
import mops.gruppen2.domain.exception.EventException;
|
import mops.gruppen2.domain.exception.EventException;
|
||||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.domain.model.group.Role;
|
import mops.gruppen2.domain.model.group.Role;
|
||||||
import mops.gruppen2.domain.model.group.Type;
|
import mops.gruppen2.domain.model.group.Type;
|
||||||
@ -26,6 +24,8 @@ import mops.gruppen2.domain.model.group.wrapper.Limit;
|
|||||||
import mops.gruppen2.domain.model.group.wrapper.Link;
|
import mops.gruppen2.domain.model.group.wrapper.Link;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Title;
|
import mops.gruppen2.domain.model.group.wrapper.Title;
|
||||||
|
import mops.gruppen2.domain.service.helper.ValidationHelper;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -37,11 +37,11 @@ import java.util.UUID;
|
|||||||
* Es werden übergebene Gruppen bearbeitet und dementsprechend Events erzeugt und gespeichert.
|
* Es werden übergebene Gruppen bearbeitet und dementsprechend Events erzeugt und gespeichert.
|
||||||
*/
|
*/
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@TraceMethodCalls
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@Service
|
@Service
|
||||||
public class GroupService {
|
public class GroupService {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
private final EventStoreService eventStoreService;
|
private final EventStoreService eventStoreService;
|
||||||
|
|
||||||
// ################################# GRUPPE ERSTELLEN ########################################
|
// ################################# GRUPPE ERSTELLEN ########################################
|
||||||
@ -266,7 +266,7 @@ public class GroupService {
|
|||||||
|
|
||||||
private void applyAndSave(Group group, Event event) throws EventException {
|
private void applyAndSave(Group group, Event event) throws EventException {
|
||||||
event.init(group.version() + 1);
|
event.init(group.version() + 1);
|
||||||
event.apply(group);
|
event.apply(group, groupCache);
|
||||||
|
|
||||||
eventStoreService.saveEvent(event);
|
eventStoreService.saveEvent(event);
|
||||||
}
|
}
|
||||||
|
@ -1,215 +0,0 @@
|
|||||||
package mops.gruppen2.domain.service;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.log4j.Log4j2;
|
|
||||||
import mops.gruppen2.domain.event.Event;
|
|
||||||
import mops.gruppen2.domain.exception.EventException;
|
|
||||||
import mops.gruppen2.domain.exception.GroupNotFoundException;
|
|
||||||
import mops.gruppen2.domain.helper.CommonHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Liefert verschiedene Projektionen auf Gruppen.
|
|
||||||
* Benötigt ausschließlich den EventStoreService.
|
|
||||||
*/
|
|
||||||
@Log4j2
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Service
|
|
||||||
public class ProjectionService {
|
|
||||||
|
|
||||||
private final EventStoreService eventStoreService;
|
|
||||||
|
|
||||||
|
|
||||||
// ################################## STATISCHE PROJEKTIONEN #################################
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
private static Group projectGroupByEvents(List<Event> events) throws EventException {
|
|
||||||
if (events.isEmpty()) {
|
|
||||||
throw new GroupNotFoundException(ProjectionService.class.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
Group group = new Group();
|
|
||||||
|
|
||||||
events.forEach(event -> event.apply(group));
|
|
||||||
|
|
||||||
return group;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Konstruiert Gruppen aus einer Liste von Events.
|
|
||||||
*
|
|
||||||
* @param events Liste an Events
|
|
||||||
*
|
|
||||||
* @return Liste an Projizierten Gruppen
|
|
||||||
*
|
|
||||||
* @throws EventException Projektionsfehler
|
|
||||||
*/
|
|
||||||
public static List<Group> projectGroupsByEvents(List<Event> events) throws EventException {
|
|
||||||
Map<UUID, Group> groupMap = new HashMap<>();
|
|
||||||
|
|
||||||
events.forEach(event -> event.apply(getOrCreateGroup(groupMap, event.getGroupid())));
|
|
||||||
|
|
||||||
return new ArrayList<>(groupMap.values());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
|
|
||||||
* wird die Gruppe erstellt und der Map hizugefügt.
|
|
||||||
*
|
|
||||||
* @param groups Map aus GruppenIds und Gruppen
|
|
||||||
* @param groupId Die Id der Gruppe, die zurückgegeben werden soll
|
|
||||||
*
|
|
||||||
* @return Die gesuchte Gruppe
|
|
||||||
*/
|
|
||||||
private static Group getOrCreateGroup(Map<UUID, Group> groups, UUID groupId) {
|
|
||||||
if (!groups.containsKey(groupId)) {
|
|
||||||
groups.put(groupId, new Group());
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups.get(groupId);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ############################### PROJEKTIONEN MIT DATENBANK ################################
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gibt die Gruppe zurück, die zu der übergebenen Id passt.
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* @return Die gesuchte Gruppe
|
|
||||||
*
|
|
||||||
* @throws GroupNotFoundException Wenn die Gruppe nicht gefunden wird
|
|
||||||
*/
|
|
||||||
public Group projectGroupById(UUID groupId) throws GroupNotFoundException {
|
|
||||||
try {
|
|
||||||
List<Event> events = eventStoreService.findGroupEvents(groupId);
|
|
||||||
return projectGroupByEvents(events);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Gruppe {} wurde nicht gefunden!", groupId.toString(), e);
|
|
||||||
throw new GroupNotFoundException(groupId + ": " + ProjectionService.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group projectParent(UUID parent) {
|
|
||||||
if (CommonHelper.uuidIsEmpty(parent)) {
|
|
||||||
return new Group();
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectGroupById(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Group> projectGroupsByIds(List<UUID> groupids) {
|
|
||||||
List<Event> events = eventStoreService.findGroupEvents(groupids);
|
|
||||||
|
|
||||||
return projectGroupsByEvents(events);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Projiziert Gruppen, welche sich seit einer übergebenen eventId geändert haben.
|
|
||||||
* Die Gruppen werden dabei vollständig konstruiert.
|
|
||||||
*
|
|
||||||
* @param status Letzte bekannte eventId
|
|
||||||
*
|
|
||||||
* @return Liste an Gruppen
|
|
||||||
*/
|
|
||||||
public List<Group> projectChangedGroups(long status) {
|
|
||||||
List<UUID> changedids = eventStoreService.findChangedGroups(status);
|
|
||||||
|
|
||||||
return projectGroupsByIds(changedids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Projiziert öffentliche Gruppen.
|
|
||||||
* Die Gruppen enthalten Metainformationen: Titel, Beschreibung und MaxUserAnzahl.
|
|
||||||
* Außerdem wird noch beachtet, ob der eingeloggte User bereits in entsprechenden Gruppen mitglied ist.
|
|
||||||
*
|
|
||||||
* @return Liste von projizierten Gruppen
|
|
||||||
*
|
|
||||||
* @throws EventException Projektionsfehler
|
|
||||||
*/
|
|
||||||
@Cacheable("groups")
|
|
||||||
public List<Group> projectPublicGroups() throws EventException {
|
|
||||||
List<UUID> groupIds = eventStoreService.findPublicGroupIds();
|
|
||||||
|
|
||||||
if (groupIds.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectGroupsByIds(groupIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Projiziert Vorlesungen.
|
|
||||||
* Projektionen enthalten nur Metainformationen: Titel.
|
|
||||||
*
|
|
||||||
* @return Liste von Veranstaltungen
|
|
||||||
*/
|
|
||||||
@Cacheable("groups")
|
|
||||||
public List<Group> projectLectures() {
|
|
||||||
List<UUID> groupIds = eventStoreService.findLectureGroupIds();
|
|
||||||
|
|
||||||
if (groupIds.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectGroupsByIds(groupIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Projiziert Gruppen, in welchen der User aktuell teilnimmt.
|
|
||||||
* Die Gruppen enthalten nur Metainformationen: Titel und Beschreibung.
|
|
||||||
*
|
|
||||||
* @param userid Die Id
|
|
||||||
*
|
|
||||||
* @return Liste aus Gruppen
|
|
||||||
*/
|
|
||||||
@Cacheable("groups")
|
|
||||||
public List<Group> projectUserGroups(String userid) {
|
|
||||||
List<UUID> groupIds = eventStoreService.findExistingUserGroups(userid);
|
|
||||||
|
|
||||||
if (groupIds.isEmpty()) {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
return projectGroupsByIds(groupIds);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entfernt alle Gruppen, in welchen ein User teilnimmt, aus einer Gruppenliste.
|
|
||||||
*
|
|
||||||
* @param groups Gruppenliste, aus der entfernt wird
|
|
||||||
* @param userid User, welcher teilnimmt
|
|
||||||
*/
|
|
||||||
void removeUserGroups(List<Group> groups, String userid) {
|
|
||||||
List<UUID> userGroups = eventStoreService.findExistingUserGroups(userid);
|
|
||||||
|
|
||||||
groups.removeIf(group -> userGroups.contains(group.getId()));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Group projectGroupByLink(String link) {
|
|
||||||
return projectGroupById(eventStoreService.findGroupByLink(link));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +1,21 @@
|
|||||||
package mops.gruppen2.domain.service;
|
package mops.gruppen2.domain.service;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.domain.exception.EventException;
|
import mops.gruppen2.domain.exception.EventException;
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.domain.model.group.SortHelper;
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
@Log4j2
|
@Log4j2
|
||||||
public class SearchService {
|
public class SearchService {
|
||||||
|
|
||||||
private final ProjectionService projectionService;
|
private final GroupCache groupCache;
|
||||||
|
|
||||||
public SearchService(ProjectionService projectionService) {
|
|
||||||
this.projectionService = projectionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filtert alle öffentliche Gruppen nach dem Suchbegriff und gibt diese als sortierte Liste zurück.
|
* Filtert alle öffentliche Gruppen nach dem Suchbegriff und gibt diese als sortierte Liste zurück.
|
||||||
@ -31,13 +28,11 @@ public class SearchService {
|
|||||||
*
|
*
|
||||||
* @throws EventException Projektionsfehler
|
* @throws EventException Projektionsfehler
|
||||||
*/
|
*/
|
||||||
@Cacheable("groups")
|
//TODO: search in lectures
|
||||||
public List<Group> searchPublicGroups(String search, String principal) {
|
public List<Group> searchPublicGroups(String search, String principal) {
|
||||||
List<Group> groups = projectionService.projectPublicGroups();
|
List<Group> groups = groupCache.publics();
|
||||||
System.out.println(groups);
|
|
||||||
projectionService.removeUserGroups(groups, principal);
|
groups = removeUserGroups(groups, principal);
|
||||||
System.out.println(groups);
|
|
||||||
SortHelper.sortByGroupType(groups);
|
|
||||||
|
|
||||||
if (search.isEmpty()) {
|
if (search.isEmpty()) {
|
||||||
return groups;
|
return groups;
|
||||||
@ -50,4 +45,10 @@ public class SearchService {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<Group> removeUserGroups(List<Group> groups, String principal) {
|
||||||
|
return groups.stream()
|
||||||
|
.filter(group -> !group.isMember(principal))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package mops.gruppen2.domain.helper;
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.web.api.GroupRequestWrapper;
|
import mops.gruppen2.infrastructure.api.GroupRequestWrapper;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.domain.helper;
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.domain.helper;
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectReader;
|
import com.fasterxml.jackson.databind.ObjectReader;
|
||||||
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.domain.helper;
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
@ -0,0 +1,49 @@
|
|||||||
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.log4j.Log4j2;
|
||||||
|
import mops.gruppen2.domain.event.Event;
|
||||||
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert verschiedene Projektionen auf Gruppen.
|
||||||
|
* Benötigt ausschließlich den EventStoreService.
|
||||||
|
*/
|
||||||
|
@Log4j2
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public final class ProjectionHelper {
|
||||||
|
|
||||||
|
public static void project(Map<UUID, Group> groups, List<Event> events, GroupCache cache) {
|
||||||
|
if (events.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.trace(groups);
|
||||||
|
log.trace(events);
|
||||||
|
|
||||||
|
events.forEach(event -> event.apply(getOrCreateGroup(groups, event.getGroupid()), cache));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Gruppe mit der richtigen Id aus der übergebenen Map wieder, existiert diese nicht
|
||||||
|
* wird die Gruppe erstellt und der Map hizugefügt.
|
||||||
|
*
|
||||||
|
* @param groups Map aus GruppenIds und Gruppen
|
||||||
|
* @param groupId Die Id der Gruppe, die zurückgegeben werden soll
|
||||||
|
*
|
||||||
|
* @return Die gesuchte Gruppe
|
||||||
|
*/
|
||||||
|
private static Group getOrCreateGroup(Map<UUID, Group> groups, UUID groupId) {
|
||||||
|
if (!groups.containsKey(groupId)) {
|
||||||
|
groups.put(groupId, new Group());
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups.get(groupId);
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.domain.helper;
|
package mops.gruppen2.domain.service.helper;
|
||||||
|
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
@ -0,0 +1,18 @@
|
|||||||
|
package mops.gruppen2.infrastructure;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Component
|
||||||
|
public class ApplicationInit {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void init() {
|
||||||
|
groupCache.init();
|
||||||
|
}
|
||||||
|
}
|
79
src/main/java/mops/gruppen2/infrastructure/GroupCache.java
Normal file
79
src/main/java/mops/gruppen2/infrastructure/GroupCache.java
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package mops.gruppen2.infrastructure;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import mops.gruppen2.domain.exception.GroupNotFoundException;
|
||||||
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
|
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.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@Component
|
||||||
|
@Scope("singleton")
|
||||||
|
public class GroupCache {
|
||||||
|
|
||||||
|
private final EventStoreService eventStoreService;
|
||||||
|
|
||||||
|
private final Map<UUID, Group> groups = new HashMap<>();
|
||||||
|
|
||||||
|
public void init() {
|
||||||
|
long maxid = eventStoreService.findMaxEventId();
|
||||||
|
ProjectionHelper.project(groups, eventStoreService.findNewEvents(0, maxid), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(Group group) {
|
||||||
|
groups.put(group.getId(), group);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Group group) {
|
||||||
|
groups.remove(group.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
|
||||||
|
public Group group(UUID groupid) {
|
||||||
|
if (!groups.containsKey(groupid)) {
|
||||||
|
throw new GroupNotFoundException("Gruppe ist nicht im Cache.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return groups.get(groupid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Group group(String link) {
|
||||||
|
return groups.values().stream()
|
||||||
|
.filter(group -> group.getLink().equals(link))
|
||||||
|
.findFirst()
|
||||||
|
.orElseThrow(() -> new GroupNotFoundException("Link nicht im Cache."));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Group> userGroups(String userid) {
|
||||||
|
return groups.values().stream()
|
||||||
|
.filter(group -> group.isMember(userid))
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Group> publics() {
|
||||||
|
return groups.values().stream()
|
||||||
|
.filter(Group::isPublic)
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Group> privates() {
|
||||||
|
return groups.values().stream()
|
||||||
|
.filter(Group::isPrivate)
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Group> lectures() {
|
||||||
|
return groups.values().stream()
|
||||||
|
.filter(Group::isLecture)
|
||||||
|
.collect(Collectors.toUnmodifiableList());
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import mops.gruppen2.domain.Account;
|
import mops.gruppen2.domain.Account;
|
||||||
import mops.gruppen2.domain.model.group.Role;
|
import mops.gruppen2.domain.model.group.Role;
|
||||||
import mops.gruppen2.domain.model.group.Type;
|
import mops.gruppen2.domain.model.group.Type;
|
||||||
@ -9,9 +10,12 @@ import org.springframework.ui.Model;
|
|||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
@ControllerAdvice
|
@ControllerAdvice
|
||||||
public class ModelAttributeControllerAdvice {
|
public class ModelAttributeControllerAdvice {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
|
|
||||||
// Add modelAttributes before each @RequestMapping
|
// Add modelAttributes before each @RequestMapping
|
||||||
@ModelAttribute
|
@ModelAttribute
|
||||||
public void modelAttributes(KeycloakAuthenticationToken token,
|
public void modelAttributes(KeycloakAuthenticationToken token,
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.web.api;
|
package mops.gruppen2.infrastructure.api;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
@ -1,4 +1,4 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure.controller;
|
||||||
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
@ -6,12 +6,8 @@ import io.swagger.annotations.ApiParam;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||||
import mops.gruppen2.domain.helper.APIHelper;
|
|
||||||
import mops.gruppen2.domain.helper.CommonHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
|
||||||
import mops.gruppen2.domain.service.EventStoreService;
|
import mops.gruppen2.domain.service.EventStoreService;
|
||||||
import mops.gruppen2.domain.service.ProjectionService;
|
import mops.gruppen2.domain.service.helper.CommonHelper;
|
||||||
import mops.gruppen2.web.api.GroupRequestWrapper;
|
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
@ -19,7 +15,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Api zum Datenabgleich.
|
* Api zum Datenabgleich.
|
||||||
@ -31,8 +26,9 @@ import java.util.UUID;
|
|||||||
@RequestMapping("/gruppen2/api")
|
@RequestMapping("/gruppen2/api")
|
||||||
public class APIController {
|
public class APIController {
|
||||||
|
|
||||||
|
//TODO: redo api
|
||||||
|
|
||||||
private final EventStoreService eventStoreService;
|
private final EventStoreService eventStoreService;
|
||||||
private final ProjectionService projectionService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erzeugt eine Liste aus Gruppen, welche sich seit einer übergebenen Event-Id geändert haben.
|
* Erzeugt eine Liste aus Gruppen, welche sich seit einer übergebenen Event-Id geändert haben.
|
||||||
@ -40,15 +36,15 @@ public class APIController {
|
|||||||
*
|
*
|
||||||
* @param eventId Die Event-ID, welche der Anfragesteller beim letzten Aufruf erhalten hat
|
* @param eventId Die Event-ID, welche der Anfragesteller beim letzten Aufruf erhalten hat
|
||||||
*/
|
*/
|
||||||
@GetMapping("/update/{id}")
|
/*@GetMapping("/update/{id}")
|
||||||
@Secured("ROLE_api_user")
|
@Secured("ROLE_api_user")
|
||||||
@ApiOperation("Gibt veränderte Gruppen zurück")
|
@ApiOperation("Gibt veränderte Gruppen zurück")
|
||||||
public GroupRequestWrapper getApiUpdate(@ApiParam("Letzte gespeicherte EventId des Anfragestellers")
|
public GroupRequestWrapper getApiUpdate(@ApiParam("Letzte gespeicherte EventId des Anfragestellers")
|
||||||
@PathVariable("id") long eventId) {
|
@PathVariable("id") long eventId) {
|
||||||
|
|
||||||
return APIHelper.wrap(eventStoreService.findMaxEventId(),
|
return APIHelper.wrap(eventStoreService.findMaxEventId(),
|
||||||
projectionService.projectChangedGroups(eventId));
|
projectionHelper.projectChangedGroups(eventId));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt die Gruppen-IDs von Gruppen, in welchen der übergebene Nutzer teilnimmt, zurück.
|
* Gibt die Gruppen-IDs von Gruppen, in welchen der übergebene Nutzer teilnimmt, zurück.
|
||||||
@ -65,13 +61,13 @@ public class APIController {
|
|||||||
/**
|
/**
|
||||||
* Konstruiert eine einzelne, vollständige Gruppe.
|
* Konstruiert eine einzelne, vollständige Gruppe.
|
||||||
*/
|
*/
|
||||||
@GetMapping("/group/{id}")
|
/*@GetMapping("/group/{id}")
|
||||||
@Secured("ROLE_api_user")
|
@Secured("ROLE_api_user")
|
||||||
@ApiOperation("Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück")
|
@ApiOperation("Gibt die Gruppe mit der als Parameter mitgegebenden groupId zurück")
|
||||||
public Group getApiGroup(@ApiParam("Gruppen-Id der gefordeten Gruppe")
|
public Group getApiGroup(@ApiParam("Gruppen-Id der gefordeten Gruppe")
|
||||||
@PathVariable("id") String groupId) {
|
@PathVariable("id") String groupId) {
|
||||||
|
|
||||||
return projectionService.projectGroupById(UUID.fromString(groupId));
|
return projectionHelper.projectGroupById(UUID.fromString(groupId));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
}
|
}
|
@ -1,10 +1,8 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure.controller;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||||
import mops.gruppen2.domain.helper.CsvHelper;
|
|
||||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.domain.model.group.Type;
|
import mops.gruppen2.domain.model.group.Type;
|
||||||
import mops.gruppen2.domain.model.group.User;
|
import mops.gruppen2.domain.model.group.User;
|
||||||
@ -13,9 +11,10 @@ import mops.gruppen2.domain.model.group.wrapper.Limit;
|
|||||||
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
import mops.gruppen2.domain.model.group.wrapper.Parent;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Title;
|
import mops.gruppen2.domain.model.group.wrapper.Title;
|
||||||
import mops.gruppen2.domain.service.GroupService;
|
import mops.gruppen2.domain.service.GroupService;
|
||||||
import mops.gruppen2.domain.service.ProjectionService;
|
import mops.gruppen2.domain.service.helper.CsvHelper;
|
||||||
|
import mops.gruppen2.domain.service.helper.ValidationHelper;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -35,21 +34,20 @@ import javax.validation.Valid;
|
|||||||
@RequestMapping("/gruppen2")
|
@RequestMapping("/gruppen2")
|
||||||
public class GroupCreationController {
|
public class GroupCreationController {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
private final GroupService groupService;
|
private final GroupService groupService;
|
||||||
private final ProjectionService projectionService;
|
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@GetMapping("/create")
|
@GetMapping("/create")
|
||||||
public String getCreate(Model model) {
|
public String getCreate(Model model) {
|
||||||
|
|
||||||
model.addAttribute("lectures", projectionService.projectLectures());
|
model.addAttribute("lectures", groupCache.lectures());
|
||||||
|
|
||||||
return "create";
|
return "create";
|
||||||
}
|
}
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postCreateOrga(KeycloakAuthenticationToken token,
|
public String postCreateOrga(KeycloakAuthenticationToken token,
|
||||||
@RequestParam("type") Type type,
|
@RequestParam("type") Type type,
|
||||||
@RequestParam("parent") @Valid Parent parent,
|
@RequestParam("parent") @Valid Parent parent,
|
@ -1,19 +1,18 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure.controller;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||||
import mops.gruppen2.domain.helper.CsvHelper;
|
|
||||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.domain.model.group.User;
|
import mops.gruppen2.domain.model.group.User;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Description;
|
import mops.gruppen2.domain.model.group.wrapper.Description;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Limit;
|
import mops.gruppen2.domain.model.group.wrapper.Limit;
|
||||||
import mops.gruppen2.domain.model.group.wrapper.Title;
|
import mops.gruppen2.domain.model.group.wrapper.Title;
|
||||||
import mops.gruppen2.domain.service.GroupService;
|
import mops.gruppen2.domain.service.GroupService;
|
||||||
import mops.gruppen2.domain.service.ProjectionService;
|
import mops.gruppen2.domain.service.helper.CsvHelper;
|
||||||
|
import mops.gruppen2.domain.service.helper.ValidationHelper;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||||
import org.springframework.cache.annotation.CacheEvict;
|
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -36,8 +35,8 @@ import java.util.UUID;
|
|||||||
@RequestMapping("/gruppen2")
|
@RequestMapping("/gruppen2")
|
||||||
public class GroupDetailsController {
|
public class GroupDetailsController {
|
||||||
|
|
||||||
|
private final GroupCache groupCache;
|
||||||
private final GroupService groupService;
|
private final GroupService groupService;
|
||||||
private final ProjectionService projectionService;
|
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@GetMapping("/details/{id}")
|
@GetMapping("/details/{id}")
|
||||||
@ -46,10 +45,13 @@ public class GroupDetailsController {
|
|||||||
@PathVariable("id") String groupId) {
|
@PathVariable("id") String groupId) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
// Parent Badge
|
// Parent Badge
|
||||||
Group parent = projectionService.projectParent(group.getParent());
|
Group parent = Group.EMPTY();
|
||||||
|
if (group.hasParent()) {
|
||||||
|
parent = groupCache.group(group.getParent());
|
||||||
|
}
|
||||||
|
|
||||||
model.addAttribute("group", group);
|
model.addAttribute("group", group);
|
||||||
model.addAttribute("parent", parent);
|
model.addAttribute("parent", parent);
|
||||||
@ -64,12 +66,11 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/join")
|
@PostMapping("/details/{id}/join")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsJoin(KeycloakAuthenticationToken token,
|
public String postDetailsJoin(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId) {
|
@PathVariable("id") String groupId) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
if (ValidationHelper.checkIfMember(group, principal)) {
|
if (ValidationHelper.checkIfMember(group, principal)) {
|
||||||
return "redirect:/gruppen2/details/" + groupId;
|
return "redirect:/gruppen2/details/" + groupId;
|
||||||
@ -82,12 +83,11 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/leave")
|
@PostMapping("/details/{id}/leave")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsLeave(KeycloakAuthenticationToken token,
|
public String postDetailsLeave(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId) {
|
@PathVariable("id") String groupId) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
groupService.kickMember(group, principal, principal);
|
groupService.kickMember(group, principal, principal);
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ public class GroupDetailsController {
|
|||||||
@PathVariable("id") String groupId) {
|
@PathVariable("id") String groupId) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
// Invite Link
|
// Invite Link
|
||||||
String actualURL = request.getRequestURL().toString();
|
String actualURL = request.getRequestURL().toString();
|
||||||
@ -119,14 +119,15 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/edit/meta")
|
@PostMapping("/details/{id}/edit/meta")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditMeta(KeycloakAuthenticationToken token,
|
public String postDetailsEditMeta(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId,
|
@PathVariable("id") String groupId,
|
||||||
@Valid Title title,
|
@Valid Title title,
|
||||||
@Valid Description description) {
|
@Valid Description description) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
|
System.out.println(group);
|
||||||
|
|
||||||
groupService.setTitle(group, principal, title);
|
groupService.setTitle(group, principal, title);
|
||||||
groupService.setDescription(group, principal, description);
|
groupService.setDescription(group, principal, description);
|
||||||
@ -136,12 +137,11 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/edit/userlimit")
|
@PostMapping("/details/{id}/edit/userlimit")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditUserLimit(KeycloakAuthenticationToken token,
|
public String postDetailsEditUserLimit(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId,
|
@PathVariable("id") String groupId,
|
||||||
@Valid Limit limit) {
|
@Valid Limit limit) {
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
groupService.setLimit(group, principal, limit);
|
groupService.setLimit(group, principal, limit);
|
||||||
|
|
||||||
@ -150,13 +150,12 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed("ROLE_orga")
|
@RolesAllowed("ROLE_orga")
|
||||||
@PostMapping("/details/{id}/edit/csv")
|
@PostMapping("/details/{id}/edit/csv")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditCsv(KeycloakAuthenticationToken token,
|
public String postDetailsEditCsv(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId,
|
@PathVariable("id") String groupId,
|
||||||
@RequestParam(value = "file", required = false) MultipartFile file) {
|
@RequestParam(value = "file", required = false) MultipartFile file) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
groupService.addUsersToGroup(group, principal, CsvHelper.readCsvFile(file));
|
groupService.addUsersToGroup(group, principal, CsvHelper.readCsvFile(file));
|
||||||
|
|
||||||
@ -165,13 +164,12 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/edit/role/{userid}")
|
@PostMapping("/details/{id}/edit/role/{userid}")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditRole(KeycloakAuthenticationToken token,
|
public String postDetailsEditRole(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId,
|
@PathVariable("id") String groupId,
|
||||||
@PathVariable("userid") String target) {
|
@PathVariable("userid") String target) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
ValidationHelper.throwIfNoAdmin(group, principal);
|
ValidationHelper.throwIfNoAdmin(group, principal);
|
||||||
|
|
||||||
@ -187,13 +185,12 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/edit/delete/{userid}")
|
@PostMapping("/details/{id}/edit/delete/{userid}")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditDelete(KeycloakAuthenticationToken token,
|
public String postDetailsEditDelete(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupId,
|
@PathVariable("id") String groupId,
|
||||||
@PathVariable("userid") String target) {
|
@PathVariable("userid") String target) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupId));
|
Group group = groupCache.group(UUID.fromString(groupId));
|
||||||
|
|
||||||
ValidationHelper.throwIfNoAdmin(group, principal);
|
ValidationHelper.throwIfNoAdmin(group, principal);
|
||||||
|
|
||||||
@ -207,12 +204,11 @@ public class GroupDetailsController {
|
|||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@PostMapping("/details/{id}/edit/destroy")
|
@PostMapping("/details/{id}/edit/destroy")
|
||||||
@CacheEvict(value = "groups", allEntries = true)
|
|
||||||
public String postDetailsEditDestroy(KeycloakAuthenticationToken token,
|
public String postDetailsEditDestroy(KeycloakAuthenticationToken token,
|
||||||
@PathVariable("id") String groupid) {
|
@PathVariable("id") String groupid) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupById(UUID.fromString(groupid));
|
Group group = groupCache.group(UUID.fromString(groupid));
|
||||||
|
|
||||||
groupService.deleteGroup(group, principal);
|
groupService.deleteGroup(group, principal);
|
||||||
|
|
@ -1,10 +1,10 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure.controller;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCall;
|
import mops.gruppen2.aspect.annotation.TraceMethodCall;
|
||||||
import mops.gruppen2.domain.exception.PageNotFoundException;
|
import mops.gruppen2.domain.exception.PageNotFoundException;
|
||||||
import mops.gruppen2.domain.service.ProjectionService;
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -20,22 +20,25 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
@Controller
|
@Controller
|
||||||
public class GruppenfindungController {
|
public class GruppenfindungController {
|
||||||
|
|
||||||
private final ProjectionService projectionService;
|
private final GroupCache groupCache;
|
||||||
|
|
||||||
// For convenience
|
// For convenience
|
||||||
//@GetMapping("")
|
@GetMapping("")
|
||||||
//public String redirect() {
|
public String redirect() {
|
||||||
// return "redirect:/gruppen2";
|
return "redirect:/gruppen2";
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String login() {
|
||||||
|
return "redirect:/gruppen2";
|
||||||
|
}
|
||||||
|
|
||||||
@TraceMethodCall
|
@TraceMethodCall
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@GetMapping("/gruppen2")
|
@GetMapping("/gruppen2")
|
||||||
public String getIndexPage(KeycloakAuthenticationToken token,
|
public String getIndexPage(KeycloakAuthenticationToken token,
|
||||||
Model model) {
|
Model model) {
|
||||||
|
model.addAttribute("groups", groupCache.userGroups(token.getName()));
|
||||||
String principal = token.getName();
|
|
||||||
model.addAttribute("groups", projectionService.projectUserGroups(principal));
|
|
||||||
|
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
@ -1,13 +1,13 @@
|
|||||||
package mops.gruppen2.web;
|
package mops.gruppen2.infrastructure.controller;
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
import mops.gruppen2.aspect.annotation.TraceMethodCalls;
|
||||||
import mops.gruppen2.domain.helper.ValidationHelper;
|
|
||||||
import mops.gruppen2.domain.model.group.Group;
|
import mops.gruppen2.domain.model.group.Group;
|
||||||
import mops.gruppen2.domain.model.group.Type;
|
import mops.gruppen2.domain.model.group.Type;
|
||||||
import mops.gruppen2.domain.service.ProjectionService;
|
|
||||||
import mops.gruppen2.domain.service.SearchService;
|
import mops.gruppen2.domain.service.SearchService;
|
||||||
|
import mops.gruppen2.domain.service.helper.ValidationHelper;
|
||||||
|
import mops.gruppen2.infrastructure.GroupCache;
|
||||||
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
@ -29,7 +29,7 @@ import java.util.List;
|
|||||||
@RequestMapping("/gruppen2")
|
@RequestMapping("/gruppen2")
|
||||||
public class SearchAndInviteController {
|
public class SearchAndInviteController {
|
||||||
|
|
||||||
private final ProjectionService projectionService;
|
private final GroupCache groupCache;
|
||||||
private final SearchService searchService;
|
private final SearchService searchService;
|
||||||
|
|
||||||
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
@RolesAllowed({"ROLE_orga", "ROLE_studentin"})
|
||||||
@ -62,7 +62,7 @@ public class SearchAndInviteController {
|
|||||||
@PathVariable("link") String link) {
|
@PathVariable("link") String link) {
|
||||||
|
|
||||||
String principal = token.getName();
|
String principal = token.getName();
|
||||||
Group group = projectionService.projectGroupByLink(link);
|
Group group = groupCache.group(link);
|
||||||
|
|
||||||
model.addAttribute("group", group);
|
model.addAttribute("group", group);
|
||||||
|
|
@ -11,43 +11,21 @@ import java.util.List;
|
|||||||
@Repository
|
@Repository
|
||||||
public interface EventRepository extends CrudRepository<EventDTO, Long> {
|
public interface EventRepository extends CrudRepository<EventDTO, Long> {
|
||||||
|
|
||||||
// ####################################### GROUP IDs #########################################
|
|
||||||
|
|
||||||
/*@Query("SELECT DISTINCT group_id FROM event"
|
|
||||||
+ " WHERE user_id = :userId AND event_type = :type")
|
|
||||||
List<String> findGroupIdsByUserAndType(@Param("userId") String userId,
|
|
||||||
@Param("type") String type);*/
|
|
||||||
|
|
||||||
@Query("SELECT DISTINCT group_id FROM event"
|
|
||||||
+ " WHERE event_id > :status")
|
|
||||||
List<String> findGroupIdsWhereEventIdGreaterThanStatus(@Param("status") long status);
|
|
||||||
|
|
||||||
// ####################################### EVENT DTOs ########################################
|
// ####################################### EVENT DTOs ########################################
|
||||||
|
|
||||||
@Query("SELECT * FROM event"
|
|
||||||
+ " WHERE group_id IN (:groupIds) ")
|
|
||||||
List<EventDTO> findEventDTOsByGroup(@Param("groupIds") List<String> groupIds);
|
|
||||||
|
|
||||||
/*@Query("SELECT * FROM event"
|
@Query("SELECT * FROM event WHERE event_id > :version AND event_id <= :max")
|
||||||
+ " WHERE group_id IN (:userIds) ")
|
List<EventDTO> findNewEvents(@Param("version") long version,
|
||||||
List<EventDTO> findEventDTOsByUser(@Param("groupIds") String... userIds);*/
|
@Param("max") long maxid);
|
||||||
|
|
||||||
@Query("SELECT * FROM event"
|
@Query("SELECT * FROM event")
|
||||||
+ " WHERE event_type IN (:types)")
|
List<EventDTO> findAllEvents();
|
||||||
List<EventDTO> findEventDTOsByType(@Param("types") List<String> types);
|
|
||||||
|
|
||||||
@Query("SELECT * FROM event"
|
|
||||||
+ " WHERE event_type IN (:types) AND group_id IN (:groupIds)")
|
|
||||||
List<EventDTO> findEventDTOsByGroupAndType(@Param("groupIds") List<String> groupIds,
|
|
||||||
@Param("types") List<String> types);
|
|
||||||
|
|
||||||
/*@Query("SELECT * FROM event"
|
|
||||||
+ " WHERE event_type IN (:types) AND user_id = :userId")
|
|
||||||
List<EventDTO> findEventDTOsByUserAndType(@Param("userId") String userId,
|
|
||||||
@Param("types") String... types);*/
|
|
||||||
|
|
||||||
// ################################ LATEST EVENT DTOs ########################################
|
// ################################ LATEST EVENT DTOs ########################################
|
||||||
|
|
||||||
|
|
||||||
@Query("WITH ranked_events AS ("
|
@Query("WITH ranked_events AS ("
|
||||||
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
|
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
|
||||||
+ " FROM event"
|
+ " FROM event"
|
||||||
|
@ -12,11 +12,6 @@ spring.datasource.password =
|
|||||||
spring.jpa.database-platform = org.hibernate.dialect.H2Dialect
|
spring.jpa.database-platform = org.hibernate.dialect.H2Dialect
|
||||||
spring.h2.console.enabled = false
|
spring.h2.console.enabled = false
|
||||||
|
|
||||||
# Security
|
|
||||||
keycloak.auth-server-url = http://localhost:8082/auth
|
|
||||||
hhu_keycloak.token-uri = http://localhost:8082/auth/realms/Gruppen/protocol/openid-connect/token
|
|
||||||
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
server.error.include-stacktrace = always
|
server.error.include-stacktrace = always
|
||||||
management.endpoints.web.exposure.include = info,health
|
management.endpoints.web.exposure.include = info,health
|
||||||
|
@ -10,11 +10,6 @@ spring.datasource.url = jdbc:mysql://dbmysql:3306/gruppen
|
|||||||
spring.datasource.username = gruppen
|
spring.datasource.username = gruppen
|
||||||
spring.datasource.password = password
|
spring.datasource.password = password
|
||||||
|
|
||||||
# Security
|
|
||||||
keycloak.auth-server-url = http://localhost:8082/auth
|
|
||||||
hhu_keycloak.token-uri = http://localhost:8082/auth/realms/Gruppen/protocol/openid-connect/token
|
|
||||||
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
management.endpoints.web.exposure.include = info,health
|
management.endpoints.web.exposure.include = info,health
|
||||||
server.error.include-stacktrace = always
|
server.error.include-stacktrace = always
|
||||||
|
@ -10,10 +10,6 @@ spring.datasource.url = mysql://b4b665d39d0670:cc933ff7@eu
|
|||||||
spring.datasource.username = b4b665d39d0670
|
spring.datasource.username = b4b665d39d0670
|
||||||
spring.datasource.password = cc933ff7
|
spring.datasource.password = cc933ff7
|
||||||
|
|
||||||
# Security
|
|
||||||
keycloak.auth-server-url = https://gruppenkeycloak.herokuapp.com/auth
|
|
||||||
hhu_keycloak.token-uri = https://gruppenkeycloak.herokuapp.com/auth/realms/master/protocol/openid-connect/token
|
|
||||||
|
|
||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
management.endpoints.web.exposure.include = info,health
|
management.endpoints.web.exposure.include = info,health
|
||||||
|
@ -11,6 +11,8 @@ spring.profiles.active = dev
|
|||||||
#keycloak.use-resource-role-mappings = true
|
#keycloak.use-resource-role-mappings = true
|
||||||
#keycloak.autodetect-bearer-only = true
|
#keycloak.autodetect-bearer-only = true
|
||||||
#keycloak.confidential-port = 443
|
#keycloak.confidential-port = 443
|
||||||
|
keycloak.auth-server-url = https://gruppenkeycloak.herokuapp.com/auth
|
||||||
|
hhu_keycloak.token-uri = https://gruppenkeycloak.herokuapp.com/auth/realms/master/protocol/openid-connect/token
|
||||||
keycloak.principal-attribute = preferred_username
|
keycloak.principal-attribute = preferred_username
|
||||||
keycloak.realm = master
|
keycloak.realm = master
|
||||||
keycloak.resource = gruppen-app
|
keycloak.resource = gruppen-app
|
||||||
|
@ -30,7 +30,7 @@ class ControllerTest {
|
|||||||
public static final ArchRule controllerClassesShouldBeInControllerPackage = classes()
|
public static final ArchRule controllerClassesShouldBeInControllerPackage = classes()
|
||||||
.that().areAnnotatedWith(Controller.class)
|
.that().areAnnotatedWith(Controller.class)
|
||||||
.or().areAnnotatedWith(RestController.class)
|
.or().areAnnotatedWith(RestController.class)
|
||||||
.should().resideInAPackage("..web");
|
.should().resideInAPackage("..controller");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
public static final ArchRule classesInControllerPackageShouldHaveControllerInName = classes()
|
public static final ArchRule classesInControllerPackageShouldHaveControllerInName = classes()
|
||||||
|
@ -25,11 +25,11 @@ class ServiceTest {
|
|||||||
@ArchTest
|
@ArchTest
|
||||||
public static final ArchRule serviceClassesShouldBeInServicePackage = classes()
|
public static final ArchRule serviceClassesShouldBeInServicePackage = classes()
|
||||||
.that().areAnnotatedWith(Service.class)
|
.that().areAnnotatedWith(Service.class)
|
||||||
.should().resideInAPackage("..service..");
|
.should().resideInAPackage("..service");
|
||||||
|
|
||||||
@ArchTest
|
@ArchTest
|
||||||
public static final ArchRule classesInServicePackageShouldHaveServiceInName = classes()
|
public static final ArchRule classesInServicePackageShouldHaveServiceInName = classes()
|
||||||
.that().resideInAPackage("..service..")
|
.that().resideInAPackage("..service")
|
||||||
.should().haveSimpleNameEndingWith("Service");
|
.should().haveSimpleNameEndingWith("Service");
|
||||||
|
|
||||||
@ArchIgnore
|
@ArchIgnore
|
||||||
|
Reference in New Issue
Block a user