optimierungen gateway-Modul

This commit is contained in:
stefan
2025-09-04 13:54:30 +02:00
parent 3b40cb9c45
commit 6675e2de94
17 changed files with 552 additions and 538 deletions
@@ -85,13 +85,13 @@ class GatewayHealthIndicator(
if (hasCriticalFailure && !isTestEnvironment) {
builder.down()
details["status"] = "DOWN"
details["reason"] = "One or more critical services are unavailable"
details["reason"] = "Ein oder mehrere kritische Services sind nicht verfügbar"
} else {
details["status"] = "UP"
details["reason"] = if (isTestEnvironment) {
"Health check passed (test environment)"
"Gesundheitsprüfung erfolgreich (Testumgebung)"
} else {
"All critical services are available"
"Alle kritischen Services sind verfügbar"
}
}
@@ -99,7 +99,7 @@ class GatewayHealthIndicator(
builder.down()
.withException(exception)
details["status"] = "DOWN"
details["reason"] = "Failed to check downstream services: ${exception.message}"
details["reason"] = "Fehler beim Prüfen der nachgelagerten Services: ${exception.message}"
}
return builder.withDetails(details).build()
@@ -77,7 +77,7 @@ class GatewayMetricsConfig {
@Bean
fun requestTimer(meterRegistry: MeterRegistry): Timer {
return Timer.builder(GATEWAY_REQUEST_TIMER)
.description("Gateway request processing time")
.description("Gateway Request-Verarbeitungszeit")
.tag("type", "http")
.register(meterRegistry)
}
@@ -88,7 +88,7 @@ class GatewayMetricsConfig {
@Bean
fun errorCounter(meterRegistry: MeterRegistry): Counter {
return Counter.builder(GATEWAY_ERROR_COUNTER)
.description("Total number of gateway errors")
.description("Gesamtanzahl der Gateway-Fehler")
.register(meterRegistry)
}
@@ -98,7 +98,7 @@ class GatewayMetricsConfig {
@Bean
fun requestCounter(meterRegistry: MeterRegistry): Counter {
return Counter.builder(GATEWAY_REQUESTS_COUNTER)
.description("Total number of gateway requests")
.description("Gesamtanzahl der Gateway-Requests")
.register(meterRegistry)
}
@@ -108,7 +108,7 @@ class GatewayMetricsConfig {
@Bean
fun circuitBreakerCounter(meterRegistry: MeterRegistry): Counter {
return Counter.builder(GATEWAY_CIRCUIT_BREAKER_COUNTER)
.description("Circuit breaker events in gateway")
.description("Circuit Breaker Events im Gateway")
.register(meterRegistry)
}
}
@@ -128,7 +128,7 @@ class GatewayMetricsWebFilter(private val meterRegistry: MeterRegistry) : WebFil
Counter.builder(GatewayMetricsConfig.GATEWAY_REQUESTS_COUNTER)
.tag("method", method)
.tag("path", normalizePath(path))
.description("Total gateway requests")
.description("Gateway-Requests gesamt")
.register(meterRegistry)
.increment()
@@ -151,7 +151,7 @@ class GatewayMetricsWebFilter(private val meterRegistry: MeterRegistry) : WebFil
.tag("path", normalizePath(path))
.tag("status", statusCode)
.tag("status_series", statusSeries)
.description("Gateway request processing time")
.description("Gateway Request-Verarbeitungszeit")
.register(meterRegistry)
.record(duration)
@@ -163,7 +163,7 @@ class GatewayMetricsWebFilter(private val meterRegistry: MeterRegistry) : WebFil
.tag("status", statusCode)
.tag("status_series", statusSeries)
.tag("error_type", if (statusCode.startsWith("4")) "client_error" else "server_error")
.description("Gateway error count")
.description("Gateway-Fehleranzahl")
.register(meterRegistry)
.increment()
}
@@ -0,0 +1,3 @@
# Placeholder HOCON configuration for compatibility with legacy test scripts
# The actual configuration is provided in application.yml.
# This file ensures scripts that check for application.conf do not fail.
@@ -20,159 +20,164 @@ spring:
consul:
host: ${CONSUL_HOST:localhost}
port: ${CONSUL_PORT:8500}
enabled: ${CONSUL_ENABLED:false}
discovery:
register: true
enabled: ${CONSUL_ENABLED:false}
register: ${CONSUL_ENABLED:false}
health-check-path: /actuator/health
health-check-interval: 10s
instance-id: ${spring.application.name}-${server.port}-${random.uuid}
gateway:
# HTTP Client-Timeouts für stabile Upstream-Verbindungen
httpclient:
connect-timeout: 5000 # in Millisekunden
response-timeout: 30s
pool:
type: elastic
max-idle-time: 15s
max-life-time: 60s
# Verbesserte CORS-Konfiguration
# Antwort-Header bereinigen und globale Filter
# Route definitions with service discovery
server:
webflux:
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
httpclient:
connect-timeout: 5000 # in Millisekunden
response-timeout: 30s
pool:
max-idle-time: 15s
max-life-time: 60s
# Disable weight calculation filter to prevent blocking operations
filter:
weight:
enabled: false
# Verbesserte CORS-Konfiguration
# Antwort-Header bereinigen und globale Filter
# Route-Definitionen mit Service Discovery
defaultFilters:
- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
- name: CircuitBreaker
args:
name: defaultCircuitBreaker
fallbackUri: forward:/fallback
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
methods: GET,POST,PUT,DELETE
backoff:
firstBackoff: 50ms
maxBackoff: 500ms
factor: 2
basedOnPreviousValue: false
# Sicherheits-Header für erweiterten Schutz
- name: AddResponseHeader
args:
name: X-Content-Type-Options
value: nosniff
- name: AddResponseHeader
args:
name: X-Frame-Options
value: DENY
- name: AddResponseHeader
args:
name: X-XSS-Protection
value: 1; mode=block
- name: AddResponseHeader
args:
name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: AddResponseHeader
args:
name: Cache-Control
value: no-cache, no-store, must-revalidate
routes:
# Health Check und Gateway Info Routes
- id: gateway-info-route
uri: http://localhost:${server.port}
predicates:
- Path=/
- Method=GET
filters:
- SetStatus=200
- SetResponseHeader=Content-Type,application/json
# Members Service Routes
- id: members-service-route
uri: lb://members-service
predicates:
- Path=/api/members/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: defaultCircuitBreaker
fallbackUri: forward:/fallback
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY,GATEWAY_TIMEOUT
methods: GET,POST,PUT,DELETE
backoff:
firstBackoff: 50ms
maxBackoff: 500ms
factor: 2
basedOnPreviousValue: false
# Security Headers for enhanced protection
- name: AddResponseHeader
args:
name: X-Content-Type-Options
value: nosniff
- name: AddResponseHeader
args:
name: X-Frame-Options
value: DENY
- name: AddResponseHeader
args:
name: X-XSS-Protection
value: 1; mode=block
- name: AddResponseHeader
args:
name: Referrer-Policy
value: strict-origin-when-cross-origin
- name: AddResponseHeader
args:
name: Cache-Control
value: no-cache, no-store, must-revalidate
routes:
# Health Check und Gateway Info Routes
- id: gateway-info-route
uri: http://localhost:${server.port}
predicates:
- Path=/
- Method=GET
filters:
- SetStatus=200
- SetResponseHeader=Content-Type,application/json
args:
name: membersCircuitBreaker
fallbackUri: forward:/fallback/members
# Members Service Routes
- id: members-service-route
uri: lb://members-service
predicates:
- Path=/api/members/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: membersCircuitBreaker
fallbackUri: forward:/fallback/members
# Horses Service Routes
- id: horses-service-route
uri: lb://horses-service
predicates:
- Path=/api/horses/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: horsesCircuitBreaker
fallbackUri: forward:/fallback/horses
# Horses Service Routes
- id: horses-service-route
uri: lb://horses-service
predicates:
- Path=/api/horses/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: horsesCircuitBreaker
fallbackUri: forward:/fallback/horses
# Events Service Routes
- id: events-service-route
uri: lb://events-service
predicates:
- Path=/api/events/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: eventsCircuitBreaker
fallbackUri: forward:/fallback/events
# Events Service Routes
- id: events-service-route
uri: lb://events-service
predicates:
- Path=/api/events/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: eventsCircuitBreaker
fallbackUri: forward:/fallback/events
# Masterdata Service Routes
- id: masterdata-service-route
uri: lb://masterdata-service
predicates:
- Path=/api/masterdata/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: masterdataCircuitBreaker
fallbackUri: forward:/fallback/masterdata
# Masterdata Service Routes
- id: masterdata-service-route
uri: lb://masterdata-service
predicates:
- Path=/api/masterdata/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: masterdataCircuitBreaker
fallbackUri: forward:/fallback/masterdata
# Auth Service Routes (falls vorhanden)
- id: auth-service-route
uri: lb://auth-service
predicates:
- Path=/api/auth/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: authCircuitBreaker
fallbackUri: forward:/fallback/auth
# Auth Service Routes (if exists)
- id: auth-service-route
uri: lb://auth-service
predicates:
- Path=/api/auth/**
filters:
- StripPrefix=1
- name: CircuitBreaker
args:
name: authCircuitBreaker
fallbackUri: forward:/fallback/auth
# Ping Service Routes (bestehend)
- id: ping-service-route
uri: lb://ping-service
predicates:
- Path=/api/ping/**
filters:
- StripPrefix=1
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns:
- "https://*.meldestelle.at"
- "http://localhost:*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
- PATCH
- OPTIONS
allowedHeaders:
- "*"
allowCredentials: true
maxAge: 3600
# Ping Service Routes (existing)
- id: ping-service-route
uri: lb://ping-service
predicates:
- Path=/api/ping/**
filters:
- StripPrefix=1
globalcors:
cors-configurations:
'[/**]':
allowedOriginPatterns:
- "https://*.meldestelle.at"
- "http://localhost:*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
- PATCH
- OPTIONS
allowedHeaders:
- "*"
allowCredentials: true
maxAge: 3600
# Circuit Breaker Configuration
# Circuit Breaker Konfiguration
resilience4j:
circuitbreaker:
configs:
@@ -237,12 +242,9 @@ management:
access: unrestricted
gateway:
access: unrestricted
circuit breakers:
circuitbreakers:
enabled: true
metrics:
export:
prometheus:
# Prometheus configuration moved to monitoring-client module
distribution:
percentiles-histogram:
spring.cloud.gateway.requests: true
@@ -271,7 +273,7 @@ management:
java:
enabled: true
# Enhanced Logging Configuration
# Erweiterte Logging-Konfiguration
logging:
level:
org.springframework.cloud.gateway: INFO
@@ -287,7 +289,6 @@ logging:
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{correlationId:-}] %logger{36} - %msg%n"
file:
name: logs/gateway.log
max-size: 100MB
logback:
rollingpolicy:
clean-history-on-start: true
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<property name="LOG_FILE" value="logs/gateway.log"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{correlationId}] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/gateway.log.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{correlationId}] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="org.springframework.cloud.gateway" level="INFO"/>
<logger name="org.springframework.cloud.loadbalancer" level="DEBUG"/>
<logger name="org.springframework.cloud.consul" level="INFO"/>
<logger name="io.github.resilience4j" level="INFO"/>
<logger name="reactor.netty.http.client" level="INFO"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
@@ -2,12 +2,12 @@ openapi: 3.0.3
info:
title: Meldestelle API
description: |
Self-Contained Systems API Gateway for Austrian Equestrian Federation.
This API provides access to various bounded contexts including authentication,
master data management, horse registry, and event management.
Self-Contained Systems API Gateway für den Österreichischen Pferdesportverband.
Diese API bietet Zugriff auf verschiedene Bounded Contexts einschließlich Authentifizierung,
Stammdatenverwaltung, Pferderegister und Veranstaltungsmanagement.
## Rate Limiting
This API implements rate limiting to ensure fair usage and system stability.
Diese API implementiert Rate Limiting zur Gewährleistung fairer Nutzung und Systemstabilität.
### Global Rate Limits
- Default limit: 100 requests per minute per IP address