diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 06b35905..7245f0d6 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -7,11 +7,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout the code
- uses: actions/checkout@v3
- - name: Set up JDK 1.17
- uses: actions/setup-java@v3
+ uses: actions/checkout@v4
+ - name: Set up JDK 21
+ uses: actions/setup-java@v4
with:
- java-version: 17.0.4+1
+ java-version: 21
distribution: zulu
- name: Build the project with Maven
run: ./mvnw --batch-mode -update-snapshots package
diff --git a/Dockerfile b/Dockerfile
index 3b70f93f..c38de528 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
-FROM openjdk:17-slim
+FROM openjdk:21-slim
ADD target/dancer.jar /dancer.jar
CMD ["java", "--enable-preview", "-jar", "/dancer.jar"]
diff --git a/Readme.md b/Readme.md
index 92475e02..8b0a492c 100644
--- a/Readme.md
+++ b/Readme.md
@@ -58,7 +58,7 @@ Here you can configure the connection to the postgres instance:
# stopping dancer in docker-compose
docker-compose stop dancer;
# running the boot app with overwriting the needed host
-./mvnw spring-boot:run -Dspring-boot.run.arguments="--spring.datasource.url=jdbc:postgresql://localhost:5432/dancer --spring.kafka.bootstrap-servers=localhost:9092"
+./mvnw spring-boot:run -Dspring-boot.run.arguments="--spring.datasource.url=jdbc:postgresql://localhost:5432/dancer
````
#### checking test-coverage
diff --git a/swagger.yaml b/api/swagger.yaml
similarity index 98%
rename from swagger.yaml
rename to api/swagger.yaml
index 46379e9f..b033b738 100644
--- a/swagger.yaml
+++ b/api/swagger.yaml
@@ -398,7 +398,9 @@ paths:
tags:
- Contacts
requestBody:
- description: the mail will end up in dev@dancier.net
+ description: >
+ The mail will end up in dev@dancier.net, the sender will also get a copy of the mail.
+ When the user of this endpoint is logged in, the senders email-address will be the one from the user. In this case the provided value in this payload will be ignored.
required: true
content:
application/json:
diff --git a/docker-compose.yml b/docker-compose.yml
index 1dff1177..6b63e3af 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -12,6 +12,7 @@ services:
- dancer-db
environment:
# https://ckinan.com/blog/remote-debug-spring-boot-docker-intellij/:
+ - SPRING_DATASOURCE_URL=jdbc:postgresql://dancer-db:5432/dancer
- SPRING_PROFILES_ACTIVE="dev"
- JAVA_TOOL_OPTIONS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
dancer-db:
@@ -27,7 +28,7 @@ services:
- ./volumes/dancer-data:/var/lib/postgresql/data
pg-admin:
- image: dpage/pgadmin4:7
+ image: dpage/pgadmin4:8.1
restart: always
ports:
- "5050:80"
diff --git a/pom.xml b/pom.xml
index e944ad25..c409b436 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 2.7.14
+ 3.2.0
net.dancier
@@ -14,8 +14,7 @@
dancer
Demo project for Spring Boot
- 5.8.8
- 17
+ 21
1.15.1
@@ -51,15 +50,35 @@
org.springframework.boot
spring-boot-starter-webflux
+
+ io.cloudevents
+ cloudevents-kafka
+ 2.5.0
+
+
+ io.cloudevents
+ cloudevents-json-jackson
+ 2.5.0
+
org.springframework.boot
spring-boot-starter-validation
+
+ org.springframework.kafka
+ spring-kafka-test
+ test
+
org.springframework.security
spring-security-test
test
+
+
+ org.thymeleaf.extras
+ thymeleaf-extras-springsecurity6
+
com.vladmihalcea
hibernate-types-52
@@ -101,6 +120,7 @@
org.projectlombok
lombok
+ true
io.minio
@@ -151,37 +171,17 @@
io.micrometer
micrometer-registry-prometheus
+ runtime
dancer
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
-
- 17
- --enable-preview
-
-
-
- maven-surefire-plugin
-
- --enable-preview
-
-
-
- maven-failsafe-plugin
-
- --enable-preview
-
-
org.jacoco
jacoco-maven-plugin
- 0.8.7
+ 0.8.11
@@ -201,7 +201,12 @@
org.springframework.boot
spring-boot-maven-plugin
- --enable-preview
+
+
+ org.projectlombok
+ lombok
+
+
diff --git a/src/main/java/net/dancier/dancer/DancerApplication.java b/src/main/java/net/dancier/dancer/DancerApplication.java
index b07e8843..24c05cf8 100644
--- a/src/main/java/net/dancier/dancer/DancerApplication.java
+++ b/src/main/java/net/dancier/dancer/DancerApplication.java
@@ -8,7 +8,7 @@
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
import org.springframework.scheduling.annotation.EnableScheduling;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import java.util.TimeZone;
@SpringBootApplication
diff --git a/src/main/java/net/dancier/dancer/authentication/AdminUserInitializer.java b/src/main/java/net/dancier/dancer/authentication/AdminUserInitializer.java
index 3a952c4c..67b2c1b3 100644
--- a/src/main/java/net/dancier/dancer/authentication/AdminUserInitializer.java
+++ b/src/main/java/net/dancier/dancer/authentication/AdminUserInitializer.java
@@ -14,8 +14,8 @@
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
-import javax.annotation.PostConstruct;
-import javax.transaction.Transactional;
+import jakarta.annotation.PostConstruct;
+import jakarta.transaction.Transactional;
import java.util.Collection;
import java.util.Optional;
diff --git a/src/main/java/net/dancier/dancer/authentication/AuthenticationController.java b/src/main/java/net/dancier/dancer/authentication/AuthenticationController.java
index f21fa4de..bc7dddbe 100644
--- a/src/main/java/net/dancier/dancer/authentication/AuthenticationController.java
+++ b/src/main/java/net/dancier/dancer/authentication/AuthenticationController.java
@@ -27,9 +27,9 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
-import javax.servlet.http.HttpServletResponse;
-import javax.validation.Valid;
-import javax.validation.constraints.NotNull;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotNull;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
@@ -64,6 +64,7 @@ public ResponseEntity> whoami() {
@Secured({ROLE_HUMAN})
@PostMapping("/registrations")
public ResponseEntity> register(@Valid @RequestBody RegisterRequestDto registerRequest) {
+ log.info("About to register user: " + registerRequest);
try {
authenticationService.registerUser(registerRequest);
} catch (UserOrEmailAlreadyExistsException userOrEmailAlreadyExistsException) {
@@ -107,19 +108,19 @@ public ResponseEntity> loginAsHuman(@RequestHeader(required = false, name = "X
HttpServletResponse httpServletResponse) {
log.info("Log in as human");
ResponseCookie cookie = null;
+ String jwt = null;
try {
captchaService.verifyToken(token);
+ jwt = authenticationService.generateJwtToken("HUMAN");
cookie = authenticationService
- .generateCookie(
- authenticationService.generateJwtToken("HUMAN")
- );
+ .generateCookie(jwt);
httpServletResponse.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());
} catch (CaptchaException captchaException) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(
new ApiResponse(false, "Not authorized as a human: " + captchaException.getMessage())
);
}
- return ResponseEntity.ok().build();
+ return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
@GetMapping("/logout")
diff --git a/src/main/java/net/dancier/dancer/authentication/dto/RegisterRequestDto.java b/src/main/java/net/dancier/dancer/authentication/dto/RegisterRequestDto.java
index 543ecbba..9f021bac 100644
--- a/src/main/java/net/dancier/dancer/authentication/dto/RegisterRequestDto.java
+++ b/src/main/java/net/dancier/dancer/authentication/dto/RegisterRequestDto.java
@@ -4,7 +4,7 @@
import lombok.Data;
import lombok.NoArgsConstructor;
-import javax.validation.constraints.*;
+import jakarta.validation.constraints.*;
@Data
@AllArgsConstructor
diff --git a/src/main/java/net/dancier/dancer/authentication/dto/SendLinkDto.java b/src/main/java/net/dancier/dancer/authentication/dto/SendLinkDto.java
index f1b12146..99e0e6ae 100644
--- a/src/main/java/net/dancier/dancer/authentication/dto/SendLinkDto.java
+++ b/src/main/java/net/dancier/dancer/authentication/dto/SendLinkDto.java
@@ -3,9 +3,9 @@
import lombok.Data;
import lombok.NoArgsConstructor;
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.Size;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.Size;
@Data
@NoArgsConstructor
diff --git a/src/main/java/net/dancier/dancer/authentication/event/NewUserCreatedEventListener.java b/src/main/java/net/dancier/dancer/authentication/event/NewUserCreatedEventListener.java
index cbf8c43e..2d96bb82 100644
--- a/src/main/java/net/dancier/dancer/authentication/event/NewUserCreatedEventListener.java
+++ b/src/main/java/net/dancier/dancer/authentication/event/NewUserCreatedEventListener.java
@@ -4,10 +4,11 @@
import net.dancier.dancer.authentication.model.EmailValidationCode;
import net.dancier.dancer.authentication.repository.EmailValidationCodeRepository;
import net.dancier.dancer.mail.service.MailCreationService;
-import net.dancier.dancer.mail.service.MailEnqueueService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
+import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Component;
import java.time.Instant;
@@ -23,7 +24,8 @@ public class NewUserCreatedEventListener {
private final static Logger log = LoggerFactory.getLogger(NewUserCreatedEventListener.class);
private final EmailValidationCodeRepository emailValidationCodeRepository;
- private final MailEnqueueService mailEnqueueService;
+
+ private final ApplicationEventPublisher applicationEventPublisher;
private final MailCreationService mailCreationService;
@@ -41,20 +43,20 @@ void handle(NewUserCreatedEvent newUserCreatedEvent) {
emailValidationCode.setUserId(newUserCreatedEvent.getId());
emailValidationCode.setCode(UUID.randomUUID().toString());
emailValidationCodeRepository.save(emailValidationCode);
- enqueueUserMail(newUserCreatedEvent, emailValidationCode.getCode());
+ applicationEventPublisher.publishEvent(
+ createMailMessage(newUserCreatedEvent, emailValidationCode.getCode())
+ );
log.debug("Created validation code: " + emailValidationCode.getCode() + " for user: " + newUserCreatedEvent);
}
- private void enqueueUserMail(NewUserCreatedEvent newUserCreatedEvent, String code) {
- mailEnqueueService.enqueueMail(
- mailCreationService.createDancierMessageFromTemplate(
+ private SimpleMailMessage createMailMessage(NewUserCreatedEvent newUserCreatedEvent, String code) {
+ return mailCreationService.createDancierMessageFromTemplate(
newUserCreatedEvent.getEmail(),
MailCreationService.NO_REPLY_FROM,
"Dancier - bestätige Deine E-Mail-Adresse!",
MailCreationService.NEW_USER_VALIDATE_EMAIL,
Map.of( "validationLink", emailValidationLink(code)
- ))
- );
+ ));
}
private String emailValidationLink(String validationCode) {
diff --git a/src/main/java/net/dancier/dancer/authentication/model/EmailValidationCode.java b/src/main/java/net/dancier/dancer/authentication/model/EmailValidationCode.java
index d15e4a3a..b8e359ce 100644
--- a/src/main/java/net/dancier/dancer/authentication/model/EmailValidationCode.java
+++ b/src/main/java/net/dancier/dancer/authentication/model/EmailValidationCode.java
@@ -2,8 +2,8 @@
import lombok.Data;
-import javax.persistence.*;
-import javax.validation.constraints.NotNull;
+import jakarta.persistence.*;
+import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/authentication/model/PasswordResetCode.java b/src/main/java/net/dancier/dancer/authentication/model/PasswordResetCode.java
index 41405d63..ef4169ee 100644
--- a/src/main/java/net/dancier/dancer/authentication/model/PasswordResetCode.java
+++ b/src/main/java/net/dancier/dancer/authentication/model/PasswordResetCode.java
@@ -2,7 +2,7 @@
import lombok.Data;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.time.Instant;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/authentication/model/Role.java b/src/main/java/net/dancier/dancer/authentication/model/Role.java
index b092df7b..726df04f 100644
--- a/src/main/java/net/dancier/dancer/authentication/model/Role.java
+++ b/src/main/java/net/dancier/dancer/authentication/model/Role.java
@@ -1,9 +1,8 @@
package net.dancier.dancer.authentication.model;
+import jakarta.persistence.*;
import lombok.Data;
-import org.hibernate.annotations.NaturalId;
-import javax.persistence.*;
import java.util.UUID;
@Data
diff --git a/src/main/java/net/dancier/dancer/authentication/model/User.java b/src/main/java/net/dancier/dancer/authentication/model/User.java
index 077f5fea..9e4aae11 100644
--- a/src/main/java/net/dancier/dancer/authentication/model/User.java
+++ b/src/main/java/net/dancier/dancer/authentication/model/User.java
@@ -2,11 +2,11 @@
import lombok.Data;
-import javax.persistence.*;
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import javax.validation.constraints.Size;
+import jakarta.persistence.*;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
import java.util.Collection;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/authentication/model/VerifiedActionCode.java b/src/main/java/net/dancier/dancer/authentication/model/VerifiedActionCode.java
index 92a8e68a..d30ec3f2 100644
--- a/src/main/java/net/dancier/dancer/authentication/model/VerifiedActionCode.java
+++ b/src/main/java/net/dancier/dancer/authentication/model/VerifiedActionCode.java
@@ -2,8 +2,8 @@
import lombok.Data;
-import javax.persistence.*;
-import javax.validation.constraints.NotNull;
+import jakarta.persistence.*;
+import jakarta.validation.constraints.NotNull;
import java.time.Instant;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/authentication/service/AuthenticationService.java b/src/main/java/net/dancier/dancer/authentication/service/AuthenticationService.java
index 502b30ca..2997fd03 100644
--- a/src/main/java/net/dancier/dancer/authentication/service/AuthenticationService.java
+++ b/src/main/java/net/dancier/dancer/authentication/service/AuthenticationService.java
@@ -1,5 +1,7 @@
package net.dancier.dancer.authentication.service;
+import jakarta.persistence.EntityNotFoundException;
+import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.dancier.dancer.authentication.dto.RegisterRequestDto;
import net.dancier.dancer.authentication.event.NewUserCreatedEvent;
@@ -10,19 +12,16 @@
import net.dancier.dancer.core.exception.BusinessException;
import net.dancier.dancer.core.exception.NotFoundException;
import net.dancier.dancer.mail.service.MailCreationService;
-import net.dancier.dancer.mail.service.MailEnqueueService;
import net.dancier.dancer.security.JwtTokenProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.ResponseCookie;
-import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
-import javax.persistence.EntityNotFoundException;
-import javax.transaction.Transactional;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
@@ -44,21 +43,22 @@ public class AuthenticationService {
private final PasswordResetCodeRepository passwordResetCodeRepository;
- private final AuthenticationManager authenticationManager;
+ private final AuthenticationProvider authenticationProvider;
private final JwtTokenProvider tokenProvider;
- private final MailEnqueueService mailEnqueueService;
-
private final MailCreationService mailCreationService;
private final VerifiedActionCodeRepository verifiedActionCodeRepository;
+
private final String frontendBaseName;
+
private final ApplicationEventPublisher applicationEventPublisher;
+
private final CookieConfiguration cookieConfiguration;
public Authentication authenticate(Authentication authentication) {
- return this.authenticationManager.authenticate(authentication);
+ return this.authenticationProvider.authenticate(authentication);
}
public String generateJwtToken(Authentication authentication) {
return this.tokenProvider.generateJwtToken(authentication);
@@ -83,8 +83,11 @@ public ResponseCookie generateCookie(String token) {
* By setting the maxAge to 0, the cookie will be deleted by the browser.
*/
public ResponseCookie generateClearingCookie() {
- return ResponseCookie.from("jwt-token", "")
- .build();
+ return ResponseCookie
+ .from("jwt-token", "")
+ .path("/")
+ .maxAge(0)
+ .build();
}
public User getUser(UUID userId) {
@@ -136,7 +139,7 @@ private void handleRegistrationAttemptOfAlreadyExistingAccount(User user) {
loginLink():
emailValidationLink(createEmailValidationCode(user));
- enqueueTypedUserMail(user.getEmail(),"Du bist schon Mitglied bei dancier.net ;-)", MailCreationService.USER_ALREADY_EXISTS_EMAIL,
+ sendUserMail(user.getEmail(),"Du bist schon Mitglied bei dancier.net ;-)", MailCreationService.USER_ALREADY_EXISTS_EMAIL,
Map.of("passwordResetLink", passwordResetLink(passwordResetCode),
"email", user.getEmail(),
"loginLink", loginLink)
@@ -226,17 +229,19 @@ public void checkPasswortCodeRequestAndCreateNew(String code, String newPassword
}
public void sendChangePasswordMail(String email, String code) {
- enqueueTypedUserMail(email,
+ sendUserMail(email,
"Du möchtest dein Passwort auf dancier.net ändern...",
MailCreationService.PASSWORD_CHANGE_REQUEST_EMAIL,
Map.of("changePasswordLink", passwordResetLink(code))
);
- } private void enqueueTypedUserMail(String email,
- String subject,
- String template,
- Map data) {
- mailEnqueueService.enqueueMail(
+ }
+
+ private void sendUserMail(String email,
+ String subject,
+ String template,
+ Map data) {
+ applicationEventPublisher.publishEvent(
mailCreationService.createDancierMessageFromTemplate(
email,
MailCreationService.NO_REPLY_FROM,
@@ -247,15 +252,14 @@ public void sendChangePasswordMail(String email, String code) {
);
}
private void enqueueUserMail(User user, String validationCode) {
- mailEnqueueService.enqueueMail(
- mailCreationService.createDancierMessageFromTemplate(
- user.getEmail(),
- MailCreationService.NO_REPLY_FROM,
- "Dancier - bestätige Deine E-Mail-Adresse!",
- MailCreationService.NEW_USER_VALIDATE_EMAIL,
- Map.of( "validationLink", emailValidationLink(validationCode)
+ applicationEventPublisher.publishEvent(
+ mailCreationService.createDancierMessageFromTemplate(
+ user.getEmail(),
+ MailCreationService.NO_REPLY_FROM,
+ "Dancier - bestätige Deine E-Mail-Adresse!",
+ MailCreationService.NEW_USER_VALIDATE_EMAIL,
+ Map.of( "validationLink", emailValidationLink(validationCode)
))
);
}
-
}
diff --git a/src/main/java/net/dancier/dancer/authentication/service/CaptchaClientProd.java b/src/main/java/net/dancier/dancer/authentication/service/CaptchaClientProd.java
index 8166d09d..64a81b27 100644
--- a/src/main/java/net/dancier/dancer/authentication/service/CaptchaClientProd.java
+++ b/src/main/java/net/dancier/dancer/authentication/service/CaptchaClientProd.java
@@ -23,9 +23,6 @@ public class CaptchaClientProd implements CaptchaClient {
@Value("${app.captcha.siteKey}")
private String siteKey;
- @Value("${app.mail.user}")
- private String mailuser;
-
@Value("${app.captcha.apiKey}")
private String apiKey;
diff --git a/src/main/java/net/dancier/dancer/chat/DancerController.java b/src/main/java/net/dancier/dancer/chat/DancerController.java
index 4a5594a7..e32c6a23 100644
--- a/src/main/java/net/dancier/dancer/chat/DancerController.java
+++ b/src/main/java/net/dancier/dancer/chat/DancerController.java
@@ -36,4 +36,10 @@ public ResponseEntity> post(
dancerService.getDancerMap(dancerIdsDto)
);
}
+
+ @GetMapping("/{dancerId}/mail")
+ public ResponseEntity getMail(@PathVariable UUID dancierId) {
+ log.info("Getting email-Address for: " + dancierId);
+ return ResponseEntity.ok("foo");
+ }
}
diff --git a/src/main/java/net/dancier/dancer/chat/client/ChatServiceClient.java b/src/main/java/net/dancier/dancer/chat/client/ChatServiceClient.java
index 32f6b910..15b66879 100644
--- a/src/main/java/net/dancier/dancer/chat/client/ChatServiceClient.java
+++ b/src/main/java/net/dancier/dancer/chat/client/ChatServiceClient.java
@@ -1,12 +1,13 @@
package net.dancier.dancer.chat.client;
import io.netty.handler.logging.LogLevel;
-import net.dancier.dancer.chat.dto.*;
+import net.dancier.dancer.chat.dto.ChatDto;
+import net.dancier.dancer.chat.dto.CreateChatDto;
+import net.dancier.dancer.chat.dto.CreatedChatDto;
+import net.dancier.dancer.chat.dto.MessageDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
-import org.springframework.boot.actuate.autoconfigure.metrics.MetricsProperties;
-import org.springframework.http.ResponseEntity;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
@@ -16,7 +17,7 @@
import reactor.netty.transport.logging.AdvancedByteBufFormat;
import reactor.util.retry.Retry;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import java.time.Duration;
import java.util.Optional;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/chat/dto/ChatDto.java b/src/main/java/net/dancier/dancer/chat/dto/ChatDto.java
index 7073ebb4..d82bd5b0 100644
--- a/src/main/java/net/dancier/dancer/chat/dto/ChatDto.java
+++ b/src/main/java/net/dancier/dancer/chat/dto/ChatDto.java
@@ -3,8 +3,6 @@
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;
@@ -13,9 +11,9 @@
public class ChatDto {
private UUID chatId;
private List participantIds;
-//2023-12-15T13:00:23.897543763Z
-// @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
- //private OffsetDateTime lastActivity;
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ private OffsetDateTime lastActivity;
private MessageDto lastMessage;
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
private OffsetDateTime createdAt;
}
diff --git a/src/main/java/net/dancier/dancer/chat/dto/ChatType.java b/src/main/java/net/dancier/dancer/chat/dto/ChatType.java
deleted file mode 100644
index a335a95a..00000000
--- a/src/main/java/net/dancier/dancer/chat/dto/ChatType.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package net.dancier.dancer.chat.dto;
-
-public enum ChatType {
- GROUP,
- DIRECT
-}
diff --git a/src/main/java/net/dancier/dancer/chat/dto/ChatsDto.java b/src/main/java/net/dancier/dancer/chat/dto/ChatsDto.java
deleted file mode 100644
index 329828f1..00000000
--- a/src/main/java/net/dancier/dancer/chat/dto/ChatsDto.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.dancier.dancer.chat.dto;
-
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-public class ChatsDto {
- private List chats;
-}
diff --git a/src/main/java/net/dancier/dancer/chat/dto/CreateChatDto.java b/src/main/java/net/dancier/dancer/chat/dto/CreateChatDto.java
index e24f3fae..5c34385e 100644
--- a/src/main/java/net/dancier/dancer/chat/dto/CreateChatDto.java
+++ b/src/main/java/net/dancier/dancer/chat/dto/CreateChatDto.java
@@ -2,8 +2,6 @@
import lombok.Data;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
import java.util.List;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/chat/dto/MessageDto.java b/src/main/java/net/dancier/dancer/chat/dto/MessageDto.java
index ee85002c..bb2e12c8 100644
--- a/src/main/java/net/dancier/dancer/chat/dto/MessageDto.java
+++ b/src/main/java/net/dancier/dancer/chat/dto/MessageDto.java
@@ -13,7 +13,7 @@ public class MessageDto {
private UUID authorId;
private String text;
private List readByParticipants;
-// @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
-// private OffsetDateTime createdAt;
+ @JsonFormat(shape = JsonFormat.Shape.STRING)
+ private OffsetDateTime createdAt;
}
diff --git a/src/main/java/net/dancier/dancer/contact/ContactController.java b/src/main/java/net/dancier/dancer/contact/ContactController.java
index 7fe3a241..5d8f1c5d 100644
--- a/src/main/java/net/dancier/dancer/contact/ContactController.java
+++ b/src/main/java/net/dancier/dancer/contact/ContactController.java
@@ -1,6 +1,8 @@
package net.dancier.dancer.contact;
import lombok.RequiredArgsConstructor;
+import net.dancier.dancer.security.AuthenticatedUser;
+import net.dancier.dancer.security.CurrentUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
@@ -11,6 +13,8 @@
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
+import java.util.stream.Collectors;
+
import static net.dancier.dancer.authentication.Constants.ROLE_HUMAN;
@RestController
@@ -23,10 +27,12 @@ public class ContactController {
private final ContactService contactService;
@PostMapping
- @Secured(ROLE_HUMAN)
- public ResponseEntity sentMail(@RequestBody ContactDto contactDto) {
+ @Secured({ROLE_HUMAN})
+ public ResponseEntity sentMail(@RequestBody ContactDto contactDto,
+ @CurrentUser AuthenticatedUser currentUser) {
+
log.info("Sending {} to {}.", contactDto.getMessage(), contactDto.getSender());
- contactService.send(contactDto);
+ contactService.send(contactDto, currentUser);
return ResponseEntity.status(HttpStatus.CREATED).build();
}
diff --git a/src/main/java/net/dancier/dancer/contact/ContactDto.java b/src/main/java/net/dancier/dancer/contact/ContactDto.java
index bf4202a4..12c69fbd 100644
--- a/src/main/java/net/dancier/dancer/contact/ContactDto.java
+++ b/src/main/java/net/dancier/dancer/contact/ContactDto.java
@@ -2,14 +2,13 @@
import lombok.Data;
-import javax.validation.constraints.Email;
-import javax.validation.constraints.NotNull;
+import jakarta.validation.constraints.Email;
+import jakarta.validation.constraints.NotNull;
@Data
public class ContactDto {
@Email
- @NotNull
private String sender;
@NotNull
diff --git a/src/main/java/net/dancier/dancer/contact/ContactService.java b/src/main/java/net/dancier/dancer/contact/ContactService.java
index 4c555d0a..0f7a86b3 100644
--- a/src/main/java/net/dancier/dancer/contact/ContactService.java
+++ b/src/main/java/net/dancier/dancer/contact/ContactService.java
@@ -1,39 +1,54 @@
package net.dancier.dancer.contact;
import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.mail.model.DancierMailMessage;
import net.dancier.dancer.mail.service.MailCreationService;
-import net.dancier.dancer.mail.service.MailEnqueueService;
+import net.dancier.dancer.security.AuthenticatedUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
+
+import static net.dancier.dancer.authentication.Constants.ROLE_USER;
@Service
@RequiredArgsConstructor
public class ContactService {
+ private final static Logger log = LoggerFactory.getLogger(ContactService.class);
+
private final MailCreationService mailCreationService;
- private final MailEnqueueService mailEnqueueService;
- void send(ContactDto contactDto) {
- DancierMailMessage mailToSender = mailCreationService.createDancierMessageFromTemplate(
- contactDto.getSender(),
+ private final ApplicationEventPublisher applicationEventPublisher;
+
+ void send(ContactDto contactDto, AuthenticatedUser authenticatedUserOfSender) {
+ String senderMailAddress = (authenticatedUserOfSender.getAuthorities().contains(ROLE_USER))
+ ? authenticatedUserOfSender.getEmail()
+ : contactDto.getSender();
+ SimpleMailMessage mailToSender = mailCreationService.createDancierMessageFromTemplate(
+ senderMailAddress,
"dev@dancier.net",
"Vielen Dank - Team Dancier",
MailCreationService.CONTACT_FORMULAR_FEEDBACK,
Map.of());
+ applicationEventPublisher.publishEvent(mailToSender);
- mailEnqueueService.enqueueMail(mailToSender);
- DancierMailMessage mailToTeamDancier = mailCreationService.createDancierMessageFromTemplate(
+ SimpleMailMessage mailToTeamDancier = mailCreationService.createDancierMessageFromTemplate(
"dev@dancier.net",
- contactDto.getSender(),
+ senderMailAddress,
"Mail über das Kontakt formular",
MailCreationService.CONTACT_FORMULAR,
Map.of(
"sender", contactDto.getSender(),
"message", contactDto.getMessage())
);
- mailEnqueueService.enqueueMail(mailToTeamDancier);
+
+ applicationEventPublisher.publishEvent(mailToTeamDancier);
}
}
diff --git a/src/main/java/net/dancier/dancer/core/AppInstanceIdFilter.java b/src/main/java/net/dancier/dancer/core/AppInstanceIdFilter.java
index ae02331e..c6e4d3f7 100644
--- a/src/main/java/net/dancier/dancer/core/AppInstanceIdFilter.java
+++ b/src/main/java/net/dancier/dancer/core/AppInstanceIdFilter.java
@@ -4,10 +4,10 @@
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
diff --git a/src/main/java/net/dancier/dancer/core/ProfileController.java b/src/main/java/net/dancier/dancer/core/ProfileController.java
index 77bb826c..1bd8346e 100644
--- a/src/main/java/net/dancier/dancer/core/ProfileController.java
+++ b/src/main/java/net/dancier/dancer/core/ProfileController.java
@@ -8,12 +8,13 @@
import net.dancier.dancer.core.exception.UnresolvableZipCode;
import net.dancier.dancer.security.AuthenticatedUser;
import net.dancier.dancer.security.CurrentUser;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.web.bind.annotation.*;
-import javax.validation.Valid;
+import jakarta.validation.Valid;
import java.util.Map;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/core/ProfileService.java b/src/main/java/net/dancier/dancer/core/ProfileService.java
index 50036cb8..5d4465b6 100644
--- a/src/main/java/net/dancier/dancer/core/ProfileService.java
+++ b/src/main/java/net/dancier/dancer/core/ProfileService.java
@@ -17,6 +17,8 @@
import net.dancier.dancer.core.util.ModelMapper;
import net.dancier.dancer.location.ZipCode;
import net.dancier.dancer.location.ZipCodeRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -30,6 +32,8 @@
@RequiredArgsConstructor
public class ProfileService {
+ private Logger log = LoggerFactory.getLogger(ProfileService.class);
+
private final UserRepository userRepository;
private final DanceService danceService;
@@ -64,6 +68,8 @@ public void updateProfileForUserId(UUID userId, ProfileOfCurrentUserDto profileO
d.setVersion(0);
return d;
});
+ Integer oldVersion = dancer.getVersion().intValue();
+
dancer.setGender(profileOfCurrentUserDto.getGender());
dancer.setBirthDate(profileOfCurrentUserDto.getBirthDate());
dancer.setSize(profileOfCurrentUserDto.getSize());
@@ -90,17 +96,20 @@ public void updateProfileForUserId(UUID userId, ProfileOfCurrentUserDto profileO
}
handleDancerProfiles(dancer, profileOfCurrentUserDto);
dancer.setUpdatedAt(Instant.now());
- if (dancer.getVersion()!=null) {
- dancer.setVersion(dancer.getVersion() + 1);
+ dancerRepository.save(dancer);
+
+ log.info("{}/{}", dancer.getVersion(), oldVersion);
+ // this hould be unequal but it does not work then
+ if (dancer.getVersion().equals(oldVersion)) {
+ log.info("Profile-Change detected");
+ applicationEventPublisher.publishEvent(
+ ProfileUpdatedEvent
+ .builder()
+ .dancer(dancer)
+ .build());
} else {
- dancer.setVersion(0);
+ log.info("Version unchanged");
}
- dancerRepository.save(dancer);
- applicationEventPublisher.publishEvent(
- ProfileUpdatedEvent
- .builder()
- .dancer(dancer)
- .build());
}
private void checkDancerNameRules(String dancerName) {
diff --git a/src/main/java/net/dancier/dancer/core/ScheduleMessagePort.java b/src/main/java/net/dancier/dancer/core/ScheduleMessagePort.java
new file mode 100644
index 00000000..5a5c7224
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/core/ScheduleMessagePort.java
@@ -0,0 +1,14 @@
+package net.dancier.dancer.core;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import io.cloudevents.CloudEvent;
+
+import java.net.URI;
+
+public interface ScheduleMessagePort {
+ void schedule(Object object,
+ String key,
+ URI source,
+ String type);
+
+}
diff --git a/src/main/java/net/dancier/dancer/core/config/KafkaTopicConfig.java b/src/main/java/net/dancier/dancer/core/config/KafkaTopicConfig.java
deleted file mode 100644
index 4e2e3bd8..00000000
--- a/src/main/java/net/dancier/dancer/core/config/KafkaTopicConfig.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package net.dancier.dancer.core.config;
-
-import org.apache.kafka.clients.admin.AdminClientConfig;
-import org.apache.kafka.clients.admin.NewTopic;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.kafka.core.KafkaAdmin;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Configuration
-public class KafkaTopicConfig {
- private static Logger log = LoggerFactory.getLogger(KafkaTopicConfig.class);
-
- @Value(value = "${spring.kafka.bootstrap-servers}")
- private String bootstrapAddress;
-
- @Bean
- public KafkaAdmin kafkaAdmin() {
- Map configs = new HashMap<>();
- configs.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
- return new KafkaAdmin(configs);
- }
-
- @Bean
- public NewTopic profileUpdated() {
- return new NewTopic("profile-updated", 1, (short) 1);
- }
-
-}
diff --git a/src/main/java/net/dancier/dancer/core/config/ObjectMapperConfiguration.java b/src/main/java/net/dancier/dancer/core/config/ObjectMapperConfiguration.java
index c9902f86..b1193abb 100644
--- a/src/main/java/net/dancier/dancer/core/config/ObjectMapperConfiguration.java
+++ b/src/main/java/net/dancier/dancer/core/config/ObjectMapperConfiguration.java
@@ -12,11 +12,10 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
-@Configuration
+//@Configuration
public class ObjectMapperConfiguration {
- @Bean
- @Primary
+// @Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule javaTimeModule=new JavaTimeModule();
diff --git a/src/main/java/net/dancier/dancer/core/config/SecurityConfig.java b/src/main/java/net/dancier/dancer/core/config/SecurityConfig.java
deleted file mode 100644
index 4f7999fd..00000000
--- a/src/main/java/net/dancier/dancer/core/config/SecurityConfig.java
+++ /dev/null
@@ -1,73 +0,0 @@
-package net.dancier.dancer.core.config;
-
-import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.security.CustomUserDetailsServiceImpl;
-import net.dancier.dancer.security.JwtAuthenticationEntryPoint;
-import net.dancier.dancer.security.JwtAuthenticationFilter;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.BeanIds;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
-@Configuration
-@EnableWebSecurity
-@RequiredArgsConstructor
-public class SecurityConfig extends WebSecurityConfigurerAdapter {
-
- private final CustomUserDetailsServiceImpl customUserDetailsService;
-
- private final JwtAuthenticationEntryPoint unauthorizedHandler;
-
- private final JwtAuthenticationFilter jwtAuthenticationFilter;
- @Override
- public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
- authenticationManagerBuilder
- .userDetailsService(customUserDetailsService)
- .passwordEncoder(passwordEncoder());
- }
-
- @Bean(BeanIds.AUTHENTICATION_MANAGER)
- @Override
- public AuthenticationManager authenticationManagerBean() throws Exception {
- return super.authenticationManagerBean();
- }
-
- @Bean
- public PasswordEncoder passwordEncoder() {
- return new BCryptPasswordEncoder();
- }
-
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http
- .cors()
- .and()
- .csrf()
- .disable()
- .exceptionHandling()
- .authenticationEntryPoint(unauthorizedHandler)
- .and()
- .sessionManagement()
- .sessionCreationPolicy(SessionCreationPolicy.NEVER)
- .and()
- .authorizeRequests()
- .antMatchers("/authentication/**",
- "/profile/checkDancerNameAvailability/*",
- "/eventlog/**",
- "/actuator/**"
- )
- .permitAll()
- .anyRequest()
- .authenticated();
-
- http.addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/dancier/dancer/core/config/SecurityConfiguration.java b/src/main/java/net/dancier/dancer/core/config/SecurityConfiguration.java
new file mode 100644
index 00000000..c53dada2
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/core/config/SecurityConfiguration.java
@@ -0,0 +1,58 @@
+package net.dancier.dancer.core.config;
+
+
+import lombok.RequiredArgsConstructor;
+import net.dancier.dancer.security.JwtAuthenticationFilter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.AuthenticationProvider;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
+
+@Configuration
+@RequiredArgsConstructor
+public class SecurityConfiguration {
+
+ @Bean
+ AuthenticationProvider authenticationProvider(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {
+ DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
+ authenticationProvider.setUserDetailsService(userDetailsService);
+ authenticationProvider.setPasswordEncoder(passwordEncoder);
+ return authenticationProvider;
+ }
+
+ @Bean
+ public PasswordEncoder passwordEncoder() {
+ return new BCryptPasswordEncoder();
+ }
+
+ @Bean
+ SecurityFilterChain filterChain(HttpSecurity httpSecurity,
+ AuthenticationProvider authenticationProvider,
+ JwtAuthenticationFilter jwtAuthenticationFilter) throws Exception {
+ httpSecurity
+ .cors(Customizer.withDefaults())
+ .csrf(c -> c.disable())
+ .exceptionHandling(Customizer.withDefaults())
+ .authorizeHttpRequests(
+ authz -> authz
+ .requestMatchers(
+ "/authentication/**",
+ "/eventlog/**"
+
+ )
+ .permitAll()
+ .anyRequest().authenticated()
+ )
+ .authenticationProvider(authenticationProvider)
+ .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
+ return httpSecurity.build();
+ }
+
+}
diff --git a/src/main/java/net/dancier/dancer/core/controller/payload/LoginRequestDto.java b/src/main/java/net/dancier/dancer/core/controller/payload/LoginRequestDto.java
index 43ff4f76..28a9371b 100644
--- a/src/main/java/net/dancier/dancer/core/controller/payload/LoginRequestDto.java
+++ b/src/main/java/net/dancier/dancer/core/controller/payload/LoginRequestDto.java
@@ -2,7 +2,7 @@
import lombok.Data;
-import javax.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotBlank;
@Data
public class LoginRequestDto {
diff --git a/src/main/java/net/dancier/dancer/core/dto/ProfileOfCurrentUserDto.java b/src/main/java/net/dancier/dancer/core/dto/ProfileOfCurrentUserDto.java
index 79cfea6f..5e26ec54 100644
--- a/src/main/java/net/dancier/dancer/core/dto/ProfileOfCurrentUserDto.java
+++ b/src/main/java/net/dancier/dancer/core/dto/ProfileOfCurrentUserDto.java
@@ -5,7 +5,6 @@
import net.dancier.dancer.core.model.Gender;
import java.time.LocalDate;
-import java.util.Date;
import java.util.Set;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/core/events/ApplicationEventListener.java b/src/main/java/net/dancier/dancer/core/events/ApplicationEventListener.java
new file mode 100644
index 00000000..a485d9e8
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/core/events/ApplicationEventListener.java
@@ -0,0 +1,42 @@
+package net.dancier.dancer.core.events;
+
+import lombok.RequiredArgsConstructor;
+import net.dancier.dancer.core.ScheduleMessagePort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.event.EventListener;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.stereotype.Component;
+
+import java.net.URI;
+import java.util.UUID;
+
+@Component
+@RequiredArgsConstructor
+public class ApplicationEventListener {
+
+ public static final Logger log = LoggerFactory.getLogger(ApplicationEventListener.class);
+ private static final URI SOURCE = URI.create("http://dancer.dancier.net");
+
+ private final ScheduleMessagePort scheduleMessagePort;
+
+ @EventListener
+ public void handle(SimpleMailMessage dancierMailMessage) {
+ scheduleMessagePort.schedule(
+ dancierMailMessage,
+ UUID.randomUUID().toString(),
+ SOURCE,
+ "email-sending-requested"
+ );
+ }
+
+ @EventListener
+ public void handle(ProfileUpdatedEvent profileUpdatedEvent) {
+ log.info("Got a Profile Change: {}", profileUpdatedEvent);
+ scheduleMessagePort.schedule(
+ profileUpdatedEvent,
+ profileUpdatedEvent.getDancer().getId().toString(),
+ SOURCE,
+ "profile-updated");
+ }
+}
diff --git a/src/main/java/net/dancier/dancer/core/events/ProfileUpdateEventListener.java b/src/main/java/net/dancier/dancer/core/events/ProfileUpdateEventListener.java
deleted file mode 100644
index 2984ce41..00000000
--- a/src/main/java/net/dancier/dancer/core/events/ProfileUpdateEventListener.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.dancier.dancer.core.events;
-
-import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.eventlog.service.EventlogService;
-import org.springframework.context.event.EventListener;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class ProfileUpdateEventListener {
-
- private final EventlogService eventlogService;
-
- private final EventCreator eventCreator;
-
- @EventListener
- public void handle(ProfileUpdatedEvent profileUpdatedEvent) {
- eventlogService.appendNew(
- eventCreator.createEventlog(
- "profile-updated",
- profileUpdatedEvent.getDancer()));
- }
-
-}
diff --git a/src/main/java/net/dancier/dancer/core/model/Address.java b/src/main/java/net/dancier/dancer/core/model/Address.java
index 7db142e4..1c56ff3e 100644
--- a/src/main/java/net/dancier/dancer/core/model/Address.java
+++ b/src/main/java/net/dancier/dancer/core/model/Address.java
@@ -1,6 +1,6 @@
package net.dancier.dancer.core.model;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.util.UUID;
@Entity
diff --git a/src/main/java/net/dancier/dancer/core/model/Dance.java b/src/main/java/net/dancier/dancer/core/model/Dance.java
index c3e74fd8..5ef83fee 100644
--- a/src/main/java/net/dancier/dancer/core/model/Dance.java
+++ b/src/main/java/net/dancier/dancer/core/model/Dance.java
@@ -1,11 +1,10 @@
package net.dancier.dancer.core.model;
import lombok.AllArgsConstructor;
-import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.util.UUID;
@Entity
diff --git a/src/main/java/net/dancier/dancer/core/model/DanceProfile.java b/src/main/java/net/dancier/dancer/core/model/DanceProfile.java
index bde01733..df8df8c6 100644
--- a/src/main/java/net/dancier/dancer/core/model/DanceProfile.java
+++ b/src/main/java/net/dancier/dancer/core/model/DanceProfile.java
@@ -3,7 +3,7 @@
import lombok.Data;
import org.hibernate.annotations.Cascade;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.util.UUID;
@Data
diff --git a/src/main/java/net/dancier/dancer/core/model/Dancer.java b/src/main/java/net/dancier/dancer/core/model/Dancer.java
index 0e63a121..4a6b3627 100644
--- a/src/main/java/net/dancier/dancer/core/model/Dancer.java
+++ b/src/main/java/net/dancier/dancer/core/model/Dancer.java
@@ -1,12 +1,11 @@
package net.dancier.dancer.core.model;
+import jakarta.persistence.*;
import lombok.Data;
import org.hibernate.annotations.Cascade;
-import javax.persistence.*;
import java.time.Instant;
import java.time.LocalDate;
-import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@@ -20,6 +19,9 @@ public class Dancer implements Recommendable{
@GeneratedValue(strategy = GenerationType.AUTO)
private UUID id;
+ @Version
+ private Integer version;
+
private UUID userId;
private String dancerName;
@@ -62,6 +64,5 @@ public class Dancer implements Recommendable{
private Instant updatedAt;
- private Integer version;
}
diff --git a/src/main/java/net/dancier/dancer/eventlog/controller/EventlogController.java b/src/main/java/net/dancier/dancer/eventlog/controller/EventlogController.java
index c75353f3..5d0b802c 100644
--- a/src/main/java/net/dancier/dancer/eventlog/controller/EventlogController.java
+++ b/src/main/java/net/dancier/dancer/eventlog/controller/EventlogController.java
@@ -25,16 +25,20 @@
public class EventlogController {
private static Logger log = LoggerFactory.getLogger(EventlogController.class);
+
private final EventlogService eventlogService;
+
@PostMapping
public ResponseEntity publish(@RequestBody NewEventlogDto newEventlogDto) {
Eventlog eventlog = EventlogMapper.toEventlog(newEventlogDto);
setRolesAndUser(eventlog);
eventlogService.appendNew(eventlog);
+
log.info("Appended " + eventlog + " to the eventlog.");
return ResponseEntity.ok().build();
}
+
private void setRolesAndUser(Eventlog eventlog) {
switch (SecurityContextHolder.getContext().getAuthentication().getPrincipal()) {
case AuthenticatedUser authenticatedUser -> {
@@ -47,7 +51,7 @@ private void setRolesAndUser(Eventlog eventlog) {
.collect(Collectors.toSet())
);
}
- case default -> {
+ default -> {
eventlog.setUserId(null);
eventlog.setRoles(Set.of("ROLE_ANONYMOUS"));
}
diff --git a/src/main/java/net/dancier/dancer/eventlog/service/EventlogS3ServiceImpl.java b/src/main/java/net/dancier/dancer/eventlog/service/EventlogS3ServiceImpl.java
index 40517aa2..ec2062b0 100644
--- a/src/main/java/net/dancier/dancer/eventlog/service/EventlogS3ServiceImpl.java
+++ b/src/main/java/net/dancier/dancer/eventlog/service/EventlogS3ServiceImpl.java
@@ -18,7 +18,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
diff --git a/src/main/java/net/dancier/dancer/eventlog/service/EventlogService.java b/src/main/java/net/dancier/dancer/eventlog/service/EventlogService.java
index 84f96486..8b855d35 100644
--- a/src/main/java/net/dancier/dancer/eventlog/service/EventlogService.java
+++ b/src/main/java/net/dancier/dancer/eventlog/service/EventlogService.java
@@ -1,22 +1,53 @@
package net.dancier.dancer.eventlog.service;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
import lombok.RequiredArgsConstructor;
+import net.dancier.dancer.core.ScheduleMessagePort;
import net.dancier.dancer.core.exception.ApplicationException;
+import net.dancier.dancer.core.exception.BusinessException;
import net.dancier.dancer.eventlog.model.Eventlog;
import net.dancier.dancer.eventlog.repository.EventlogDAO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
+import java.net.URI;
import java.sql.SQLException;
import java.time.Instant;
+import java.util.Set;
import java.util.UUID;
+import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class EventlogService {
+ private final Logger log = LoggerFactory.getLogger(EventlogService.class);
+
private final EventlogDAO eventlogDAO;
+ private final ScheduleMessagePort scheduleMessagePort;
+
+ public static final URI FRONTEND_SOURCE = URI.create("http://dancier.net");
+ private final static Set AT_LEAST_HUMAN = Set.of("ROLE_HUMAN", "ROLE_USER", "ROLE_ADMIN");
+ private final static Set NO_SPECIAL_ROLE_NEEDED = Set.of("ROLE_ANONYMOUS");
+ private final static Set allowedEvents = Set.of(
+ EventlogConfig.of("app_instance_id_created", NO_SPECIAL_ROLE_NEEDED),
+ EventlogConfig.of("navigated_to_page", NO_SPECIAL_ROLE_NEEDED),
+ EventlogConfig.of("human_session_created", AT_LEAST_HUMAN),
+ EventlogConfig.of("contact_message_sent", AT_LEAST_HUMAN),
+
+ EventlogConfig.of("app-instance-id-created", NO_SPECIAL_ROLE_NEEDED),
+ EventlogConfig.of("navigated-to-page", NO_SPECIAL_ROLE_NEEDED),
+ EventlogConfig.of("human-session-created", AT_LEAST_HUMAN),
+ EventlogConfig.of("contact-message-sent", AT_LEAST_HUMAN)
+ );
+
public void appendNew(Eventlog eventlog) {
+ validateTopic(eventlog);
+ authorize(eventlog);
try {
eventlog.setId(UUID.randomUUID());
eventlog.setCreated(Instant.now());
@@ -24,6 +55,47 @@ public void appendNew(Eventlog eventlog) {
} catch (SQLException sqlException) {
throw new ApplicationException("Unable to create new Eventlog-Entry.", sqlException);
}
+ log.info("Now scheduling..." + eventlog);
+ scheduleMessagePort.schedule(
+ eventlog,
+ eventlog.getId().toString(),
+ FRONTEND_SOURCE,
+ eventlog.getTopic().replaceAll("_", "-")); // as long halbe kanne is still sending old event format
+ }
+
+ private void validateTopic(Eventlog eventlog) {
+ String topic = eventlog.getTopic();
+ log.info("Validating Topic: {}", eventlog.getTopic());
+ if (!allowedEvents.stream()
+ .map(EventlogConfig::getName)
+ .collect(Collectors.toSet())
+ .contains(topic)) {
+ throw new BusinessException("this eventlog topic is not allowed at all: " + topic);
+ }
+
+ }
+ private void authorize(Eventlog eventlog) {
+ String topic = eventlog.getTopic();
+ Set usedRoles = eventlog.getRoles();
+ Set neededRoles = allowedEvents
+ .stream()
+ .filter(eventlogConfig -> eventlogConfig.name.equals(topic))
+ .flatMap(eventlogConfig -> eventlogConfig.neededRoles.stream())
+ .collect(Collectors.toSet());
+ log.info("Authorizing eventlog request: {}", topic);
+ Boolean authorized = usedRoles.stream().anyMatch(usedRole -> neededRoles.contains(usedRole));
+ if (!authorized) {
+ throw new BusinessException("We got this roles: " + usedRoles + " but needed this:" + neededRoles);
+ }
}
+ @AllArgsConstructor(access = AccessLevel.PRIVATE)
+ @Getter
+ private static class EventlogConfig {
+ public static EventlogConfig of(String name, Set roles) {
+ return new EventlogConfig(name, roles);
+ }
+ private String name;
+ private Set neededRoles;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/net/dancier/dancer/location/ZipCode.java b/src/main/java/net/dancier/dancer/location/ZipCode.java
index 824648c5..a3b52d6d 100644
--- a/src/main/java/net/dancier/dancer/location/ZipCode.java
+++ b/src/main/java/net/dancier/dancer/location/ZipCode.java
@@ -2,7 +2,7 @@
import lombok.Data;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.util.UUID;
@Data
diff --git a/src/main/java/net/dancier/dancer/mail/OutgoingMailProcessor.java b/src/main/java/net/dancier/dancer/mail/OutgoingMailProcessor.java
deleted file mode 100644
index 826d67c8..00000000
--- a/src/main/java/net/dancier/dancer/mail/OutgoingMailProcessor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package net.dancier.dancer.mail;
-
-import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.mail.model.OutgoingMail;
-import net.dancier.dancer.mail.model.OutgoingMailStatus;
-import net.dancier.dancer.mail.repository.OutgoingMailRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.context.annotation.Profile;
-import org.springframework.mail.MailAuthenticationException;
-import org.springframework.mail.MailException;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-
-import java.util.Collection;
-
-@Profile("!test")
-@Component
-@RequiredArgsConstructor
-public class OutgoingMailProcessor {
-
- private final Logger log = LoggerFactory.getLogger(OutgoingMailProcessor.class);
-
- private final OutgoingMailRepository outgoingMailRepository;
-
- private final JavaMailSender javaMailSender;
-
- @Scheduled(fixedRate = 10000)
- public void process() {
- log.debug("Processing outgoing mails...");
- Collection outgoingMailList = outgoingMailRepository.lockAndList();
- log.debug("Got this: " + outgoingMailList);
- for(OutgoingMail outgoingMail: outgoingMailList) {
- processOneMail(outgoingMail);
- }
- }
-
- private void processOneMail(OutgoingMail outgoingMail) {
- log.debug("About to send this mail...");
- outgoingMail.setRetry(outgoingMail.getRetry() + 1);
- try {
- this.javaMailSender.send(outgoingMail.getMail());
- outgoingMail.setStatus(OutgoingMailStatus.OK);
- } catch (MailAuthenticationException mailAuthenticationException) {
- outgoingMail.setStatus(OutgoingMailStatus.TEMPORARY_FAILED);
- log.error("Problem with password." + mailAuthenticationException);
- } catch (MailException mailException) {
- outgoingMail.setStatus(OutgoingMailStatus.FINALLY_FAILED);
- log.error("Some: " + mailException);
- }
- outgoingMailRepository.save(outgoingMail);
- }
-}
diff --git a/src/main/java/net/dancier/dancer/mail/configuration/AllForOneMailSender.java b/src/main/java/net/dancier/dancer/mail/configuration/AllForOneMailSender.java
deleted file mode 100644
index c358cbd4..00000000
--- a/src/main/java/net/dancier/dancer/mail/configuration/AllForOneMailSender.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package net.dancier.dancer.mail.configuration;
-
-import org.hibernate.cfg.NotYetImplementedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.mail.MailException;
-import org.springframework.mail.SimpleMailMessage;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.mail.javamail.MimeMessagePreparator;
-
-import javax.mail.internet.MimeMessage;
-import java.io.InputStream;
-import java.util.Properties;
-
-public class AllForOneMailSender implements JavaMailSender {
-
- private static final Logger log = LoggerFactory.getLogger(AllForOneMailSender.class);
-
- private final JavaMailSenderImpl springJavaMailSenderImpl;
-
- private final String allForOneAddress;
-
- public AllForOneMailSender(String hostname, Integer port, String user, String pass, String allForOneAddress) {
- JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
- javaMailSender.setHost(hostname);
- javaMailSender.setPort(Integer.valueOf(port));
-
- javaMailSender.setUsername(user);
- javaMailSender.setPassword(pass);
-
- Properties props = javaMailSender.getJavaMailProperties();
- props.put("mail.smtp.ssl.enable", "true");
- props.put("mail.debug", "true");
- this.allForOneAddress = allForOneAddress;
- this.springJavaMailSenderImpl = javaMailSender;
- }
-
- @Override
- public void send(SimpleMailMessage simpleMessage) throws MailException {
- simpleMessage.setBcc();
- simpleMessage.setCc();
- simpleMessage.setFrom("dev@dancier.net");
- simpleMessage.setReplyTo("dev@dancier.net");
- log.debug("Sending mail: " + simpleMessage);
- this.springJavaMailSenderImpl.send(simpleMessage);
- }
-
- @Override
- public MimeMessage createMimeMessage() {
- throw new NotYetImplementedException();
- }
-
- @Override
- public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessage mimeMessage) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessage... mimeMessages) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(SimpleMailMessage... simpleMessages) throws MailException {
- throw new NotYetImplementedException();
- }
-}
diff --git a/src/main/java/net/dancier/dancer/mail/configuration/DumpingMailSender.java b/src/main/java/net/dancier/dancer/mail/configuration/DumpingMailSender.java
deleted file mode 100644
index 83bfc105..00000000
--- a/src/main/java/net/dancier/dancer/mail/configuration/DumpingMailSender.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package net.dancier.dancer.mail.configuration;
-
-import org.hibernate.cfg.NotYetImplementedException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.mail.MailException;
-import org.springframework.mail.SimpleMailMessage;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-import org.springframework.mail.javamail.MimeMessagePreparator;
-
-import javax.mail.internet.MimeMessage;
-import java.io.InputStream;
-import java.util.Properties;
-
-public class DumpingMailSender implements JavaMailSender {
-
- private static final Logger log = LoggerFactory.getLogger(DumpingMailSender.class);
-
- @Override
- public MimeMessage createMimeMessage() {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(SimpleMailMessage simpleMessage) throws MailException {
- log.debug("Sending Mail: " + simpleMessage);
- }
-
- @Override
- public MimeMessage createMimeMessage(InputStream contentStream) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessage mimeMessage) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessage... mimeMessages) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessagePreparator mimeMessagePreparator) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(MimeMessagePreparator... mimeMessagePreparators) throws MailException {
- throw new NotYetImplementedException();
- }
-
- @Override
- public void send(SimpleMailMessage... simpleMessages) throws MailException {
- throw new NotYetImplementedException();
- }
-}
diff --git a/src/main/java/net/dancier/dancer/mail/configuration/MailSenderConfiguration.java b/src/main/java/net/dancier/dancer/mail/configuration/MailSenderConfiguration.java
deleted file mode 100644
index fa15b71d..00000000
--- a/src/main/java/net/dancier/dancer/mail/configuration/MailSenderConfiguration.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package net.dancier.dancer.mail.configuration;
-
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Profile;
-import org.springframework.mail.javamail.JavaMailSender;
-import org.springframework.mail.javamail.JavaMailSenderImpl;
-
-import java.util.Properties;
-
-@Configuration
-public class MailSenderConfiguration {
-
- @Bean("javaMailSender")
- @Profile("prod")
- public JavaMailSender getSpringJavaMailSender(
- @Value("${app.mail.host}") String hostname,
- @Value("${app.mail.port}") String port,
- @Value("${app.mail.user}") String user,
- @Value("${app.mail.pass}") String pass
- ) {
- JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
- javaMailSender.setHost(hostname);
- javaMailSender.setPort(Integer.valueOf(port));
-
- javaMailSender.setUsername(user);
- javaMailSender.setPassword(pass);
-
- Properties props = javaMailSender.getJavaMailProperties();
- props.put("mail.smtp.ssl.enable", "true");
- props.put("mail.debug", "true");
-
- return javaMailSender;
- }
-
- @Bean("javaMailSender")
- @Profile("staging")
- public JavaMailSender getAllForOneJavaMailSender(
- @Value("${app.mail.host}") String hostname,
- @Value("${app.mail.port}") String port,
- @Value("${app.mail.user}") String user,
- @Value("${app.mail.pass}") String pass,
- @Value("${app.mail.allForOneAddress}") String allForOneAddress
- ) {
- JavaMailSender javaMailSender = new AllForOneMailSender(
- hostname,
- Integer.valueOf(port),
- user,
- pass,
- allForOneAddress);
- return javaMailSender;
- }
-
- @Bean("javaMailSender")
- @Profile({"dev", "it"})
- public JavaMailSender getDumpingOnlySender() {
- return new DumpingMailSender();
- }
-}
diff --git a/src/main/java/net/dancier/dancer/mail/configuration/MailTemplateConfiguration.java b/src/main/java/net/dancier/dancer/mail/configuration/MailTemplateConfiguration.java
index b5b0d13b..78b93ef1 100644
--- a/src/main/java/net/dancier/dancer/mail/configuration/MailTemplateConfiguration.java
+++ b/src/main/java/net/dancier/dancer/mail/configuration/MailTemplateConfiguration.java
@@ -3,7 +3,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.TemplateEngine;
-import org.thymeleaf.spring5.SpringTemplateEngine;
+import org.thymeleaf.spring6.SpringTemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;
@@ -26,7 +26,7 @@ private ITemplateResolver textTemplateResolver() {
final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setOrder(Integer.valueOf(1));
templateResolver.setResolvablePatterns(Collections.singleton("text/*"));
- templateResolver.setPrefix("/mail/");
+ templateResolver.setPrefix("/templates/mail/");
templateResolver.setSuffix(".txt");
templateResolver.setTemplateMode(TemplateMode.TEXT);
templateResolver.setCharacterEncoding(EMAIL_TEMPLATE_ENCODING);
diff --git a/src/main/java/net/dancier/dancer/mail/model/DancierMailMessage.java b/src/main/java/net/dancier/dancer/mail/model/DancierMailMessage.java
deleted file mode 100644
index f0dcd3da..00000000
--- a/src/main/java/net/dancier/dancer/mail/model/DancierMailMessage.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package net.dancier.dancer.mail.model;
-
-import org.springframework.mail.SimpleMailMessage;
-
-public class DancierMailMessage extends SimpleMailMessage {
-
- public void setTo(String[] in) {
- super.setTo(in);
- }
-}
diff --git a/src/main/java/net/dancier/dancer/mail/model/EntityWithUUID.java b/src/main/java/net/dancier/dancer/mail/model/EntityWithUUID.java
deleted file mode 100644
index 46ffb764..00000000
--- a/src/main/java/net/dancier/dancer/mail/model/EntityWithUUID.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package net.dancier.dancer.mail.model;
-
-import com.vladmihalcea.hibernate.type.json.JsonBinaryType;
-import org.hibernate.annotations.Type;
-import org.hibernate.annotations.TypeDef;
-import org.hibernate.annotations.TypeDefs;
-
-import javax.persistence.Id;
-import javax.persistence.MappedSuperclass;
-import java.util.UUID;
-
-@MappedSuperclass
-@TypeDefs({
- @TypeDef(name = "jsonb", typeClass = JsonBinaryType.class)
-})
-public class EntityWithUUID {
- @Id
- @Type(type = "pg-uuid")
- private UUID id;
-
- public EntityWithUUID() {
- this.id = UUID.randomUUID();
- }
-}
\ No newline at end of file
diff --git a/src/main/java/net/dancier/dancer/mail/model/OutgoingMail.java b/src/main/java/net/dancier/dancer/mail/model/OutgoingMail.java
deleted file mode 100644
index 1257e4ba..00000000
--- a/src/main/java/net/dancier/dancer/mail/model/OutgoingMail.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package net.dancier.dancer.mail.model;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.hibernate.annotations.Type;
-
-import javax.persistence.*;
-import java.io.Serializable;
-
-@Entity
-@Data
-@AllArgsConstructor
-@NoArgsConstructor
-public class OutgoingMail extends EntityWithUUID implements Serializable {
-
- @Enumerated(EnumType.STRING)
- private OutgoingMailStatus status;
- private Integer retry;
-
- @Type(type = "jsonb")
- @Column(columnDefinition = "jsonb")
- @Basic(fetch = FetchType.EAGER)
- private DancierMailMessage mail;
-}
diff --git a/src/main/java/net/dancier/dancer/mail/model/OutgoingMailStatus.java b/src/main/java/net/dancier/dancer/mail/model/OutgoingMailStatus.java
deleted file mode 100644
index e42f4cfe..00000000
--- a/src/main/java/net/dancier/dancer/mail/model/OutgoingMailStatus.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package net.dancier.dancer.mail.model;
-
-public enum OutgoingMailStatus {
- QUEUED,
- IN_PROGRESS,
- TEMPORARY_FAILED,
- FINALLY_FAILED,
- OK
-}
diff --git a/src/main/java/net/dancier/dancer/mail/repository/OutgoingMailRepository.java b/src/main/java/net/dancier/dancer/mail/repository/OutgoingMailRepository.java
deleted file mode 100644
index 3acb35d2..00000000
--- a/src/main/java/net/dancier/dancer/mail/repository/OutgoingMailRepository.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.dancier.dancer.mail.repository;
-
-import net.dancier.dancer.mail.model.OutgoingMail;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.CrudRepository;
-
-import java.util.Collection;
-import java.util.UUID;
-
-public interface OutgoingMailRepository extends CrudRepository {
- @Query(
- value = """
- UPDATE outgoing_mail
- SET status = 'IN_PROGRESS'
- WHERE id IN (
- SELECT id
- FROM outgoing_mail
- WHERE status = 'QUEUED'
- LIMIT 1
- FOR UPDATE
- )
- RETURNING *;
- """,
- nativeQuery = true
- )
- Collection lockAndList();
-}
diff --git a/src/main/java/net/dancier/dancer/mail/service/MailCreationService.java b/src/main/java/net/dancier/dancer/mail/service/MailCreationService.java
index ca84f370..119eeb90 100644
--- a/src/main/java/net/dancier/dancer/mail/service/MailCreationService.java
+++ b/src/main/java/net/dancier/dancer/mail/service/MailCreationService.java
@@ -1,7 +1,6 @@
package net.dancier.dancer.mail.service;
import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.mail.model.DancierMailMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mail.SimpleMailMessage;
@@ -32,14 +31,14 @@ public class MailCreationService {
private final TemplateEngine emailTemplateEngine;
- public DancierMailMessage createDancierMessageFromTemplate(
+ public SimpleMailMessage createDancierMessageFromTemplate(
String to,
String from,
String subject,
String bodyTemplate,
Map context) {
- final DancierMailMessage dancierMailMessage = new DancierMailMessage();
+ final SimpleMailMessage dancierMailMessage = new SimpleMailMessage();
dancierMailMessage.setFrom(from);
dancierMailMessage.setTo(to);
dancierMailMessage.setSubject(subject);
diff --git a/src/main/java/net/dancier/dancer/mail/service/MailEnqueueService.java b/src/main/java/net/dancier/dancer/mail/service/MailEnqueueService.java
deleted file mode 100644
index 8afe08a9..00000000
--- a/src/main/java/net/dancier/dancer/mail/service/MailEnqueueService.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.dancier.dancer.mail.service;
-
-import lombok.RequiredArgsConstructor;
-import net.dancier.dancer.mail.model.DancierMailMessage;
-import net.dancier.dancer.mail.repository.OutgoingMailRepository;
-import net.dancier.dancer.mail.model.OutgoingMail;
-import net.dancier.dancer.mail.model.OutgoingMailStatus;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.mail.SimpleMailMessage;
-import org.springframework.stereotype.Component;
-
-@Component
-@RequiredArgsConstructor
-public class MailEnqueueService {
-
- private static Logger log = LoggerFactory.getLogger(MailEnqueueService.class);
-
- private final OutgoingMailRepository outgoingMailRepository;
-
- public void enqueueMail(DancierMailMessage dancierMailMessage) {
- OutgoingMail outgoingMail = new OutgoingMail();
- outgoingMail.setStatus(OutgoingMailStatus.QUEUED);
- outgoingMail.setRetry(0);
- outgoingMail.setMail(dancierMailMessage);
- this.outgoingMailRepository.save(outgoingMail);
- }
-
-}
diff --git a/src/main/java/net/dancier/dancer/core/config/KafkaProducerConfiguration.java b/src/main/java/net/dancier/dancer/messaging/KafkaConfiguration.java
similarity index 75%
rename from src/main/java/net/dancier/dancer/core/config/KafkaProducerConfiguration.java
rename to src/main/java/net/dancier/dancer/messaging/KafkaConfiguration.java
index 064c9504..a1dd2c2e 100644
--- a/src/main/java/net/dancier/dancer/core/config/KafkaProducerConfiguration.java
+++ b/src/main/java/net/dancier/dancer/messaging/KafkaConfiguration.java
@@ -1,5 +1,7 @@
-package net.dancier.dancer.core.config;
+package net.dancier.dancer.messaging;
+import io.cloudevents.CloudEvent;
+import io.cloudevents.kafka.CloudEventSerializer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
@@ -15,24 +17,24 @@
import java.util.Map;
@Configuration
-public class KafkaProducerConfiguration {
+public class KafkaConfiguration {
- private static Logger log = LoggerFactory.getLogger(KafkaProducerConfiguration.class);
+ private static Logger log = LoggerFactory.getLogger(KafkaConfiguration.class);
@Value(value = "${spring.kafka.bootstrap-servers}")
private String bootstrapAddress;
@Bean
- ProducerFactory producerFactory() {
+ ProducerFactory producerFactory() {
Map configProps = new HashMap<>();
configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress);
configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
- configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
+ configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, CloudEventSerializer.class);
configProps.put(ProducerConfig.MAX_REQUEST_SIZE_CONFIG, "20971520");
return new DefaultKafkaProducerFactory<>(configProps);
}
@Bean
- public KafkaTemplate kafkaTemplate() {
+ public KafkaTemplate kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
diff --git a/src/main/java/net/dancier/dancer/messaging/OutboxJpaEntity.java b/src/main/java/net/dancier/dancer/messaging/OutboxJpaEntity.java
new file mode 100644
index 00000000..88ae7406
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/OutboxJpaEntity.java
@@ -0,0 +1,45 @@
+package net.dancier.dancer.messaging;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import jakarta.persistence.*;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.annotations.JdbcTypeCode;
+import org.hibernate.type.SqlTypes;
+
+import java.time.OffsetDateTime;
+import java.util.UUID;
+
+@Data
+@Entity
+@Table(name = "outbox")
+@NoArgsConstructor
+public class OutboxJpaEntity {
+
+ @Id
+ @GeneratedValue
+ private UUID id;
+
+ private String type;
+
+ private String source;
+
+ private String key;
+
+ @JdbcTypeCode(SqlTypes.JSON)
+ private JsonNode data;
+
+ private OffsetDateTime createdAt;
+
+ @Enumerated(EnumType.STRING)
+ private STATUS status;
+
+ public static enum STATUS {
+ NEW,
+ IN_PROGRESS,
+ TEMP_FAILED,
+ FINALLY_FAILED,
+ DONE
+ }
+
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/OutboxJpaRepository.java b/src/main/java/net/dancier/dancer/messaging/OutboxJpaRepository.java
new file mode 100644
index 00000000..e84de7c5
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/OutboxJpaRepository.java
@@ -0,0 +1,27 @@
+package net.dancier.dancer.messaging;
+
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.Collection;
+import java.util.UUID;
+
+public interface OutboxJpaRepository extends JpaRepository {
+
+ @Query(
+ value = """
+ UPDATE outbox
+ SET status = 'IN_PROGRESS'
+ WHERE id IN (
+ SELECT id
+ FROM outbox
+ WHERE status = 'NEW'
+ LIMIT 1
+ FOR UPDATE
+ )
+ RETURNING *; """,
+ nativeQuery = true
+ )
+ Collection lockAndList();
+
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/ProfileUpdatedEventDto.java b/src/main/java/net/dancier/dancer/messaging/ProfileUpdatedEventDto.java
new file mode 100644
index 00000000..6614dd87
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/ProfileUpdatedEventDto.java
@@ -0,0 +1,4 @@
+package net.dancier.dancer.messaging;
+
+public class ProfileUpdatedEventDto {
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/ScheduleMessageAdapter.java b/src/main/java/net/dancier/dancer/messaging/ScheduleMessageAdapter.java
new file mode 100644
index 00000000..31ea7673
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/ScheduleMessageAdapter.java
@@ -0,0 +1,43 @@
+package net.dancier.dancer.messaging;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import net.dancier.dancer.core.ScheduleMessagePort;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.context.ApplicationContextException;
+import org.springframework.stereotype.Component;
+
+import java.net.URI;
+import java.time.OffsetDateTime;
+
+@RequiredArgsConstructor
+@Component
+public class ScheduleMessageAdapter implements ScheduleMessagePort {
+
+ public static final Logger log = LoggerFactory.getLogger(ScheduleMessageAdapter.class);
+
+ private final OutboxJpaRepository outboxJpaRepository;
+
+ private final ObjectMapper objectMapper;
+
+ @Override
+ public void schedule(Object object,
+ String key,
+ URI source,
+ String type) {
+ log.info("sending object: " + object);
+ log.info("with key:" + key);
+
+ OutboxJpaEntity outboxJpaEntity = new OutboxJpaEntity();
+ outboxJpaEntity.setData(objectMapper.convertValue(object, JsonNode.class));
+ outboxJpaEntity.setType(type);
+ outboxJpaEntity.setSource(source.toString());
+ outboxJpaEntity.setKey(key);
+ outboxJpaEntity.setCreatedAt(OffsetDateTime.now());
+ outboxJpaEntity.setStatus(OutboxJpaEntity.STATUS.NEW);
+ outboxJpaRepository.save(outboxJpaEntity);
+ }
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/SendMessagesJob.java b/src/main/java/net/dancier/dancer/messaging/SendMessagesJob.java
new file mode 100644
index 00000000..4fdf97c7
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/SendMessagesJob.java
@@ -0,0 +1,53 @@
+package net.dancier.dancer.messaging;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import io.cloudevents.CloudEvent;
+import io.cloudevents.core.builder.CloudEventBuilder;
+import jakarta.transaction.Transactional;
+import lombok.RequiredArgsConstructor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.kafka.core.KafkaTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.net.URI;
+import java.util.Collection;
+
+@RequiredArgsConstructor
+@Component
+public class SendMessagesJob {
+
+ private final static Logger log = LoggerFactory.getLogger(SendMessagesJob.class);
+
+ private final OutboxJpaRepository outboxJpaRepository;
+
+ private final KafkaTemplate kafkaTemplate;
+
+ private final ObjectMapper objectMapper;
+
+ @Transactional
+ @Scheduled(fixedRate = 2000)
+ public void sendMessages() throws JsonProcessingException {
+ Collection itemsToSend = outboxJpaRepository.lockAndList();
+ for (OutboxJpaEntity item: itemsToSend) {
+ log.info("Sending: {}", item);
+ send(item);
+ item.setStatus(OutboxJpaEntity.STATUS.DONE);
+ }
+ kafkaTemplate.flush();
+ }
+
+ private void send(OutboxJpaEntity item) throws JsonProcessingException {
+ CloudEvent cloudEvent = CloudEventBuilder.v1()
+ .withId(item.getId().toString())
+ .withSource(URI.create(item.getSource()))
+ .withType(item.getType())
+ .withData(objectMapper.writeValueAsBytes(item.getData()))
+ .build();
+
+ kafkaTemplate.send(item.getType(), item.getKey(), cloudEvent);
+
+ }
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/TopicConfiguration.java b/src/main/java/net/dancier/dancer/messaging/TopicConfiguration.java
new file mode 100644
index 00000000..4a93ead3
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/TopicConfiguration.java
@@ -0,0 +1,29 @@
+package net.dancier.dancer.messaging;
+
+import org.apache.kafka.clients.admin.NewTopic;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.kafka.core.KafkaAdmin;
+
+@Configuration
+public class TopicConfiguration {
+ @Bean
+ public KafkaAdmin.NewTopics createTopics() {
+
+ NewTopic profileUpdated = new NewTopic("profile-updated", 1, (short) 1);
+ NewTopic appInstanceIdCreated = new NewTopic("app-instance-id-created", 1, (short) 1);
+ NewTopic navigatedToPage = new NewTopic("navigated-to-page", 1, (short) 1);
+ NewTopic humanSessionCreated = new NewTopic("human-session-created", 1, (short) 1);
+ NewTopic contactMessageSent = new NewTopic("contact-message-sent", 1, (short) 1);
+ NewTopic emailSendingRequested = new NewTopic("email-sending-requested", 1, (short) 1);
+ return new KafkaAdmin.NewTopics(
+ profileUpdated,
+ appInstanceIdCreated,
+ navigatedToPage,
+ humanSessionCreated,
+ contactMessageSent,
+ emailSendingRequested);
+ }
+
+}
diff --git a/src/main/java/net/dancier/dancer/messaging/UserCreatedEventDto.java b/src/main/java/net/dancier/dancer/messaging/UserCreatedEventDto.java
new file mode 100644
index 00000000..f7de51a3
--- /dev/null
+++ b/src/main/java/net/dancier/dancer/messaging/UserCreatedEventDto.java
@@ -0,0 +1,4 @@
+package net.dancier.dancer.messaging;
+
+public class UserCreatedEventDto {
+}
diff --git a/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java b/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java
index ba58250e..f1256c9d 100644
--- a/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java
+++ b/src/main/java/net/dancier/dancer/recommendation/RecommendationService.java
@@ -3,16 +3,12 @@
import lombok.RequiredArgsConstructor;
import net.dancier.dancer.core.DancerRepository;
import net.dancier.dancer.core.model.Dancer;
-import net.dancier.dancer.core.model.Recommendable;
-import net.dancier.dancer.recommendation.dto.RecommendationDto;
import net.dancier.dancer.recommendation.model.BaseRecommendation;
import net.dancier.dancer.recommendation.model.RecommendationWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
-import javax.persistence.criteria.CriteriaBuilder;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/recommendation/RecommendationServiceClient.java b/src/main/java/net/dancier/dancer/recommendation/RecommendationServiceClient.java
index 664f7f06..62d5ec1e 100644
--- a/src/main/java/net/dancier/dancer/recommendation/RecommendationServiceClient.java
+++ b/src/main/java/net/dancier/dancer/recommendation/RecommendationServiceClient.java
@@ -7,7 +7,7 @@
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;
-import javax.annotation.PostConstruct;
+import jakarta.annotation.PostConstruct;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/recommendation/dto/Mapper.java b/src/main/java/net/dancier/dancer/recommendation/dto/Mapper.java
index 8e87c8b7..5ab8bd01 100644
--- a/src/main/java/net/dancier/dancer/recommendation/dto/Mapper.java
+++ b/src/main/java/net/dancier/dancer/recommendation/dto/Mapper.java
@@ -45,7 +45,7 @@ public static ExposedRecommendationDto recommendationWrapper2ExposedRecommendati
dancerPayload.setScore(recommendationWrapper.getScore());
exposedRecommendationDto.setPayload(dancerPayload);
}
- case default -> {
+ default -> {
throw new IllegalStateException();
}
}
diff --git a/src/main/java/net/dancier/dancer/school/School.java b/src/main/java/net/dancier/dancer/school/School.java
index fc552b9b..f54f3cd6 100644
--- a/src/main/java/net/dancier/dancer/school/School.java
+++ b/src/main/java/net/dancier/dancer/school/School.java
@@ -5,7 +5,7 @@
import net.dancier.dancer.core.model.Dance;
import net.dancier.dancer.core.model.Recommendable;
-import javax.persistence.*;
+import jakarta.persistence.*;
import java.util.Set;
import java.util.UUID;
diff --git a/src/main/java/net/dancier/dancer/security/AuthenticatedUser.java b/src/main/java/net/dancier/dancer/security/AuthenticatedUser.java
index 00f7693b..05c75abf 100644
--- a/src/main/java/net/dancier/dancer/security/AuthenticatedUser.java
+++ b/src/main/java/net/dancier/dancer/security/AuthenticatedUser.java
@@ -57,6 +57,10 @@ public UUID getUserId() {
return userId;
}
+ public String getEmail() {
+ return this.email;
+ }
+
public boolean isEmailValidated() {
return isEmailValidated;
}
diff --git a/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java b/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java
index 2b2eb6e7..978455b9 100644
--- a/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java
+++ b/src/main/java/net/dancier/dancer/security/CustomUserDetailsServiceImpl.java
@@ -1,16 +1,14 @@
package net.dancier.dancer.security;
+import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import net.dancier.dancer.authentication.model.User;
import net.dancier.dancer.authentication.repository.UserRepository;
import net.dancier.dancer.core.DancerRepository;
import net.dancier.dancer.core.model.Dancer;
-import org.springframework.security.core.userdetails.UserDetails;
-import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
-import javax.transaction.Transactional;
import java.util.UUID;
@Service
diff --git a/src/main/java/net/dancier/dancer/security/JwtAuthenticationEntryPoint.java b/src/main/java/net/dancier/dancer/security/JwtAuthenticationEntryPoint.java
index 49e14c79..bfaf737d 100644
--- a/src/main/java/net/dancier/dancer/security/JwtAuthenticationEntryPoint.java
+++ b/src/main/java/net/dancier/dancer/security/JwtAuthenticationEntryPoint.java
@@ -6,9 +6,9 @@
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
@@ -23,4 +23,5 @@ public void commence(HttpServletRequest request,
log.error("Problem while trying to authenticate: " + authException.getMessage());
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage());
}
+
}
diff --git a/src/main/java/net/dancier/dancer/security/JwtAuthenticationFilter.java b/src/main/java/net/dancier/dancer/security/JwtAuthenticationFilter.java
index e5aeedc1..3aaaf8d2 100644
--- a/src/main/java/net/dancier/dancer/security/JwtAuthenticationFilter.java
+++ b/src/main/java/net/dancier/dancer/security/JwtAuthenticationFilter.java
@@ -14,11 +14,11 @@
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.Cookie;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 6198d8f5..d2abca0a 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -2,13 +2,13 @@ spring:
profiles:
active: dev
kafka:
- bootstrap-servers: kafka:9092
+ bootstrap-servers: localhost:9092
jpa:
show-sql: false
hibernate:
ddl-auto: validate
datasource:
- url: jdbc:postgresql://dancer-db:5432/dancer
+ url: jdbc:postgresql://localhost:5432/dancer
username: dancer
password: dancer
liquibase:
@@ -35,12 +35,6 @@ app:
cors:
allowedOrigins: http://localhost:4200 # Comma separated list of allowed origins
# differentiate between success and failure
- mail:
- host: mail.your-server.de
- port: 465
- user: user
- pass: pass
- allForOneAddress: dev@dancier.net
file:
dir: ./images-dir
captcha:
diff --git a/src/main/resources/liquibase-changeLog.xml b/src/main/resources/liquibase-changeLog.xml
index ab139570..aa27f783 100644
--- a/src/main/resources/liquibase-changeLog.xml
+++ b/src/main/resources/liquibase-changeLog.xml
@@ -543,4 +543,19 @@
ADD COLUMN version INTEGER;
+
+
+ CREATE TABLE IF NOT EXISTS outbox
+ (
+ id uuid NOT NULL,
+ type character varying(256) NOT NULL,
+ data jsonb NOT NULL,
+ created_at timestamp without time zone NOT NULL,
+ status character varying(256) NOT NULL,
+ key character varying(1024),
+ source character varying(256) NOT NULL
+ )
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/mail/text/contact-formular-feedback.txt b/src/main/resources/templates/mail/text/contact-formular-feedback.txt
similarity index 100%
rename from src/main/resources/mail/text/contact-formular-feedback.txt
rename to src/main/resources/templates/mail/text/contact-formular-feedback.txt
diff --git a/src/main/resources/mail/text/contact-formular.txt b/src/main/resources/templates/mail/text/contact-formular.txt
similarity index 100%
rename from src/main/resources/mail/text/contact-formular.txt
rename to src/main/resources/templates/mail/text/contact-formular.txt
diff --git a/src/main/resources/mail/text/new-user-already-exists-email.txt b/src/main/resources/templates/mail/text/new-user-already-exists-email.txt
similarity index 100%
rename from src/main/resources/mail/text/new-user-already-exists-email.txt
rename to src/main/resources/templates/mail/text/new-user-already-exists-email.txt
diff --git a/src/main/resources/mail/text/new-user-validate-email.txt b/src/main/resources/templates/mail/text/new-user-validate-email.txt
similarity index 100%
rename from src/main/resources/mail/text/new-user-validate-email.txt
rename to src/main/resources/templates/mail/text/new-user-validate-email.txt
diff --git a/src/main/resources/mail/text/password-change-request-email.txt b/src/main/resources/templates/mail/text/password-change-request-email.txt
similarity index 100%
rename from src/main/resources/mail/text/password-change-request-email.txt
rename to src/main/resources/templates/mail/text/password-change-request-email.txt
diff --git a/src/test/java/net/dancier/dancer/TestDatabaseHelper.java b/src/test/java/net/dancier/dancer/TestDatabaseHelper.java
index d1ec8f29..38734ca1 100644
--- a/src/test/java/net/dancier/dancer/TestDatabaseHelper.java
+++ b/src/test/java/net/dancier/dancer/TestDatabaseHelper.java
@@ -4,7 +4,7 @@
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
-import javax.persistence.EntityManager;
+import jakarta.persistence.EntityManager;
import java.util.UUID;
/**
diff --git a/src/test/java/net/dancier/dancer/authentication/AuthenticationControllerTest.java b/src/test/java/net/dancier/dancer/authentication/AuthenticationControllerTest.java
index b8a20502..b2e924f9 100644
--- a/src/test/java/net/dancier/dancer/authentication/AuthenticationControllerTest.java
+++ b/src/test/java/net/dancier/dancer/authentication/AuthenticationControllerTest.java
@@ -1,6 +1,7 @@
package net.dancier.dancer.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.servlet.http.Cookie;
import net.dancier.dancer.AbstractPostgreSQLEnabledTest;
import net.dancier.dancer.authentication.dto.RegisterRequestDto;
import net.dancier.dancer.authentication.model.User;
@@ -10,15 +11,11 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
-import org.springframework.http.HttpHeaders;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
-import javax.servlet.http.Cookie;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
import static org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
diff --git a/src/test/java/net/dancier/dancer/authentication/AuthenticationServiceTest.java b/src/test/java/net/dancier/dancer/authentication/AuthenticationServiceTest.java
index 767f7840..77e77f5a 100644
--- a/src/test/java/net/dancier/dancer/authentication/AuthenticationServiceTest.java
+++ b/src/test/java/net/dancier/dancer/authentication/AuthenticationServiceTest.java
@@ -10,7 +10,6 @@
import net.dancier.dancer.authentication.service.AuthenticationService;
import net.dancier.dancer.core.exception.NotFoundException;
import net.dancier.dancer.mail.service.MailCreationService;
-import net.dancier.dancer.mail.service.MailEnqueueService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -19,9 +18,10 @@
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.mail.SimpleMailMessage;
import org.springframework.security.crypto.password.PasswordEncoder;
-import javax.persistence.EntityNotFoundException;
+import jakarta.persistence.EntityNotFoundException;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Optional;
@@ -49,9 +49,6 @@ class AuthenticationServiceTest {
@Mock
private MailCreationService mailCreationService;
- @Mock
- private MailEnqueueService mailEnqueueService;
-
@Mock
private EmailValidationCodeRepository validationCodeRepositoryMock;
@@ -105,9 +102,11 @@ void mailIsEnqueudWhenAccountAlreadyExists() {
dummyUser().getEmail()))
.thenReturn(Optional.of(dummyUser(true)));
+ when(mailCreationService.createDancierMessageFromTemplate(any(), any(), any(), any(), any())).thenReturn(new SimpleMailMessage());
+
underTest.registerUser(dummyRegisterRequestDto(dummyUser()));
- verify(mailEnqueueService, times(1)).enqueueMail(any());
+ verify(applicationEventPublisherMock, times(1)).publishEvent(any(SimpleMailMessage.class));
}
@Test
diff --git a/src/test/java/net/dancier/dancer/authentication/EndToEndAuthenticationTest.java b/src/test/java/net/dancier/dancer/authentication/EndToEndAuthenticationTest.java
index 162e3a8d..ed73b240 100644
--- a/src/test/java/net/dancier/dancer/authentication/EndToEndAuthenticationTest.java
+++ b/src/test/java/net/dancier/dancer/authentication/EndToEndAuthenticationTest.java
@@ -1,31 +1,33 @@
package net.dancier.dancer.authentication;
import com.fasterxml.jackson.databind.ObjectMapper;
+import jakarta.servlet.http.Cookie;
import net.dancier.dancer.AbstractPostgreSQLEnabledTest;
import net.dancier.dancer.TestDatabaseHelper;
import net.dancier.dancer.authentication.dto.RegisterRequestDto;
import net.dancier.dancer.authentication.dto.SendLinkDto;
import net.dancier.dancer.authentication.model.User;
import net.dancier.dancer.core.controller.payload.LoginRequestDto;
-import net.dancier.dancer.mail.service.MailEnqueueService;
import net.dancier.dancer.security.JwtTokenProvider;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.context.ApplicationEvent;
import org.springframework.http.MediaType;
+import org.springframework.mail.SimpleMailMessage;
+import org.springframework.test.context.event.ApplicationEvents;
+import org.springframework.test.context.event.RecordApplicationEvents;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
-import javax.servlet.http.Cookie;
+import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.times;
+import static org.assertj.core.api.BDDAssertions.then;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+@RecordApplicationEvents
public class EndToEndAuthenticationTest extends AbstractPostgreSQLEnabledTest {
@Autowired
@@ -37,8 +39,8 @@ public class EndToEndAuthenticationTest extends AbstractPostgreSQLEnabledTest {
@Autowired
private JwtTokenProvider jwtTokenProvider;
- @MockBean
- private MailEnqueueService mailEnqueueService;
+ @Autowired
+ ApplicationEvents applicationEvents;
@Test
void registrationHappyPath() throws Exception {
@@ -82,8 +84,7 @@ void registrationOfAlreadyExistingAccount() throws Exception {
registerUser(dummyUser)
.andExpect(status().isCreated());
- Mockito.verify(mailEnqueueService, times(2)).enqueueMail(any());
-
+ then(applicationEvents.stream(SimpleMailMessage.class).count()).isEqualTo(2);
}
@Test
diff --git a/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java b/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java
index 1d9e38f8..8d49f02d 100644
--- a/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java
+++ b/src/test/java/net/dancier/dancer/chat/ChatControllerTest.java
@@ -179,10 +179,8 @@ void getMessagesShouldReturnMessagesIfUserIsInChat() throws Exception {
ChatDto chat = new ChatDto();
chat.setParticipantIds(List.of(dancerId, UUID.randomUUID()));
- MessagesDto messages = new MessagesDto();
MessageDto message = new MessageDto();
message.setText("Hallo");
- messages.setMessages(List.of(message));
when(chatServiceClient.getChat(chatId)).thenReturn(chat);
when(chatServiceClient.getMessages(chatId, dancerId, Optional.empty())).thenReturn(new MessageDto[]{message});
diff --git a/src/test/java/net/dancier/dancer/core/EndToEndProfileTest.java b/src/test/java/net/dancier/dancer/core/EndToEndProfileTest.java
index bf805b73..37c4e7ea 100644
--- a/src/test/java/net/dancier/dancer/core/EndToEndProfileTest.java
+++ b/src/test/java/net/dancier/dancer/core/EndToEndProfileTest.java
@@ -11,6 +11,7 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
+import org.springframework.kafka.test.context.EmbeddedKafka;
import org.springframework.security.test.context.support.WithUserDetails;
import org.springframework.test.web.servlet.ResultActions;
@@ -24,6 +25,7 @@
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+@EmbeddedKafka
public class EndToEndProfileTest extends AbstractPostgreSQLEnabledTest {
@Autowired
diff --git a/src/test/java/net/dancier/dancer/mail/EndToEndMailTest.java b/src/test/java/net/dancier/dancer/mail/MailCreationTest.java
similarity index 65%
rename from src/test/java/net/dancier/dancer/mail/EndToEndMailTest.java
rename to src/test/java/net/dancier/dancer/mail/MailCreationTest.java
index 59ff76be..f414719d 100644
--- a/src/test/java/net/dancier/dancer/mail/EndToEndMailTest.java
+++ b/src/test/java/net/dancier/dancer/mail/MailCreationTest.java
@@ -1,36 +1,34 @@
package net.dancier.dancer.mail;
import net.dancier.dancer.AbstractPostgreSQLEnabledTest;
-import net.dancier.dancer.mail.model.DancierMailMessage;
import net.dancier.dancer.mail.service.MailCreationService;
-import net.dancier.dancer.mail.service.MailEnqueueService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.SimpleMailMessage;
import org.springframework.test.context.ActiveProfiles;
-import javax.mail.MessagingException;
+import jakarta.mail.MessagingException;
import java.util.Map;
+import static org.assertj.core.api.BDDAssertions.then;
+
@ActiveProfiles({"test", "dev"})
-public class EndToEndMailTest extends AbstractPostgreSQLEnabledTest {
+public class MailCreationTest extends AbstractPostgreSQLEnabledTest {
@Autowired
MailCreationService mailCreationService;
- @Autowired
- MailEnqueueService mailEnqueueService;
-
@Test
public void checkSending() throws MessagingException {
Map context = Map.of("name", "Marc", "validationLink", "http:/");
- DancierMailMessage dancierMailMessage = mailCreationService.createDancierMessageFromTemplate(
+ SimpleMailMessage dancierMailMessage = mailCreationService.createDancierMessageFromTemplate(
"gorzala@gmx.de",
"no-reply@dancier.net",
"Bestätige Deine Email-Adresse",
MailCreationService.NEW_USER_VALIDATE_EMAIL,
context
);
- mailEnqueueService.enqueueMail(dancierMailMessage);
+ then(dancierMailMessage).isNotNull();
}
}