diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt index 8b6c9d53..6e6bcdd0 100644 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt +++ b/client/common-ui/src/commonMain/kotlin/at/mocode/client/data/service/PingResponse.kt @@ -20,7 +20,7 @@ class PingService(private val baseUrl: String = "http://localhost:8080") { } suspend fun ping(): Result = try { - val response = client.get("$baseUrl/ping-service/ping").body() + val response = client.get("$baseUrl/api/ping/ping").body() Result.success(response) } catch (e: Exception) { Result.failure(e) diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt index e17face8..b0269bdf 100644 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt +++ b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/App.kt @@ -20,7 +20,7 @@ fun App(baseUrl: String = "http://localhost:8080") { @Composable fun PingScreen(baseUrl: String) { - val pingComponent = remember { PingTestComponent() } + val pingComponent = remember { PingTestComponent(baseUrl) } var pingState by remember { mutableStateOf(pingComponent.state) } LaunchedEffect(pingComponent) { diff --git a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/components/PingTestComponent.kt b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/components/PingTestComponent.kt index 0772ae8a..17327a04 100644 --- a/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/components/PingTestComponent.kt +++ b/client/common-ui/src/commonMain/kotlin/at/mocode/client/ui/components/PingTestComponent.kt @@ -11,8 +11,8 @@ data class PingTestState( val isConnected: Boolean = false ) -class PingTestComponent { - private val pingService = PingService() +class PingTestComponent(baseUrl: String = "http://localhost:8080") { + private val pingService = PingService(baseUrl) private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) var state: PingTestState = PingTestState() diff --git a/client/web-app/src/jsMain/kotlin/at/mocode/client/web/Main.kt b/client/web-app/src/jsMain/kotlin/at/mocode/client/web/Main.kt index 5c3255a4..ac3fd723 100644 --- a/client/web-app/src/jsMain/kotlin/at/mocode/client/web/Main.kt +++ b/client/web-app/src/jsMain/kotlin/at/mocode/client/web/Main.kt @@ -15,7 +15,11 @@ fun main() { @Composable fun MeldestelleWebApp() { - val pingComponent = remember { PingTestComponent() } + // Get baseUrl from a window location or use default + val baseUrl = remember { + js("window.location.origin").toString().ifEmpty { "http://localhost:8080" } + } + val pingComponent = remember { PingTestComponent(baseUrl) } var pingState by remember { mutableStateOf(pingComponent.state) } LaunchedEffect(pingComponent) { diff --git a/docker-compose.yml b/docker-compose.yml index 200d687c..d589e017 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -209,7 +209,7 @@ services: retries: 3 start_period: 15s restart: unless-stopped - # Security: Run as non-root user + # Security: Run as a non-root user user: "65534:65534" # Resource limits for development deploy: @@ -242,7 +242,7 @@ services: retries: 3 start_period: 20s restart: unless-stopped - # Security: Run as non-root user + # Security: Run as a non-root user user: "472:472" # Resource limits for development deploy: diff --git a/infrastructure/auth/auth-client/src/main/kotlin/at/mocode/infrastructure/auth/client/JwtService.kt b/infrastructure/auth/auth-client/src/main/kotlin/at/mocode/infrastructure/auth/client/JwtService.kt index 4fbf1a4d..9900cf19 100644 --- a/infrastructure/auth/auth-client/src/main/kotlin/at/mocode/infrastructure/auth/client/JwtService.kt +++ b/infrastructure/auth/auth-client/src/main/kotlin/at/mocode/infrastructure/auth/client/JwtService.kt @@ -79,7 +79,7 @@ class JwtService( permissionStrings?.mapNotNull { try { BerechtigungE.valueOf(it) - } catch (e: Exception) { + } catch (_: Exception) { null } } ?: emptyList() diff --git a/infrastructure/event-store/redis-event-store/src/main/kotlin/at/mocode/infrastructure/eventstore/redis/JacksonEventSerializer.kt b/infrastructure/event-store/redis-event-store/src/main/kotlin/at/mocode/infrastructure/eventstore/redis/JacksonEventSerializer.kt index c3b6153b..849ad865 100644 --- a/infrastructure/event-store/redis-event-store/src/main/kotlin/at/mocode/infrastructure/eventstore/redis/JacksonEventSerializer.kt +++ b/infrastructure/event-store/redis-event-store/src/main/kotlin/at/mocode/infrastructure/eventstore/redis/JacksonEventSerializer.kt @@ -8,7 +8,6 @@ import com.fasterxml.jackson.databind.SerializationFeature import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.module.kotlin.KotlinModule import org.slf4j.LoggerFactory -import java.util.UUID import java.util.concurrent.ConcurrentHashMap /** diff --git a/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisEventStoreTest.kt b/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisEventStoreTest.kt index 1ab4d6a7..468351ef 100644 --- a/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisEventStoreTest.kt +++ b/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisEventStoreTest.kt @@ -1,10 +1,11 @@ package at.mocode.infrastructure.eventstore.redis import at.mocode.core.domain.event.BaseDomainEvent -import at.mocode.core.domain.model.* +import at.mocode.core.domain.model.AggregateId +import at.mocode.core.domain.model.EventType +import at.mocode.core.domain.model.EventVersion import at.mocode.infrastructure.eventstore.api.ConcurrencyException import at.mocode.infrastructure.eventstore.api.EventSerializer -import com.benasher44.uuid.Uuid import com.benasher44.uuid.uuid4 import kotlinx.serialization.Serializable import kotlinx.serialization.Transient diff --git a/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisIntegrationTest.kt b/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisIntegrationTest.kt index e27593bf..fb017828 100644 --- a/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisIntegrationTest.kt +++ b/infrastructure/event-store/redis-event-store/src/test/kotlin/at/mocode/infrastructure/eventstore/redis/RedisIntegrationTest.kt @@ -2,10 +2,11 @@ package at.mocode.infrastructure.eventstore.redis import at.mocode.core.domain.event.BaseDomainEvent import at.mocode.core.domain.event.DomainEvent -import at.mocode.core.domain.model.* +import at.mocode.core.domain.model.AggregateId +import at.mocode.core.domain.model.EventType +import at.mocode.core.domain.model.EventVersion import at.mocode.infrastructure.eventstore.api.EventSerializer import at.mocode.infrastructure.eventstore.api.EventStore -import com.benasher44.uuid.Uuid import com.benasher44.uuid.uuid4 import kotlinx.serialization.Serializable import kotlinx.serialization.Transient diff --git a/infrastructure/gateway/src/test/kotlin/at/mocode/infrastructure/gateway/GatewaySecurityTests.kt b/infrastructure/gateway/src/test/kotlin/at/mocode/infrastructure/gateway/GatewaySecurityTests.kt index 9e7e5b1a..6332abad 100644 --- a/infrastructure/gateway/src/test/kotlin/at/mocode/infrastructure/gateway/GatewaySecurityTests.kt +++ b/infrastructure/gateway/src/test/kotlin/at/mocode/infrastructure/gateway/GatewaySecurityTests.kt @@ -57,7 +57,7 @@ class GatewaySecurityTests { @BeforeEach fun setUpClient() { - // Ensure absolute base URL with scheme to satisfy CORS processor + // Ensure absolute base URL with a scheme to satisfy the CORS processor webTestClient = webTestClient.mutate() .baseUrl("http://localhost:$port") .build() diff --git a/temp/ping-service/Dockerfile b/temp/ping-service/Dockerfile index 84449ada..a7102d9e 100644 --- a/temp/ping-service/Dockerfile +++ b/temp/ping-service/Dockerfile @@ -1,18 +1,29 @@ # syntax=docker/dockerfile:1 # Build stage: compile the ping-service JAR inside Docker -FROM gradle:8.7-jdk17-alpine AS builder +FROM gradle:8.14-jdk21-alpine AS builder WORKDIR /workspace -# Copy the entire repository (simplest and most robust for multi-module setups) -# This allows building the ping-service even if it depends on shared build files or platforms. -COPY . . +# Enable Gradle build cache and daemon for faster builds +ENV GRADLE_OPTS="-Dorg.gradle.caching=true -Dorg.gradle.daemon=false" + +# Copy gradle files first for better layer caching +COPY gradle/ gradle/ +COPY gradlew gradlew.bat gradle.properties settings.gradle.kts ./ +COPY build.gradle.kts ./ +COPY platform/ platform/ + +# Copy only necessary source files for the ping-service and its dependencies +COPY temp/ping-service/ temp/ping-service/ + +# Download dependencies first (better caching) +RUN gradle :temp:ping-service:dependencies --no-daemon # Build only the ping-service artifact RUN gradle :temp:ping-service:bootJar --no-daemon # Runtime stage: slim JRE image to run the service -FROM eclipse-temurin:17-jre-alpine +FROM eclipse-temurin:21-jre-alpine # Set working directory WORKDIR /app @@ -22,20 +33,28 @@ RUN apk add --no-cache curl # Create a non-root user for better security RUN addgroup -S app && adduser -S app -G app -USER app # Copy the built JAR from the builder stage -COPY --from=builder /workspace/temp/ping-service/build/libs/*.jar app.jar +COPY --from=builder --chown=app:app /workspace/temp/ping-service/build/libs/*.jar app.jar + +# Switch to non-root user +USER app # Expose application port EXPOSE 8082 -# Health check against the ping endpoint -HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \ - CMD curl -fsS http://localhost:8082/ping || exit 1 +# Health check against the actuator health endpoint +HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ + CMD curl -fsS http://localhost:8082/actuator/health || exit 1 -# JVM options can be overridden at runtime via JAVA_OPTS env -ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 -XX:+UseStringDeduplication" +# Enhanced JVM options for containerized Spring Boot applications +ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 \ + -XX:+UseStringDeduplication \ + -XX:+UseG1GC \ + -XX:+UseContainerSupport \ + -XX:+OptimizeStringConcat \ + -Djava.security.egd=file:/dev/./urandom \ + -Dspring.jmx.enabled=false" # Run the application ENTRYPOINT ["sh", "-c", "exec java $JAVA_OPTS -jar app.jar"]