Skip to content

Commit 21d4bb2

Browse files
Merge branch 'feat/user-svc' into feat/concept-svc
2 parents 14158d6 + dd96a5c commit 21d4bb2

23 files changed

+997
-15
lines changed

compose.aws.yml

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ services:
3838
- "8081:8080"
3939
environment:
4040
- SPRING_PROFILES_ACTIVE=docker
41+
- SPRING_DATASOURCE_URL=jdbc:postgresql://user-svc-db:5432/eventdb
42+
- SPRING_DATASOURCE_USERNAME=postgres
43+
- SPRING_DATASOURCE_PASSWORD=postgres
44+
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
45+
- SPRING_JPA_SHOW_SQL=true
46+
- SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL=true
47+
networks:
48+
- backend-network
49+
depends_on:
50+
- user-svc-db
51+
restart: unless-stopped
52+
53+
user-svc-db:
54+
image: postgres:15
55+
ports:
56+
- "5432:5432"
57+
environment:
58+
- POSTGRES_PASSWORD=postgres
59+
- POSTGRES_USER=postgres
60+
- POSTGRES_DB=eventdb
4161
networks:
4262
- backend-network
4363
restart: unless-stopped
@@ -88,4 +108,4 @@ networks:
88108
frontend-network:
89109
driver: bridge
90110
backend-network:
91-
driver: bridge
111+
driver: bridge

docker-compose.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,29 @@ services:
3838
- "8081:8080"
3939
environment:
4040
- SPRING_PROFILES_ACTIVE=docker
41+
- SPRING_DATASOURCE_URL=jdbc:postgresql://user-svc-db:5432/eventdb
42+
- SPRING_DATASOURCE_USERNAME=postgres
43+
- SPRING_DATASOURCE_PASSWORD=postgres
44+
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
45+
- SPRING_JPA_SHOW_SQL=true
46+
- SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL=true
4147
networks:
4248
- backend-network
49+
depends_on:
50+
- user-svc-db
51+
52+
user-svc-db:
53+
image: postgres:15
54+
ports:
55+
- "5432:5432"
56+
environment:
57+
- POSTGRES_PASSWORD=postgres
58+
- POSTGRES_USER=postgres
59+
- POSTGRES_DB=eventdb
60+
networks:
61+
- backend-network
62+
#volumes:
63+
#- eventdb_data:/var/lib/postgresql/data
4364

4465
# Concept Service (Spring Boot)
4566
concept-svc:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: user-svc-db
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: user-svc-db-selector
10+
template:
11+
metadata:
12+
labels:
13+
app: user-svc-db-selector
14+
spec:
15+
containers:
16+
- name: user-svc-db
17+
image: "{{ .Values.userdb.image.repository }}:{{ .Values.userdb.image.tag }}"
18+
imagePullPolicy: {{ .Values.userdb.image.pullPolicy }}
19+
resources:
20+
limits:
21+
cpu: {{ .Values.userdb.resources.limits.cpu | quote }}
22+
memory: {{ .Values.userdb.resources.limits.memory | quote }}
23+
requests:
24+
cpu: {{ .Values.userdb.resources.requests.cpu | quote }}
25+
memory: {{ .Values.userdb.resources.requests.memory | quote }}
26+
ports:
27+
- containerPort: {{ .Values.userdb.service.targetPort }}
28+
env:
29+
{{- range .Values.userdb.env }}
30+
- name: {{ .name }}
31+
value: "{{ .value }}"
32+
{{- end }}
33+
volumeMounts:
34+
- name: user-svc-db-data
35+
mountPath: /var/lib/postgresql/data
36+
volumes:
37+
- name: user-svc-db-data
38+
emptyDir: {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: user-svc-db
5+
spec:
6+
selector:
7+
app: user-svc-db-selector
8+
ports:
9+
- port: {{ .Values.userdb.service.port }}
10+
targetPort: {{ .Values.userdb.service.targetPort }}
11+
type: {{ .Values.userdb.service.type }}

helm/ai-event-concepter/values.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,18 @@ usersvc:
4949
env:
5050
- name: SPRING_PROFILES_ACTIVE
5151
value: docker
52+
- name: SPRING_DATASOURCE_URL
53+
value: jdbc:postgresql://user-svc-db:5432/eventdb
54+
- name: SPRING_DATASOURCE_USERNAME
55+
value: postgres
56+
- name: SPRING_DATASOURCE_PASSWORD
57+
value: postgres
58+
- name: SPRING_JPA_HIBERNATE_DDL_AUTO
59+
value: update
60+
- name: SPRING_JPA_SHOW_SQL
61+
value: "true"
62+
- name: SPRING_JPA_PROPERTIES_HIBERNATE_FORMAT_SQL
63+
value: "true"
5264

5365
conceptsvc:
5466
image:
@@ -90,6 +102,30 @@ genaisvc:
90102
- name: FLASK_ENV
91103
value: production
92104

105+
userdb:
106+
image:
107+
repository: postgres
108+
tag: "15"
109+
pullPolicy: IfNotPresent
110+
service:
111+
type: ClusterIP
112+
port: 5432
113+
targetPort: 5432
114+
resources:
115+
limits:
116+
cpu: "500m"
117+
memory: "512Mi"
118+
requests:
119+
cpu: "200m"
120+
memory: "256Mi"
121+
env:
122+
- name: POSTGRES_PASSWORD
123+
value: postgres
124+
- name: POSTGRES_USER
125+
value: postgres
126+
- name: POSTGRES_DB
127+
value: eventdb
128+
93129
conceptdb:
94130
image:
95131
repository: postgres

user-svc/build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,15 @@ repositories {
1919

2020
dependencies {
2121
implementation 'org.springframework.boot:spring-boot-starter-web'
22-
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
22+
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
23+
runtimeOnly 'org.postgresql:postgresql'
2324
implementation 'io.swagger.core.v3:swagger-annotations:2.2.20'
2425
implementation 'jakarta.validation:jakarta.validation-api:3.0.2'
26+
implementation 'org.openapitools:jackson-databind-nullable:0.2.6'
27+
implementation 'org.springframework.boot:spring-boot-starter-security'
28+
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
29+
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
30+
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
2531
testImplementation 'org.springframework.boot:spring-boot-starter-test'
2632
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
2733
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package de.tum.aet.devops25.usersvc;
2+
3+
import java.io.IOException;
4+
import java.time.OffsetDateTime;
5+
6+
import org.springframework.http.MediaType;
7+
import org.springframework.security.core.AuthenticationException;
8+
import org.springframework.security.web.AuthenticationEntryPoint;
9+
import org.springframework.stereotype.Component;
10+
11+
import com.fasterxml.jackson.databind.ObjectMapper;
12+
13+
import de.tum.aet.devops25.api.generated.model.ErrorResponse;
14+
import jakarta.servlet.ServletException;
15+
import jakarta.servlet.http.HttpServletRequest;
16+
import jakarta.servlet.http.HttpServletResponse;
17+
18+
@Component
19+
public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint {
20+
21+
private final ObjectMapper objectMapper;
22+
23+
public CustomAuthenticationEntryPoint(ObjectMapper objectMapper) {
24+
this.objectMapper = objectMapper;
25+
}
26+
27+
@Override
28+
public void commence(HttpServletRequest request, HttpServletResponse response,
29+
AuthenticationException authException) throws IOException, ServletException {
30+
31+
String requestURI = request.getRequestURI();
32+
String authHeader = request.getHeader("Authorization");
33+
34+
ErrorResponse error;
35+
if (authHeader == null || authHeader.isEmpty()) {
36+
error = new ErrorResponse()
37+
.error("MISSING_TOKEN")
38+
.message("Authentication token is required")
39+
.path(requestURI)
40+
.status(401)
41+
.timestamp(OffsetDateTime.now());
42+
} else {
43+
error = new ErrorResponse()
44+
.error("INVALID_TOKEN")
45+
.message("Invalid or expired authentication token")
46+
.path(requestURI)
47+
.status(401)
48+
.timestamp(OffsetDateTime.now());
49+
}
50+
51+
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
52+
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
53+
response.getWriter().write(objectMapper.writeValueAsString(error));
54+
}
55+
}

user-svc/src/main/java/de/tum/aet/devops25/usersvc/DefaultController.java

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package de.tum.aet.devops25.usersvc;
2+
3+
import java.time.OffsetDateTime;
4+
5+
import org.springframework.http.HttpStatus;
6+
import org.springframework.http.ResponseEntity;
7+
import org.springframework.web.bind.annotation.ControllerAdvice;
8+
import org.springframework.web.bind.annotation.ExceptionHandler;
9+
import org.springframework.web.context.request.WebRequest;
10+
11+
import de.tum.aet.devops25.api.generated.model.ErrorResponse;
12+
13+
@ControllerAdvice
14+
public class GlobalExceptionHandler {
15+
16+
@ExceptionHandler(UserAlreadyExistsException.class)
17+
public ResponseEntity<ErrorResponse> handleUserAlreadyExistsException(UserAlreadyExistsException ex, WebRequest request) {
18+
ErrorResponse error = new ErrorResponse()
19+
.error("USER_ALREADY_EXISTS")
20+
.message(ex.getMessage())
21+
.path(request.getDescription(false).replace("uri=", ""))
22+
.status(409)
23+
.timestamp(OffsetDateTime.now());
24+
25+
return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
26+
}
27+
28+
@ExceptionHandler(RuntimeException.class)
29+
public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex, WebRequest request) {
30+
ErrorResponse error = new ErrorResponse()
31+
.error("RUNTIME_ERROR")
32+
.message(ex.getMessage())
33+
.path(request.getDescription(false).replace("uri=", ""))
34+
.status(500)
35+
.timestamp(OffsetDateTime.now());
36+
37+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
38+
}
39+
40+
@ExceptionHandler(Exception.class)
41+
public ResponseEntity<ErrorResponse> handleGenericException(Exception ex, WebRequest request) {
42+
ErrorResponse error = new ErrorResponse()
43+
.error("INTERNAL_SERVER_ERROR")
44+
.message("An unexpected error occurred")
45+
.path(request.getDescription(false).replace("uri=", ""))
46+
.status(500)
47+
.timestamp(OffsetDateTime.now());
48+
49+
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
50+
}
51+
52+
@ExceptionHandler(IllegalArgumentException.class)
53+
public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex, WebRequest request) {
54+
ErrorResponse error = new ErrorResponse()
55+
.error("VALIDATION_ERROR")
56+
.message(ex.getMessage())
57+
.path(request.getDescription(false).replace("uri=", ""))
58+
.status(400)
59+
.timestamp(OffsetDateTime.now());
60+
61+
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
62+
}
63+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package de.tum.aet.devops25.usersvc;
2+
3+
import org.openapitools.jackson.nullable.JsonNullableModule;
4+
import org.springframework.context.annotation.Bean;
5+
import org.springframework.context.annotation.Configuration;
6+
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.databind.SerializationFeature;
9+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
10+
11+
@Configuration
12+
public class JacksonConfig {
13+
14+
@Bean
15+
public ObjectMapper objectMapper() {
16+
ObjectMapper mapper = new ObjectMapper();
17+
mapper.registerModule(new JavaTimeModule());
18+
mapper.registerModule(new JsonNullableModule());
19+
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
20+
return mapper;
21+
}
22+
}

0 commit comments

Comments
 (0)