1
This commit is contained in:
Christoph
2020-04-16 02:09:15 +02:00
parent 87f0779a99
commit 3aefe2f2b3
4 changed files with 5 additions and 125 deletions

View File

@ -3,23 +3,16 @@ 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.domain.event.AddMemberEvent;
import mops.gruppen2.domain.event.Event; import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.event.EventType;
import mops.gruppen2.domain.exception.BadPayloadException; import mops.gruppen2.domain.exception.BadPayloadException;
import mops.gruppen2.domain.service.helper.JsonHelper; import mops.gruppen2.domain.service.helper.JsonHelper;
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.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static mops.gruppen2.domain.event.EventType.DESTROYGROUP;
import static mops.gruppen2.domain.service.helper.CommonHelper.eventTypesToString;
@Log4j2 @Log4j2
@RequiredArgsConstructor @RequiredArgsConstructor
@Service @Service
@ -110,82 +103,10 @@ public class EventStoreService {
} }
// ######################################## QUERIES ##########################################
/**
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen, in welchen der User teilnimmt.
*
* <p>
* Vorgang:
* Finde für jede Gruppe das letzte Add- oder Kick-Event, welches den User betrifft
* Finde für jede Gruppe das letzte Destroy-Event
* Entferne alle alle Events von Gruppen, welche ein Destroy-Event haben
* Gebe die Gruppen zurück, auf welche sich die Add-Events beziehen
*
* @return GruppenIds (UUID) als Liste
*/
public List<UUID> findExistingUserGroups(String userid) {
List<Event> userEvents = findLatestEventsFromGroupsByUser(userid);
List<UUID> deletedIds = findLatestEventsFromGroupsByType(DESTROYGROUP)
.stream()
.map(Event::getGroupid)
.collect(Collectors.toList());
userEvents.removeIf(event -> deletedIds.contains(event.getGroupid()));
return userEvents.stream()
.filter(event -> event instanceof AddMemberEvent)
.map(Event::getGroupid)
.collect(Collectors.toList());
}
// #################################### SIMPLE QUERIES ####################################### // #################################### SIMPLE QUERIES #######################################
/**
* Ermittelt die Id zuletzt gespeicherten Events.
*
* @return Letzte EventId
*/
public long findMaxEventId() {
try {
return eventStore.findMaxEventId();
} catch (NullPointerException e) {
log.debug("Keine Events vorhanden!");
return 0;
}
}
/**
* Sucht zu jeder Gruppe das letzte Add- oder DeleteUserEvent heraus, welches den übergebenen User betrifft.
*
* @param userid User, zu welchem die Events gesucht werden
*
* @return Eine Liste von einem Add- oder DeleteUserEvent pro Gruppe
*/
private List<Event> findLatestEventsFromGroupsByUser(String userid) {
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupTarget(userid));
}
/**
* Sucht zu jeder Gruppe das letzte Event des/der übergebenen Typen heraus.
*
* @param types Eventtyp, nach welchem gesucht wird
*
* @return Eine Liste von einem Event pro Gruppe
*/
private List<Event> findLatestEventsFromGroupsByType(EventType... types) {
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(Arrays.asList(eventTypesToString(types))));
}
public List<Event> findAllEvents() { public List<Event> findAllEvents() {
return getEventsFromDTOs(eventStore.findAllEvents()); return getEventsFromDTOs(eventStore.findAllEvents());
} }
public List<Event> findNewEvents(long version, long maxid) {
return getEventsFromDTOs(eventStore.findNewEvents(version, maxid));
}
} }

View File

@ -24,8 +24,7 @@ public class GroupCache {
private final Map<UUID, Group> groups = new HashMap<>(); private final Map<UUID, Group> groups = new HashMap<>();
public void init() { public void init() {
long maxid = eventStoreService.findMaxEventId(); ProjectionHelper.project(groups, eventStoreService.findAllEvents(), this);
ProjectionHelper.project(groups, eventStoreService.findNewEvents(0, maxid), this);
} }
public void put(Group group) { public void put(Group group) {

View File

@ -1,21 +1,13 @@
package mops.gruppen2.infrastructure.controller; package mops.gruppen2.infrastructure.controller;
import io.swagger.annotations.ApiOperation;
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.service.EventStoreService; import mops.gruppen2.domain.service.EventStoreService;
import mops.gruppen2.domain.service.helper.CommonHelper;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; 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;
/** /**
* Api zum Datenabgleich. * Api zum Datenabgleich.
*/ */
@ -49,14 +41,14 @@ public class APIController {
/** /**
* 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.
*/ */
@GetMapping("/usergroups/{id}") /*@GetMapping("/usergroups/{id}")
@Secured("ROLE_api_user") @Secured("ROLE_api_user")
@ApiOperation("Gibt Gruppen zurück, in welchen ein Nutzer teilnimmt") @ApiOperation("Gibt Gruppen zurück, in welchen ein Nutzer teilnimmt")
public List<String> getApiUserGroups(@ApiParam("Nutzer-Id") public List<String> getApiUserGroups(@ApiParam("Nutzer-Id")
@PathVariable("id") String userId) { @PathVariable("id") String userId) {
return CommonHelper.uuidsToString(eventStoreService.findExistingUserGroups(userId)); return CommonHelper.uuidsToString(eventStoreService.findExistingUserGroups(userId));
} }*/
/** /**
* Konstruiert eine einzelne, vollständige Gruppe. * Konstruiert eine einzelne, vollständige Gruppe.

View File

@ -3,7 +3,6 @@ package mops.gruppen2.persistance;
import mops.gruppen2.persistance.dto.EventDTO; import mops.gruppen2.persistance.dto.EventDTO;
import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@ -15,37 +14,6 @@ public interface EventRepository extends CrudRepository<EventDTO, Long> {
// ####################################### EVENT DTOs ######################################## // ####################################### EVENT DTOs ########################################
@Query("SELECT * FROM event WHERE event_id > :version AND event_id <= :max") @Query("SELECT * FROM heroku_f6ff902475fc2fa")
List<EventDTO> findNewEvents(@Param("version") long version,
@Param("max") long maxid);
@Query("SELECT * FROM event")
List<EventDTO> findAllEvents(); List<EventDTO> findAllEvents();
// ################################ LATEST EVENT DTOs ########################################
@Query("WITH ranked_events AS ("
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
+ " FROM event"
+ " WHERE target_id = :userId AND event_type IN ('ADDMEMBER', 'KICKMEMBER')"
+ ")"
+ "SELECT * FROM ranked_events WHERE rn = 1;")
List<EventDTO> findLatestEventDTOsPartitionedByGroupTarget(@Param("userId") String target);
@Query("WITH ranked_events AS ("
+ "SELECT *, ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY event_id DESC) AS rn"
+ " FROM event"
+ " WHERE event_type IN (:types)"
+ ")"
+ "SELECT * FROM ranked_events WHERE rn = 1;")
List<EventDTO> findLatestEventDTOsPartitionedByGroupByType(@Param("types") List<String> types);
// ######################################### COUNT ###########################################
@Query("SELECT MAX(event_id) FROM event")
Long findMaxEventId();
} }