1
Files
lecture-professional-softwa…/src/main/java/mops/gruppen2/service/EventStoreService.java
2020-04-08 21:08:57 +02:00

260 lines
8.5 KiB
Java

package mops.gruppen2.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import lombok.extern.log4j.Log4j2;
import mops.gruppen2.domain.User;
import mops.gruppen2.domain.dto.EventDTO;
import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.Event;
import mops.gruppen2.domain.exception.BadPayloadException;
import mops.gruppen2.repository.EventRepository;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@Service
@Log4j2
public class EventStoreService {
private final EventRepository eventStore;
public EventStoreService(EventRepository eventStore) {
this.eventStore = eventStore;
}
//########################################### SAVE ###########################################
/**
* Erzeugt ein DTO aus einem Event und speicher es.
*
* @param event Event, welches gespeichert wird
*/
public void saveEvent(Event event) {
eventStore.save(getDTOFromEvent(event));
}
public void saveAll(Event... events) {
for (Event event : events) {
eventStore.save(getDTOFromEvent(event));
}
}
/**
* Speichert alle Events aus der übergebenen Liste in der DB.
*
* @param events Liste an Events die gespeichert werden soll
*/
@SafeVarargs
public final void saveAll(List<Event>... events) {
for (List<Event> eventlist : events) {
for (Event event : eventlist) {
eventStore.save(getDTOFromEvent(event));
}
}
}
//########################################### DTOs ###########################################
static List<EventDTO> getDTOsFromEvents(List<Event> events) {
return events.stream()
.map(EventStoreService::getDTOFromEvent)
.collect(Collectors.toList());
}
/**
* Erzeugt aus einem Event Objekt ein EventDTO Objekt.
*
* @param event Event, welches in DTO übersetzt wird
*
* @return EventDTO (Neues DTO)
*/
static EventDTO getDTOFromEvent(Event event) {
try {
String payload = JsonService.serializeEvent(event);
return new EventDTO(null,
event.getGroupId().toString(),
event.getUserId(),
getEventType(event),
payload);
} catch (JsonProcessingException e) {
log.error("Event ({}) konnte nicht serialisiert werden!", event, e);
throw new BadPayloadException(EventStoreService.class.toString());
}
}
/**
* Erzeugt aus einer Liste von eventDTOs eine Liste von Events.
*
* @param eventDTOS Liste von DTOs
*
* @return Liste von Events
*/
private static List<Event> getEventsFromDTOs(List<EventDTO> eventDTOS) {
return eventDTOS.stream()
.map(EventStoreService::getEventFromDTO)
.collect(Collectors.toList());
}
private static Event getEventFromDTO(EventDTO dto) {
try {
return JsonService.deserializeEvent(dto.getEvent_payload());
} catch (JsonProcessingException e) {
log.error("Payload {} konnte nicht deserialisiert werden!", dto.getEvent_payload(), e);
throw new BadPayloadException(EventStoreService.class.toString());
}
}
/**
* Gibt den Eventtyp als String wieder.
*
* @param event Event dessen Typ abgefragt werden soll
*
* @return Der Name des Typs des Events
*/
private static String getEventType(Event event) {
int lastDot = event.getClass().getName().lastIndexOf('.');
return event.getClass().getName().substring(lastDot + 1);
}
// ######################################## 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<Event> findChangedGroupEvents(long status) {
List<String> changedGroupIds = eventStore.findGroupIdsWhereEventIdGreaterThanStatus(status);
List<EventDTO> groupEventDTOS = eventStore.findEventDTOsByGroup(changedGroupIds);
log.debug("Seit Event {} haben sich {} Gruppen geändert!", status, changedGroupIds.size());
return getEventsFromDTOs(groupEventDTOS);
}
/**
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen.
*
* @return GruppenIds (UUID) als Liste
*/
List<UUID> findExistingGroupIds() {
List<Event> createEvents = findLatestEventsFromGroupsByType("CreateGroupEvent",
"DeleteGroupEvent");
return createEvents.stream()
.filter(event -> event instanceof CreateGroupEvent)
.map(Event::getGroupId)
.collect(Collectors.toList());
}
/**
* Liefert Gruppen-Ids von existierenden (ungelöschten) Gruppen, in welchen der User teilnimmt.
*
* @return GruppenIds (UUID) als Liste
*/
public List<UUID> findExistingUserGroups(User user) {
List<Event> userEvents = findLatestEventsFromGroupsByUser(user);
List<UUID> deletedIds = findLatestEventsFromGroupsByType("DeleteGroupEvent")
.stream()
.map(Event::getGroupId)
.collect(Collectors.toList());
userEvents.removeIf(event -> deletedIds.contains(event.getGroupId()));
return userEvents.stream()
.filter(event -> event instanceof AddUserEvent)
.map(Event::getGroupId)
.collect(Collectors.toList());
}
// #################################### 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;
}
}
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(Arrays.asList(types),
IdService.uuidsToString(groupIds)));
}
/**
* Sucht zu jeder Gruppe das letzte Add- oder DeleteUserEvent heraus, welches den übergebenen User betrifft.
*
* @param user User, zu welchem die Events gesucht werden
*
* @return Eine Liste von einem Add- oder DeleteUserEvent pro Gruppe
*/
private List<Event> findLatestEventsFromGroupsByUser(User user) {
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByUser(user.getId()));
}
/**
* 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(String... types) {
return getEventsFromDTOs(eventStore.findLatestEventDTOsPartitionedByGroupByType(Arrays.asList(types)));
}
}