meldestelle/docs/90_Reports/Ping-Service_Impl_01-2026.md
Stefan Mogeritsch 84337697ce docs: update code block formatting in reports and restructure guides
Updated code block formatting in `Ping-Service_Impl_01-2026.md` for consistency by switching from `kotlin` to `text`. Refactored `README.md` to rename `02_Onboarding` to `02_Guides` for improved clarity. Adjusted UI code example in `UIUXDesigner.md` with added descriptive comments.
2026-01-23 13:39:07 +01:00

216 lines
6.9 KiB
Markdown

---
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.