Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c19c211839 | ||
|
|
aace535914 | ||
|
|
59982ef762 | ||
|
|
56c6fef178 | ||
|
|
46b1b32708 | ||
|
|
519101023c | ||
|
|
82b4f51390 | ||
|
|
3256939ac7 | ||
|
|
02e4c5318d | ||
|
|
f06abd2838 | ||
|
|
f0297f2d2c | ||
|
|
ec23bd4d32 | ||
|
|
bab1892673 | ||
|
|
247fe83caa | ||
|
|
5fe6165373 | ||
|
|
64a8f17e6e | ||
|
|
5eff527c48 | ||
|
|
642713e14c | ||
|
|
ff8b205124 | ||
|
|
8c5f925e36 | ||
|
|
fe5cd41749 | ||
|
|
3a25e33f3f | ||
|
|
ec625fb7b5 | ||
|
|
c8e4474175 | ||
|
|
499c85ae49 | ||
|
|
e88d98efc1 | ||
|
|
8d545aa7fb | ||
|
|
a04094bc60 | ||
|
|
7d68612e57 | ||
|
|
64295db0e7 | ||
|
|
6dcd302ab7 | ||
|
|
e50e769e22 | ||
|
|
b7c85e2368 | ||
|
|
a60289fc49 | ||
|
|
9c4feee043 | ||
|
|
1a50b40eaf | ||
|
|
3c7464a0cf |
@@ -62,7 +62,7 @@ tasks.named("buildAll") {
|
||||
|
||||
val formatter: DateTimeFormatter = ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
|
||||
|
||||
tasks.bootJar {
|
||||
tasks.jar {
|
||||
manifest {
|
||||
attributes["Implementation-Title"] = rootProject.name
|
||||
attributes["Implementation-Version"] = archiveVersion.get()
|
||||
|
||||
@@ -38,6 +38,7 @@ spring-boot-oauth2-resource-server = { module = "org.springframework.boot:spring
|
||||
spring-boot-config = { module = "org.springframework.boot:spring-boot-configuration-processor", version.ref = "spring-boot" }
|
||||
spring-cloud = { module = "org.springframework.cloud:spring-cloud-dependencies", version.ref = "spring-cloud" }
|
||||
spring-cloud-starter = { module = "org.springframework.cloud:spring-cloud-starter" }
|
||||
spring-cloud-starter-bus-kafka = { module = "org.springframework.cloud:spring-cloud-starter-bus-kafka" }
|
||||
spring-cloud-starter-config = { module = "org.springframework.cloud:spring-cloud-starter-config" }
|
||||
spring-cloud-config-server = { module = "org.springframework.cloud:spring-cloud-config-server" }
|
||||
spring-boot-starter = { module = "org.springframework.boot:spring-boot-starter" }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST http://localhost:12000/wahlrecht/v1/calculate
|
||||
POST {{backend}}/wahlrecht/v1/calculate
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
GET {{backend}}/wahlrecht/v1/elections
|
||||
Content-Type: application/json
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dev": {
|
||||
"backend": "http://localhost:12000"
|
||||
},
|
||||
"prod" : {
|
||||
"backend": "https://api.2martens.de"
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,8 @@ jib {
|
||||
}
|
||||
}
|
||||
container {
|
||||
extraClasspath = listOf("/configmap")
|
||||
mainClass = "de.twomartens.wahlrecht.MainApplication"
|
||||
mainClass = "de.twomartens.wahlrecht.MainApplicationKt"
|
||||
jvmFlags = listOf("-XX:+UseContainerSupport",
|
||||
"-XX:MaxRAMPercentage=75.0",
|
||||
"-Dlog4j.configurationFile=/configmap/log4j2.xml")
|
||||
"-XX:MaxRAMPercentage=75.0")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
server:
|
||||
port: 12000
|
||||
@@ -10,4 +10,5 @@ dependencies {
|
||||
annotationProcessor(libs.mapstruct.processor)
|
||||
kapt(libs.mapstruct.processor)
|
||||
implementation(libs.spring.cloud.starter.config)
|
||||
implementation(libs.spring.cloud.starter.bus.kafka)
|
||||
}
|
||||
|
||||
+3
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.security.OAuthFlows
|
||||
import io.swagger.v3.oas.annotations.security.SecurityScheme
|
||||
import io.swagger.v3.oas.models.OpenAPI
|
||||
import io.swagger.v3.oas.models.info.Info
|
||||
import io.swagger.v3.oas.models.servers.Server
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
@@ -35,5 +36,7 @@ open class OpenApiConfiguration {
|
||||
.version(apiVersion)
|
||||
.description(apiDescription)
|
||||
)
|
||||
.addServersItem(Server().url("http://localhost:12000"))
|
||||
.addServersItem(Server().url("https://api.2martens.de"))
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -16,10 +16,13 @@ open class WebConfiguration(private val headerInterceptorRest: HeaderInterceptor
|
||||
override fun addCorsMappings(registry: CorsRegistry) {
|
||||
val registration = registry.addMapping("/**")
|
||||
registration.allowedMethods(
|
||||
HttpMethod.GET.name(), HttpMethod.POST.name(),
|
||||
HttpMethod.PUT.name(), HttpMethod.OPTIONS.name()
|
||||
HttpMethod.GET.name(), HttpMethod.POST.name(),
|
||||
HttpMethod.PUT.name(), HttpMethod.HEAD.name()
|
||||
)
|
||||
registration.allowCredentials(true)
|
||||
registration.allowedOrigins("http://localhost:4200")
|
||||
registration.allowedOrigins(
|
||||
"http://localhost:4200",
|
||||
"https://wahlrecht.2martens.de"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -32,14 +32,16 @@ class VersionHtmlController {
|
||||
}
|
||||
|
||||
private fun getTitle(): String {
|
||||
val title = VersionHtmlController::class.java.getPackage().implementationTitle
|
||||
val title = VersionHtmlController::class.java.`package`.implementationTitle
|
||||
?: return "application"
|
||||
return title.ifBlank {
|
||||
"application"
|
||||
}
|
||||
}
|
||||
|
||||
private fun getVersion(): String {
|
||||
val version = VersionHtmlController::class.java.getPackage().implementationVersion
|
||||
val version = VersionHtmlController::class.java.`package`.implementationVersion
|
||||
?: return "DEVELOPER"
|
||||
return version.ifBlank {
|
||||
"DEVELOPER"
|
||||
}
|
||||
|
||||
+4
-2
@@ -1,5 +1,6 @@
|
||||
package de.twomartens.wahlrecht.controller.v1
|
||||
|
||||
import de.twomartens.wahlrecht.property.ServiceProperties
|
||||
import io.swagger.v3.oas.annotations.Hidden
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
@@ -7,11 +8,12 @@ import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping(value = ["/wahlrecht/v1"])
|
||||
class HealthCheckController {
|
||||
class HealthCheckController(private val properties: ServiceProperties) {
|
||||
|
||||
|
||||
@Hidden
|
||||
@GetMapping("/healthCheck")
|
||||
fun healthCheck(message: String): String {
|
||||
return message
|
||||
return properties.greeting.format(message)
|
||||
}
|
||||
}
|
||||
+8
-5
@@ -1,6 +1,7 @@
|
||||
package de.twomartens.wahlrecht.monitoring.actuator
|
||||
|
||||
import de.twomartens.wahlrecht.interceptor.HeaderInterceptorRest
|
||||
import de.twomartens.wahlrecht.property.ServiceProperties
|
||||
import org.springframework.boot.actuate.health.Health
|
||||
import org.springframework.boot.actuate.health.HealthIndicator
|
||||
import org.springframework.boot.actuate.health.Status
|
||||
@@ -28,8 +29,10 @@ import java.time.Clock
|
||||
*/
|
||||
@Component
|
||||
class RestHealthIndicator(
|
||||
clock: Clock, interceptor: HeaderInterceptorRest,
|
||||
serverProperties: ServerProperties, private val restTemplateRestHealthIndicator: RestTemplate
|
||||
clock: Clock, interceptor: HeaderInterceptorRest,
|
||||
serverProperties: ServerProperties,
|
||||
private val restTemplateRestHealthIndicator: RestTemplate,
|
||||
private val serviceProperties: ServiceProperties
|
||||
) : AbstractHealthIndicator(clock, Preparable { interceptor.markAsHealthCheck() }), HealthIndicator {
|
||||
private val randomizer = SecureRandom()
|
||||
private val urlPrefix: String = (HTTP_PREFIX + HOST + HOST_PORT_SEPARATOR
|
||||
@@ -43,10 +46,10 @@ class RestHealthIndicator(
|
||||
val random = randomizer.nextInt(100000, 999999).toString()
|
||||
val url = "$urlPrefix{random}"
|
||||
val response = restTemplateRestHealthIndicator.getForEntity(url, String::class.java, random)
|
||||
val status = if (response.body == random) Status.UP else Status.DOWN
|
||||
val status = if (response.body == serviceProperties.greeting.format(random)) Status.UP else Status.DOWN
|
||||
return Health.status(status)
|
||||
.withDetail(DETAIL_ENDPOINT_KEY, url)
|
||||
.build()
|
||||
.withDetail(DETAIL_ENDPOINT_KEY, url)
|
||||
.build()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -2,11 +2,13 @@ package de.twomartens.wahlrecht.property
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||
import org.springframework.boot.context.properties.bind.ConstructorBinding
|
||||
import org.springframework.cloud.context.config.annotation.RefreshScope
|
||||
import java.time.ZoneId
|
||||
|
||||
@RefreshScope
|
||||
@ConfigurationProperties(prefix = "de.twomartens.wahlrecht")
|
||||
@Schema(description = "Properties, to configure this Application")
|
||||
data class ServiceProperties @ConstructorBinding constructor(val defaultTimeZone: ZoneId, val greeting: String)
|
||||
class ServiceProperties {
|
||||
lateinit var defaultTimeZone: ZoneId
|
||||
lateinit var greeting: String
|
||||
}
|
||||
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package de.twomartens.wahlrecht.service
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.apache.logging.log4j.message.StringMapMessage
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher
|
||||
import org.springframework.scheduling.annotation.Scheduled
|
||||
import org.springframework.stereotype.Service
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* automatically reloads application*.yaml. reload can also be triggered manually by doing a post
|
||||
* request on http://localhost:12001/actuator/refresh
|
||||
*/
|
||||
@Service
|
||||
class PropertyReloadService(@Qualifier("configDataContextRefresher") private val contextRefresher: ContextRefresher) {
|
||||
@Scheduled(
|
||||
fixedDelay = REFRESH_SECONDS.toLong(),
|
||||
initialDelay = REFRESH_SECONDS.toLong(),
|
||||
timeUnit = TimeUnit.SECONDS
|
||||
)
|
||||
fun refresh() {
|
||||
val properties = contextRefresher.refresh()
|
||||
if (properties.isNotEmpty()) {
|
||||
log.info(
|
||||
StringMapMessage()
|
||||
.with(PARAM_MESSAGE, "properties changed")
|
||||
.with(PARAM_PROPERTIES, properties.joinToString("\n"))
|
||||
.asString()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REFRESH_SECONDS = 60
|
||||
const val PARAM_MESSAGE = "message"
|
||||
const val PARAM_PROPERTIES = "labels.properties"
|
||||
|
||||
private val log = KotlinLogging.logger {}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +1,9 @@
|
||||
server.port: 12000
|
||||
management.server.port: 12001
|
||||
|
||||
|
||||
spring:
|
||||
config:
|
||||
import:
|
||||
- "classpath:config/wahlrecht.yaml"
|
||||
- "optional:configserver:http://localhost:8888/config"
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
spring:
|
||||
config:
|
||||
import:
|
||||
- "configserver:http://configserver:8888/config"
|
||||
kafka:
|
||||
bootstrap-servers:
|
||||
- kafka:9092
|
||||
@@ -23,8 +23,9 @@ management:
|
||||
http.server.requests: true
|
||||
|
||||
spring:
|
||||
config:
|
||||
import: "optional:configserver:http://localhost:8888/config"
|
||||
cloud:
|
||||
config:
|
||||
name: wahlrecht
|
||||
main:
|
||||
banner-mode: off
|
||||
profiles:
|
||||
@@ -40,17 +41,6 @@ spring:
|
||||
application:
|
||||
name: wahlrecht
|
||||
|
||||
|
||||
# properties for application
|
||||
de.twomartens.wahlrecht:
|
||||
defaultTimeZone: Europe/Berlin
|
||||
greeting: "Hello %s"
|
||||
statusprobe:
|
||||
scheduleDuration: 60
|
||||
maxKafkaFailureDuration: 5
|
||||
maxBlobFailureCount: 5
|
||||
maxFailurePercent: 50
|
||||
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
display-request-duration: true
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
de.twomartens.wahlrecht:
|
||||
greeting: "Moin %s, you are sth"
|
||||
@@ -0,0 +1,8 @@
|
||||
de.twomartens.wahlrecht:
|
||||
defaultTimeZone: Europe/Berlin
|
||||
greeting: "Hello %s, on millenium"
|
||||
statusprobe:
|
||||
scheduleDuration: 60
|
||||
maxKafkaFailureDuration: 5
|
||||
maxBlobFailureCount: 5
|
||||
maxFailurePercent: 50
|
||||
Reference in New Issue
Block a user