chore: entferne veraltete Architekturdokumente
Signed-off-by: StefanMoCoAt <stefan.mo.co@gmail.com>
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
---
|
||||
type: Report
|
||||
status: ARCHIVED
|
||||
owner: Lead Architect
|
||||
date: 2026-01-10
|
||||
tags: [backend, ping-service, task]
|
||||
---
|
||||
|
||||
# Arbeitsauftrag: Implementierung des `ping-service` (Tracer Bullet)
|
||||
|
||||
**ARCHIVED:** This is the original task description. The implementation has evolved. Please refer to
|
||||
`docs/05_Backend/Services/PingService_Reference.md`.
|
||||
|
||||
---
|
||||
|
||||
**An:** Senior Backend Developer
|
||||
**Von:** Lead Software Architect
|
||||
**Betreff:** Arbeitsauftrag: Implementierung des `ping-service` (Tracer Bullet)
|
||||
|
||||
Guten Tag,
|
||||
|
||||
deine nächste Aufgabe ist die Implementierung unseres ersten Microservices, des `ping-service`. Dieser Service ist von
|
||||
strategischer Bedeutung, da er als **"Tracer Bullet"** und **Blaupause** für alle zukünftigen fachlichen Services dient.
|
||||
|
||||
Mit dieser Implementierung validieren wir die gesamte Kette: von der Service-Registrierung bei Consul über das
|
||||
Gateway-Routing und die Security mit Keycloak bis hin zur Observability mit Zipkin.
|
||||
|
||||
Deine Expertise in Spring Boot, DDD und sauberer Architektur ist hier entscheidend, um eine qualitativ hochwertige und
|
||||
wiederverwendbare Vorlage zu schaffen.
|
||||
|
||||
## Deine Aufgaben im Detail:
|
||||
|
||||
1. Modulstruktur anlegen
|
||||
|
||||
Bitte lege die folgende Modulstruktur an. Beachte die neue, klarere Benennung des
|
||||
Implementierungsmoduls:
|
||||
|
||||
- `:contracts:ping-api`: Enthält die KMP-kompatiblen DTOs.
|
||||
- `:backend:services:ping:ping-service`: Enthält die Spring Boot Anwendung, Controller und Konfiguration.
|
||||
|
||||
Stelle sicher, dass die Module in der `settings.gradle.kts` registriert sind.
|
||||
|
||||
```text
|
||||
include(
|
||||
":platform:platform-bom",
|
||||
":platform:platform-testing",
|
||||
":contracts:ping-api",
|
||||
":backend:services:ping:ping-service",
|
||||
":backend:infrastructure:gateway",
|
||||
// ":backend:services:registry:registry-api",
|
||||
// ":backend:services:registry:registry-domain",
|
||||
```
|
||||
|
||||
2. API-Definition in `:ping-api`
|
||||
|
||||
Definiere in `ping-api/src/commonMain/kotlin` ein einfaches, serialisierbares DTO. Dieses Modul darf **keine
|
||||
JVM-spezifischen Abhängigkeiten** enthalten, um die KMP-Kompatibilität für das Frontend zu gewährleisten.
|
||||
|
||||
```text
|
||||
PingResponse.kt
|
||||
```
|
||||
|
||||
```text
|
||||
package de.meldestelle.api.ping
|
||||
|
||||
import kotlinx . serialization . Serializable
|
||||
|
||||
@Serializable
|
||||
data class PingResponse(
|
||||
val message: String,
|
||||
val principal: String? = null
|
||||
)
|
||||
```
|
||||
|
||||
3. Service-Implementierung in :ping-service
|
||||
|
||||
Implementiere die Spring Boot Anwendung.
|
||||
|
||||
- **`PingController.kt`:**
|
||||
- **`GET /api/ping`:** Ein öffentlicher Endpunkt, der eine `PingResponse("Pong", "anonymous")` zurückgibt.
|
||||
- **`GET /api/ping/secure`:** Ein durch Spring Security geschützter Endpunkt. Er soll den `preferred_username` aus dem
|
||||
`Jwt` Principal extrahieren und in der `PingResponse` zurückgeben.
|
||||
|
||||
Hier ist ein Implementierungsvorschlag für den Controller:
|
||||
|
||||
```text
|
||||
// in backend/services/ping/ping-service/src/main/kotlin/.../PingController.kt
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/ping")
|
||||
class PingController {
|
||||
|
||||
@GetMapping
|
||||
fun pingPublic(): PingResponse {
|
||||
return PingResponse(message = "Pong", principal = "anonymous")
|
||||
}
|
||||
|
||||
@GetMapping("/secure")
|
||||
fun pingSecure(principal: Jwt): PingResponse {
|
||||
val username = principal.getClaimAsString("preferred_username")
|
||||
return PingResponse(message = "Pong (Secure)", principal = username)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. **Konfiguration**
|
||||
|
||||
Erstelle die `application.yml` für den Service. Sie muss die Anwendung für unsere Infrastruktur korrekt konfigurieren:
|
||||
|
||||
- **Service Name:** ping-service
|
||||
- **Service Discovery:** Registrierung bei Consul.
|
||||
- **Security:** Konfiguration als Resource Server, der JWTs vom `issuer-uri` unseres Keycloak-Containers validiert.
|
||||
- **Observability:** Actuator-Endpunkte (`health`, `info`, `prometheus`) freigeben und Tracing aktivieren.
|
||||
|
||||
```yaml
|
||||
# in backend/services/ping/ping-service/src/main/resources/application.yml
|
||||
|
||||
server:
|
||||
port: 8081 # Eindeutiger Port für den Service
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: ping-service
|
||||
|
||||
# --- Consul Discovery ---
|
||||
cloud:
|
||||
consul:
|
||||
host: consul
|
||||
port: 8500
|
||||
discovery:
|
||||
instance-id: \${spring.application.name}:\${random.value}
|
||||
health-check-path: /actuator/health
|
||||
health-check-interval: 10s
|
||||
|
||||
# --- Security (Keycloak) ---
|
||||
security:
|
||||
oauth2:
|
||||
resourceserver:
|
||||
jwt:
|
||||
issuer-uri: http://keycloak:8080/realms/meldestelle
|
||||
|
||||
# --- Observability ---
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: "health,info,prometheus"
|
||||
tracing:
|
||||
sampling:
|
||||
probability: 1.0 # Trace every request
|
||||
|
||||
logging:
|
||||
pattern:
|
||||
level: "%5p [${spring.application.name:},%X{traceId:-},%X{spanId:-}]"
|
||||
```
|
||||
|
||||
5. **Build-Konfiguration(`build.gradle.kts`)
|
||||
|
||||
Achte auf die korrekte und saubere Definition der Abhängigkeiten.
|
||||
|
||||
- `ping-api/build.gradle.kts`
|
||||
```text
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
alias(libs.plugins.kotlin.serialization)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm() // Für die Nutzung im Backend
|
||||
js(IR) { browser() } // Für die Nutzung im Frontend
|
||||
sourceSets {
|
||||
commonMain.dependencies {
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- `ping-service/build.gradle.kts`
|
||||
```text
|
||||
plugins {
|
||||
alias(libs.plugins.spring.boot)
|
||||
alias(libs.plugins.kotlin.jvm)
|
||||
alias(libs.plugins.kotlin.spring)
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// API-Modul einbinden
|
||||
implementation(project(":contracts:ping-api"))
|
||||
|
||||
// Unsere zentrale BOM für konsistente Versionen
|
||||
implementation(platform(project(":platform:platform-bom")))
|
||||
|
||||
// Spring Boot Starter
|
||||
implementation(libs.spring.boot.starter.web)
|
||||
implementation(libs.spring.boot.starter.actuator)
|
||||
implementation(libs.spring.boot.starter.security)
|
||||
implementation(libs.spring.boot.starter.oauth2.resource.server)
|
||||
|
||||
// Spring Cloud (Consul, OpenFeign etc.)
|
||||
implementation(libs.spring.cloud.starter.consul.discovery)
|
||||
|
||||
// Test-Abhängigkeiten
|
||||
testImplementation(platform(project(":platform:platform-testing")))
|
||||
testImplementation(libs.bundles.test.spring)
|
||||
}
|
||||
```
|
||||
|
||||
## Definition of Done:
|
||||
|
||||
Der Auftrag gilt als erledigt, wenn:
|
||||
|
||||
1. Die Anwendung erfolgreich startet und sich im Consul UI als `UP` registriert.
|
||||
2. Ein `GET`-Request auf `http//localhost:8081/api/ping` (über das Gateway) den Status `200 OK` und die
|
||||
`{"message":"Pong", "principal":"anonymous"}` zurückgibt.
|
||||
3. Ein `GET`-Request auf `http//localhost:8081/api/ping/secure` ohne Token den Status `401 Unauthorized` zurückgibt.
|
||||
4. Ein `GET`-Request auf `http//localhost:8081/api/ping/secure` mit einem gültigen Keycloak-Token deb Status `200 OK`
|
||||
und eine Antwort mit dem korrekten Benutzernamen zurückgibt.
|
||||
5. Die Requests in der Zipkin UI als Trace sichtbar sind.
|
||||
|
||||
Bei Fragen zur Konfiguration oder zur Architektur stehe ich dir zur Verfügung.
|
||||
Reference in New Issue
Block a user