1

Merge pull request #36 from hhu-propra2/general-refactor

General refactor
This commit is contained in:
killerber4t
2020-03-09 13:02:25 +01:00
committed by GitHub
44 changed files with 475 additions and 398 deletions

View File

@ -14,7 +14,7 @@ endif::[]
== Gruppenbildung == Gruppenbildung
Für das Abschlussprojekt bilden Sie bitte eine Gruppe im GitHub Classroom, die Für das Abschlussprojekt bilden Sie bitte eine Gruppe im GitHub Classroom, die
aus 7 bis 9 Personen besteht und laden eine entsprechende `gruppe.yml` in AUAS aus 7 bis 9 Personen besteht und laden eine entsprechende `group.yml` in AUAS
hoch. Im Gegensatz zu den normalen Blättern haben Sie volle hoch. Im Gegensatz zu den normalen Blättern haben Sie volle
Administrationsrechte und alle Projekte sind öffentlich um den Austausch mit Administrationsrechte und alle Projekte sind öffentlich um den Austausch mit
anderen Gruppen bei Integrationen zwischen Anwendungen einfacher zu gestalten. anderen Gruppen bei Integrationen zwischen Anwendungen einfacher zu gestalten.
@ -22,18 +22,18 @@ anderen Gruppen bei Integrationen zwischen Anwendungen einfacher zu gestalten.
IMPORTANT: Bitte entfernen Sie nicht die Organisatoren aus Ihrem Projekt. IMPORTANT: Bitte entfernen Sie nicht die Organisatoren aus Ihrem Projekt.
NOTE: Sie finden neben dieser README eine NOTE: Sie finden neben dieser README eine
link:gruppe.yml[Beispiel-Gruppe-YML-Datei]. Füllen Sie diese aus, checken Sie link:group.yml[Beispiel-Gruppe-YML-Datei]. Füllen Sie diese aus, checken Sie
sie ein. sie ein.
IMPORTANT: Erstellen Sie direkt eine Abgabe in AUAS. Diese ist *essentiell* für IMPORTANT: Erstellen Sie direkt eine Abgabe in AUAS. Diese ist *essentiell* für
die Teilnahme am Praktikum. Diesmal muss die Abgabe eine ZIP-Datei sein. Die die Teilnahme am Praktikum. Diesmal muss die Abgabe eine ZIP-Datei sein. Die
ZIP-Datei soll die `gruppe.yml` und eine _optionale_ Beschreibung eines eigenen ZIP-Datei soll die `group.yml` und eine _optionale_ Beschreibung eines eigenen
Systems für MOPS beinhalten. Sie können natürlich auch einfach die Systems für MOPS beinhalten. Sie können natürlich auch einfach die
vorgeschlagenen Systeme wählen und müssen keine eigenen Systeme entwerfen. vorgeschlagenen Systeme wählen und müssen keine eigenen Systeme entwerfen.
== Systeme == Systeme
*Die folgenden Beschreibungen sind keine Spezifikationen, die den Funktionsumfang der Projekte festlegen,* sondern nur ein "Braindump" von den Ideen, die mir zu dem entsprechenden System gekommen sind. Die Beschreibungen sollen Ihnen primär helfen, Systeme auszusuchen, die Sie umsetzen möchten. Wenn Sie einen eigenen Vorschlag für ein System haben, können Sie das auch gerne vorschlagen. Sie müssen dann zusammen mit der `gruppe.yml` Datei einen kurzen Pitch (in etwa wie in diesem Dokument) einreichen, damit wir uns vorstellen können, was Sie machen wollen und den Umfang begutachten. *Die folgenden Beschreibungen sind keine Spezifikationen, die den Funktionsumfang der Projekte festlegen,* sondern nur ein "Braindump" von den Ideen, die mir zu dem entsprechenden System gekommen sind. Die Beschreibungen sollen Ihnen primär helfen, Systeme auszusuchen, die Sie umsetzen möchten. Wenn Sie einen eigenen Vorschlag für ein System haben, können Sie das auch gerne vorschlagen. Sie müssen dann zusammen mit der `group.yml` Datei einen kurzen Pitch (in etwa wie in diesem Dokument) einreichen, damit wir uns vorstellen können, was Sie machen wollen und den Umfang begutachten.
=== Online Modulhandbuch === Online Modulhandbuch
Im Modulhandbuch werden die Beschreibungen für Veranstaltungen angegeben. Die Beschreibungen werden von den Dozierenden angelegt und werden von einer Verantwortlichen geprüft und dann freigeschaltet. Im Modulhandbuch werden die Beschreibungen für Veranstaltungen angegeben. Die Beschreibungen werden von den Dozierenden angelegt und werden von einer Verantwortlichen geprüft und dann freigeschaltet.

View File

@ -4,11 +4,18 @@ plugins {
id 'org.springframework.boot' version '2.2.5.RELEASE' id 'org.springframework.boot' version '2.2.5.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java' id 'java'
id 'com.github.spotbugs' version "3.0.0"
id 'com.github.spotbugs' version '3.0.0'
id 'checkstyle' id 'checkstyle'
} }
group = 'mops'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
spotbugs{ spotbugs{
ignoreFailures = true ignoreFailures = true
reportLevel = "high"
effort = "max" effort = "max"
toolVersion = '4.0.0-RC1' toolVersion = '4.0.0-RC1'
} }
@ -26,10 +33,6 @@ checkstyle {
ignoreFailures = true ignoreFailures = true
} }
group = 'mops'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations { configurations {
developmentOnly developmentOnly
runtimeClasspath { runtimeClasspath {
@ -56,21 +59,25 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0' implementation 'org.keycloak:keycloak-spring-boot-starter:9.0.0'
implementation 'org.keycloak.bom:keycloak-adapter-bom:3.3.0.Final' implementation 'org.keycloak.bom:keycloak-adapter-bom:3.3.0.Final'
implementation 'mops:styleguide:2.1.0' implementation 'mops:styleguide:2.1.0'
compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0' implementation 'io.springfox:springfox-swagger2:2.9.2'
compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0' implementation 'io.springfox:springfox-swagger-ui:2.9.2'
implementation 'com.github.javafaker:javafaker:1.0.2'
compileOnly 'org.projectlombok:lombok' compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.assertj:assertj-core:3.15.0'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.assertj:assertj-core:3.15.0'
testImplementation('org.springframework.boot:spring-boot-starter-test') { testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
} }
testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.springframework.security:spring-security-test'
compile('org.springframework.boot:spring-boot-starter-web') testImplementation 'com.tngtech.archunit:archunit-junit5:0.13.1'
} }
test { test {

View File

@ -229,13 +229,6 @@
<property name="lineWrappingIndentation" value="8"/> <property name="lineWrappingIndentation" value="8"/>
<property name="arrayInitIndent" value="4"/> <property name="arrayInitIndent" value="4"/>
</module> </module>
<module name="AbbreviationAsWordInName">
<property name="ignoreFinal" value="false"/>
<property name="allowedAbbreviationLength" value="1"/>
<property name="tokens"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF"/>
</module>
<module name="OverloadMethodsDeclarationOrder"/> <module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/> <module name="VariableDeclarationUsageDistance"/>
<module name="MethodParamPad"> <module name="MethodParamPad">

View File

@ -3,11 +3,16 @@ package mops.gruppen2;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.Collections;
@SpringBootApplication @SpringBootApplication
@EnableSwagger2 @EnableSwagger2
public class Gruppen2Application { public class Gruppen2Application {
@ -16,8 +21,25 @@ public class Gruppen2Application {
} }
@Bean @Bean
public Docket productAPI(){ public Docket productAPI() {
return new Docket(DocumentationType.SWAGGER_2).select() return new Docket(DocumentationType.SWAGGER_2)
.apis(RequestHandlerSelectors.basePackage("mops.gruppen2")).build(); .select()
.paths(PathSelectors.ant("/products/**"))
.apis(RequestHandlerSelectors.basePackage("mops.gruppen2"))
.build()
.apiInfo(apiMetadata());
}
private ApiInfo apiMetadata() {
return new ApiInfo(
"Gruppenbildung API",
"API zum anfragen/aktualisieren der Gruppendaten.",
"0.0.1",
"Free to use",
new Contact("gruppen2", "https://github.com/hhu-propra2/abschlussprojekt-it-bois", ""),
"",
"",
Collections.emptyList()
);
} }
} }

View File

@ -1,13 +1,11 @@
package mops.gruppen2.controllers; package mops.gruppen2.controller;
import mops.gruppen2.services.KeyCloakService; import mops.gruppen2.service.KeyCloakService;
import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken; import org.keycloak.adapters.springsecurity.token.KeycloakAuthenticationToken;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.annotation.SessionScope;
import javax.annotation.security.RolesAllowed; import javax.annotation.security.RolesAllowed;

View File

@ -0,0 +1,47 @@
package mops.gruppen2.controller;
import com.github.javafaker.Faker;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import mops.gruppen2.domain.ProductSwaggerExample;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* Ein Beispiel für eine API mit Swagger.
*/
@RestController
@RequestMapping("/products")
public class SwaggerAPIControllerExample {
private final Faker faker = new Faker();
private final List<ProductSwaggerExample> products = new ArrayList<>();
@GetMapping("/get/all")
@ApiOperation(value = "Erzeugt eine Liste mit allen gespeicherten Produkten")
public List<ProductSwaggerExample> getProducts() {
return products;
}
@GetMapping("/get/{index}")
public ProductSwaggerExample getProduct(@ApiParam("Produkt Index") @PathVariable int index) {
return products.get(index);
}
@PostMapping("/save")
public String saveProduct(@RequestBody ProductSwaggerExample product) {
products.add(product);
return "Product saved successfully";
}
@PostMapping("/random")
public String saveRandomProduct() {
products.add(new ProductSwaggerExample(faker.food().ingredient(), "Empty"));
return "Product saved successfully";
}
}

View File

@ -1,24 +0,0 @@
package mops.gruppen2.controllers;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
@RestController
public class SwaggerAPIController {
@RequestMapping(value = "/products", method = RequestMethod.GET)
public List<String> getProducts(){
List<String> productList = new ArrayList<>();
productList.add("Honey");
productList.add("Almond");
return productList;
}
@RequestMapping(value = "/products", method = RequestMethod.POST)
public String createProduct() {
return "Product is saved successfully";
}
}

View File

@ -1,15 +1,22 @@
package mops.gruppen2.entities; package mops.gruppen2.domain;
import mops.gruppen2.events.Event; import lombok.Getter;
import mops.gruppen2.domain.event.Event;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public abstract class Aggregat { /**
* Repräsentiert viele Events als aggregiertes Objekt.
*/
@Getter
public abstract class Aggregate {
protected long id;
/** /**
* Ruft die spezifische applyEvent-Methode im entsprechenden Aggregat auf. * Ruft die spezifische applyEvent-Methode im entsprechenden Aggregat auf.
* *
* @param event * @param event Event, welches aggregiert wird
*/ */
public void applyEvent(Event event) { public void applyEvent(Event event) {
try { try {

View File

@ -0,0 +1,74 @@
package mops.gruppen2.domain;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import mops.gruppen2.domain.event.*;
import java.util.*;
/**
* Repräsentiert den aggregierten Zustand einer Gruppe.
*/
@EqualsAndHashCode(callSuper = false)
@Getter
public class Group extends Aggregate {
private String title;
private String description;
private final List<User> members;
private final Map<User, Role> roles;
public Group() {
this.members = new ArrayList<>();
this.roles = new HashMap<>();
}
private void applyEvent(CreateGroupEvent event) {
title = event.getGroupTitle();
description = event.getGroupDescription();
id = event.getGroup_id();
}
private void applyEvent(UpdateRoleEvent event) {
User user;
Optional<User> userOptional = members.stream()
.filter(u -> u.getUser_id().equals(event.getUser_id()))
.findFirst();
if (userOptional.isPresent()) {
user = userOptional.get();
} else {
System.out.println("UserNotFoundException");
return;
}
if (roles.containsKey(user) && event.getNewRole() == Role.STUDENT) {
roles.remove(user);
} else {
roles.put(user, event.getNewRole());
}
}
private void applyEvent(AddUserEvent event) {
User user = new User(event.getUser_id(), event.getGivenname(), event.getFamilyname(), event.getEmail());
this.members.add(user);
}
private void applyEvent(UpdateGroupTitleEvent event) {
this.title = event.getNewGroupTitle();
}
private void applyEvent(UpdateGroupDescriptionEvent event) {
this.description = event.getNewGroupDescription();
}
private void applyEvent(DeleteUserEvent event) {
for (User user : members) {
if (user.getUser_id().equals(event.getUser_id())) {
this.members.remove(user);
break;
}
}
}
}

View File

@ -0,0 +1,12 @@
package mops.gruppen2.domain;
import lombok.Value;
// @ApiModelProperty
@Value
public class ProductSwaggerExample {
// @ApiModelProperty
String name;
String description;
}

View File

@ -0,0 +1,5 @@
package mops.gruppen2.domain;
public enum Role {
ORGA, ADMIN, STUDENT
}

View File

@ -0,0 +1,14 @@
package mops.gruppen2.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class User {
String user_id;
String givenname;
String familyname;
String email;
}

View File

@ -0,0 +1,30 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
import mops.gruppen2.domain.User;
/**
* Fügt einen einzelnen Nutzer einer Gruppe hinzu.
*/
@EqualsAndHashCode(callSuper = true)
@Value
public class AddUserEvent extends Event {
String givenname;
String familyname;
String email;
public AddUserEvent(long event_id, long group_id, String user_id, String givenname, String familyname, String email) {
super(event_id, group_id, user_id);
this.givenname = givenname;
this.familyname = familyname;
this.email = email;
}
public AddUserEvent(long event_id, long group_id, User user) {
super(event_id, group_id, user.getUser_id());
this.givenname = user.getGivenname();
this.familyname = user.getFamilyname();
this.email = user.getEmail();
}
}

View File

@ -0,0 +1,17 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
@EqualsAndHashCode(callSuper = true)
@Value
public class CreateGroupEvent extends Event {
String groupTitle;
String groupDescription;
public CreateGroupEvent(long event_id, long group_id, String user_id, String groupTitle, String groupDescription) {
super(event_id, group_id, user_id);
this.groupTitle = groupTitle;
this.groupDescription = groupDescription;
}
}

View File

@ -0,0 +1,16 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
/**
* Entfernt ein einzelnes Mitglied einer Gruppe.
*/
@EqualsAndHashCode(callSuper = true)
@Value
public class DeleteUserEvent extends Event {
public DeleteUserEvent(long event_id, long group_id, String user_id) {
super(event_id, group_id, user_id);
}
}

View File

@ -0,0 +1,12 @@
package mops.gruppen2.domain.event;
import lombok.Value;
import lombok.experimental.NonFinal;
@Value
@NonFinal
public class Event {
long event_id;
long group_id;
String user_id;
}

View File

@ -0,0 +1,18 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
/**
* Ändert nur die Gruppenbeschreibung.
*/
@EqualsAndHashCode(callSuper = true)
@Value
public class UpdateGroupDescriptionEvent extends Event {
String newGroupDescription;
public UpdateGroupDescriptionEvent(long event_id, long group_id, String user_id, String newGroupDescription) {
super(event_id, group_id, user_id);
this.newGroupDescription = newGroupDescription;
}
}

View File

@ -0,0 +1,18 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
/**
* Ändert nur den Gruppentitel.
*/
@EqualsAndHashCode(callSuper = true)
@Value
public class UpdateGroupTitleEvent extends Event {
String newGroupTitle;
public UpdateGroupTitleEvent(long event_id, long group_id, String user_id, String newGroupTitle) {
super(event_id, group_id, user_id);
this.newGroupTitle = newGroupTitle;
}
}

View File

@ -0,0 +1,21 @@
package mops.gruppen2.domain.event;
import lombok.EqualsAndHashCode;
import lombok.Value;
import mops.gruppen2.domain.Role;
/**
* Aktualisiert die Gruppenrolle eines Teilnehmers.
*/
@EqualsAndHashCode(callSuper = true)
@Value
public class UpdateRoleEvent extends Event {
Role newRole;
public UpdateRoleEvent(long event_id, long group_id, String user_id, Role newRole) {
super(event_id, group_id, user_id);
this.newRole = newRole;
}
}

View File

@ -1,4 +0,0 @@
package mops.gruppen2.entities;
public class Admin extends Rolle {
}

View File

@ -1,69 +0,0 @@
package mops.gruppen2.entities;
import lombok.Data;
import lombok.EqualsAndHashCode;
import mops.gruppen2.events.*;
import mops.gruppen2.events.AddUser;
import mops.gruppen2.events.CreateGroupEvent;
import mops.gruppen2.events.UpdateGroupDescriptionEvent;
import mops.gruppen2.events.UpdateGroupTitleEvent;
import mops.gruppen2.events.DeleteUserEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@EqualsAndHashCode(callSuper=false)
@Data
public class Gruppe extends Aggregat {
long id;
String titel;
String beschreibung;
List<Teilnehmer> teilnehmersList;
Map<Teilnehmer, Rolle> rollenList;
public void applyEvent(CreateGroupEvent event){
this.id = event.getGruppe_id();
this.titel = event.getTitel();
this.beschreibung = event.getBeschreibung();
this.teilnehmersList = new ArrayList<>();
this.rollenList = new HashMap<>();
}
public void applyEvent(UpdateRoleEvent event) {
teilnehmersList.stream()
.filter(teilnehmer -> teilnehmer.getId().equals(event.getUser_id()))
.findFirst()
.ifPresentOrElse(teilnehmer -> rollenList.put(teilnehmer, event.getRole()),
() -> System.out.println("UserNotFoundException"));
}
public void applyEvent(AddUser event){
Teilnehmer teilnehmer = new Teilnehmer();
teilnehmer.setId(event.getUser_id());
teilnehmer.setVorname(event.getVorname());
teilnehmer.setNachname(event.getNachname());
teilnehmer.setEmail(event.getEmail());
this.teilnehmersList.add(teilnehmer);
}
public void applyEvent(UpdateGroupTitleEvent event) {
this.titel = event.getTitel();
}
public void applyEvent(UpdateGroupDescriptionEvent event) {
this.beschreibung = event.getBeschreibung();
}
public void applyEvent(DeleteUserEvent event) {
for (Teilnehmer teilnehmer: teilnehmersList) {
if (teilnehmer.getId().equals(event.getUser_id())) {
this.teilnehmersList.remove(teilnehmer);
break;
}
}
}
}

View File

@ -1,4 +0,0 @@
package mops.gruppen2.entities;
public class Orga extends Rolle {
}

View File

@ -1,5 +0,0 @@
package mops.gruppen2.entities;
public class Rolle {
}

View File

@ -1,14 +0,0 @@
package mops.gruppen2.entities;
import lombok.Data;
import java.util.List;
@Data
public class Teilnehmer {
String id;
String vorname;
String nachname;
String email;
List<Gruppe> Gruppen;
}

View File

@ -1,15 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
@Getter
public class AddUser extends Event{
String vorname, nachname, email;
public AddUser(long id, long gruppe_id, String user_id, String vorname, String nachname, String email) {
super(id, gruppe_id, user_id);
this.vorname = vorname;
this.nachname = nachname;
this.email = email;
}
}

View File

@ -1,15 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
@Getter
public class CreateGroupEvent extends Event {
String titel;
String beschreibung;
public CreateGroupEvent(long id, long gruppe_id, String user_id, String titel, String beschreibung) {
super(id, gruppe_id, user_id);
this.titel = titel;
this.beschreibung = beschreibung;
}
}

View File

@ -1,11 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
@Getter
public class DeleteUserEvent extends Event{
public DeleteUserEvent(long id, long gruppe_id, String user_id) {
super(id, gruppe_id, user_id);
}
}

View File

@ -1,12 +0,0 @@
package mops.gruppen2.events;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class Event {
long id;
long gruppe_id;
String user_id;
}

View File

@ -1,13 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
@Getter
public class UpdateGroupDescriptionEvent extends Event {
String beschreibung;
public UpdateGroupDescriptionEvent(long id, long gruppe_id, String user_id, String beschreibung) {
super(id, gruppe_id, user_id);
this.beschreibung = beschreibung;
}
}

View File

@ -1,13 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
@Getter
public class UpdateGroupTitleEvent extends Event {
String titel;
public UpdateGroupTitleEvent(long id, long gruppe_id, String user_id, String titel) {
super(id, gruppe_id, user_id);
this.titel = titel;
}
}

View File

@ -1,16 +0,0 @@
package mops.gruppen2.events;
import lombok.Getter;
import mops.gruppen2.entities.Rolle;
@Getter
public class UpdateRoleEvent extends Event {
private final Rolle role;
public UpdateRoleEvent(long id, long gruppe_id, String user_id, Rolle newRole) {
super(id, gruppe_id, user_id);
this.role = newRole;
}
}

View File

@ -1,6 +1,6 @@
package mops.gruppen2.repositories; package mops.gruppen2.repository;
import mops.gruppen2.events.Event; import mops.gruppen2.domain.event.Event;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
public interface EventRepository extends CrudRepository<Event, Long> { public interface EventRepository extends CrudRepository<Event, Long> {

View File

@ -6,7 +6,11 @@ import org.keycloak.adapters.springsecurity.authentication.KeycloakAuthenticatio
import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter; import org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter;
import org.keycloak.representations.AccessToken; import org.keycloak.representations.AccessToken;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration; import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
@ -70,8 +74,6 @@ class SecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
http.headers().frameOptions().disable(); http.headers().frameOptions().disable();
} }
/** /**
* Declaring this class enables us to use the Spring specific * Declaring this class enables us to use the Spring specific
* {@link org.springframework.security.access.annotation.Secured} annotation * {@link org.springframework.security.access.annotation.Secured} annotation

View File

@ -0,0 +1,26 @@
package mops.gruppen2.service;
import mops.gruppen2.domain.Group;
import mops.gruppen2.domain.event.Event;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GroupService {
/**
* Konstruiert eine vollständige Gruppe aus Events, welche dieselbe Gruppe betreffen.
*
* @param event Initiales CreateGroup-Event
* @param eventList Die restlichen Events für diese Gruppe
* @return Gruppe auf aktuellem Stand
*/
Group buildGroupFromEvents(List<Event> eventList) {
Group newGroup = new Group();
eventList.forEach(newGroup::applyEvent);
return newGroup;
}
}

View File

@ -1,4 +1,4 @@
package mops.gruppen2.services; package mops.gruppen2.service;
import mops.gruppen2.security.Account; import mops.gruppen2.security.Account;
import org.keycloak.KeycloakPrincipal; import org.keycloak.KeycloakPrincipal;

View File

@ -0,0 +1,10 @@
package mops.gruppen2.service;
import org.springframework.stereotype.Service;
/**
* Übersetzt JSON-Event-Payloads zu Java-Event-Repräsentationen und zurück.
*/
@Service
public class SerializationService {
}

View File

@ -1,16 +0,0 @@
package mops.gruppen2.services;
import mops.gruppen2.events.Event;
import mops.gruppen2.entities.Gruppe;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GruppenService {
Gruppe buildGroup(List<Event> eventList){
Gruppe newGroup = new Gruppe();
eventList.forEach(newGroup::applyEvent);
return newGroup;
}
}

View File

@ -1,10 +0,0 @@
package mops.gruppen2.services;
import org.springframework.stereotype.Service;
/**
* Übersetzt und baut
*/
@Service
public class SerializationService {
}

View File

@ -14,4 +14,3 @@ keycloak.auth-server-url=https://keycloak.cs.hhu.de/auth
keycloak.realm=MOPS keycloak.realm=MOPS
keycloak.resource=demo keycloak.resource=demo
keycloak.public-client=true keycloak.public-client=true

View File

@ -1,4 +0,0 @@
-- noinspection SqlNoDataSourceInspectionForFile
insert into TEILNEHMER (VORNAME, NACHNAME, EMAIL) values
('Peter', 'Müller', 'Peter@123.de');

View File

@ -1,25 +1,11 @@
-- noinspection SqlNoDataSourceInspectionForFile -- noinspection SqlNoDataSourceInspectionForFile
DROP TABLE IF EXISTS teilnehmer; DROP TABLE IF EXISTS event;
CREATE TABLE teilnehmer (
teilnehmer_id INT PRIMARY KEY AUTO_INCREMENT,
vorname VARCHAR(50) NOT NULL,
nachname VARCHAR(50) NOT NULL ,
email VARCHAR(255) NOT NULL
);
DROP TABLE IF EXISTS gruppe; CREATE TABLE event
CREATE TABLE gruppe
( (
gruppe_id INTEGER PRIMARY KEY auto_increment, event_id INT PRIMARY KEY AUTO_INCREMENT,
titel TEXT NOT NULL, group_id INT NOT NULL,
beschreibung TEXT NOT NULL user_id VARCHAR(50),
); event_payload VARCHAR(255)
DROP TABLE IF EXISTS teilnahme;
CREATE TABLE teilnahme
(
id INTEGER PRIMARY KEY auto_increment,
teilnehmer_dto INTEGER REFERENCES teilnehmer(teilnehmer_id),
gruppe_dto INTEGER REFERENCES gruppe(gruppe_id)
); );

View File

@ -0,0 +1,78 @@
package mops.gruppen2.domain;
import mops.gruppen2.domain.event.AddUserEvent;
import mops.gruppen2.domain.event.CreateGroupEvent;
import mops.gruppen2.domain.event.UpdateRoleEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class GroupTest {
@BeforeEach
public void setUp(){
}
@Disabled
@Test
void applyEvent() {
}
@Test
void createSingleGroup() {
CreateGroupEvent createGroupEvent = new CreateGroupEvent(1,2, "asd", "hello", "foo");
Group group = new Group();
group.applyEvent(createGroupEvent);
assertThat(group.getDescription()).isEqualTo("foo");
assertThat(group.getTitle()).isEqualTo("hello");
assertThat(group.getId()).isEqualTo(2);
}
// Verwendet CreateGroupEvent
@Test
void addSingleUser() {
CreateGroupEvent createGroupEvent = new CreateGroupEvent(1,1,"prof1", "hi", "foo");
Group group = new Group();
group.applyEvent(createGroupEvent);
User user = new User("prof", "jens", "bendi", "hi@gmail.com");
AddUserEvent addUserEvent = new AddUserEvent(1,1, user);
group.applyEvent(addUserEvent);
assertThat(group.getMembers().get(0)).isEqualTo(user);
}
// Verwendet CreateGroupEvent und AddUserEvent
@Test
void updateRoleForExistingUser() {
// Arrange
CreateGroupEvent createGroupEvent = new CreateGroupEvent(1L, 1L, "1L", "gruppe1", "Eine Testgruppe");
AddUserEvent addUserEvent = new AddUserEvent(1L, 1L, "5L", "Peter", "Pan", "123@mail.de");
Group group = new Group();
group.applyEvent(createGroupEvent);
group.applyEvent(addUserEvent);
UpdateRoleEvent updateRoleEvent = new UpdateRoleEvent(1L, 1L, "5L", Role.ORGA);
// Act
group.applyEvent(updateRoleEvent);
// Assert
assertThat(group.getRoles())
.containsOnlyKeys(group.getMembers().get(0))
.containsValue(Role.ORGA);
}
@Disabled
@Test
void updateRoleForNonExistingUser() {
}
}

View File

@ -1,90 +0,0 @@
package mops.gruppen2.entities;
import mops.gruppen2.events.AddUser;
import mops.gruppen2.events.CreateGroupEvent;
import mops.gruppen2.events.UpdateRoleEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
class GruppeTest {
AddUser addUser;
CreateGroupEvent createGroupEvent;
@BeforeEach
public void setUp(){
}
@Test
void applyEvent() {
}
@Test
void applyAddUserEvent(){
Gruppe gruppe = new Gruppe();
Gruppe testGruppe = new Gruppe();
Teilnehmer teilnehmer = new Teilnehmer();
addUser = new AddUser(1L,1L,"prof","jens","bendi", "hi@gmail.com");
createGroupEvent = new CreateGroupEvent(1L,1L,"prof1", "hi", "foo");
gruppe.applyEvent(createGroupEvent);
gruppe.applyEvent(addUser);
testGruppe.applyEvent(createGroupEvent);
teilnehmer.setId("prof");
teilnehmer.setVorname("jens");
teilnehmer.setNachname("bendi");
teilnehmer.setEmail("hi@gmail.com");
List<Teilnehmer> testTeil= new ArrayList<>();
testTeil.add(teilnehmer);
testGruppe.setTeilnehmersList(testTeil);
assertEquals(testGruppe,gruppe);
}
// Verwendet CreateGroupEvent und AddUserEvent
@Test
void updateRoleForExistingUser() {
// Arrange
Gruppe gruppe = new Gruppe();
Orga orga = new Orga();
gruppe.applyEvent(new CreateGroupEvent(1L, 1L, "1L", "gruppe1", "Eine Testgruppe"));
gruppe.applyEvent(new AddUser(1L, 1L, "5L", "Peter", "Pan", "123@mail.de"));
// Act
gruppe.applyEvent(new UpdateRoleEvent(1L, 1L, "5L", orga));
// Assert
assertThat(gruppe.getRollenList())
.containsOnlyKeys(gruppe.getTeilnehmersList().get(0))
.containsValue(orga);
}
@Test
void applyCreteGroupEvent() {
String userId = "asd";
CreateGroupEvent event = new CreateGroupEvent(1L,2,userId, "hello", "foo");
Gruppe gruppe1 = new Gruppe();
gruppe1.applyEvent(event);
Gruppe gruppe2 = new Gruppe();
gruppe2.id = 2L;
gruppe2.titel = "hello";
gruppe2.beschreibung = "foo";
gruppe2.teilnehmersList = new ArrayList<>();
gruppe2.rollenList = new HashMap<>();
assertEquals(gruppe2, gruppe1);
}
}