Health
This commit is contained in:
parent
6d4fb2d35f
commit
45b1327345
@ -29,8 +29,10 @@ repositories {
|
||||
dependencies {
|
||||
/*Spring boot*/
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter:2.7.0")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket:2.6.3")
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||
implementation("org.springframework:spring-tx")
|
||||
|
||||
|
||||
|
||||
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package no.iktdev.mediaprocessing.converter.controller
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint
|
||||
import org.springframework.boot.actuate.health.Status
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/system")
|
||||
class ReadinessController(
|
||||
private val healthEndpoint: HealthEndpoint
|
||||
) {
|
||||
|
||||
@GetMapping("/ready")
|
||||
fun ready(): ResponseEntity<String> {
|
||||
val health = healthEndpoint.health()
|
||||
|
||||
return if (health.status == Status.UP) {
|
||||
ResponseEntity.ok("READY")
|
||||
} else {
|
||||
ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.body("NOT_READY: ${health.status}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6,12 +6,15 @@ spring:
|
||||
enabled: true
|
||||
locations: classpath:flyway
|
||||
baseline-on-migrate: true
|
||||
datasource:
|
||||
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
|
||||
driver-class-name: org.h2.Driver
|
||||
username: sa
|
||||
password:
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
logging:
|
||||
level:
|
||||
|
||||
@ -25,4 +25,9 @@ management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: mappings
|
||||
include:
|
||||
- mappings
|
||||
- health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
@ -22,12 +22,12 @@ repositories {
|
||||
}
|
||||
|
||||
|
||||
val exposedVersion = "0.61.0"
|
||||
dependencies {
|
||||
|
||||
/*Spring boot*/
|
||||
implementation("org.springframework.boot:spring-boot-starter")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-webflux")
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||
implementation("org.springframework:spring-tx")
|
||||
@ -49,11 +49,6 @@ dependencies {
|
||||
implementation(project(mapOf("path" to ":shared:ffmpeg")))
|
||||
implementation(project(mapOf("path" to ":shared:common")))
|
||||
|
||||
implementation("org.jetbrains.exposed:exposed-core:$exposedVersion")
|
||||
implementation("org.jetbrains.exposed:exposed-dao:$exposedVersion")
|
||||
implementation("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
|
||||
implementation("org.jetbrains.exposed:exposed-java-time:$exposedVersion")
|
||||
implementation ("mysql:mysql-connector-java:8.0.29")
|
||||
|
||||
|
||||
implementation("org.jetbrains.kotlin:kotlin-stdlib")
|
||||
|
||||
@ -1,16 +1,28 @@
|
||||
package no.iktdev.mediaprocessing.coordinator
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import no.iktdev.mediaprocessing.ffmpeg.dsl.AudioCodec
|
||||
import no.iktdev.mediaprocessing.ffmpeg.dsl.VideoCodec
|
||||
import no.iktdev.mediaprocessing.shared.common.silentTry
|
||||
import java.io.File
|
||||
|
||||
|
||||
data class PeferenceConfig(
|
||||
val processer: ProcesserPreference
|
||||
)
|
||||
|
||||
data class ProcesserPreference(
|
||||
val videoPreference: VideoPreference? = null,
|
||||
val audioPreference: AudioPreference? = null
|
||||
) {
|
||||
companion object {
|
||||
fun default(): ProcesserPreference {
|
||||
return ProcesserPreference(
|
||||
videoPreference = VideoPreference(VideoCodec.Hevc(), false),
|
||||
audioPreference = AudioPreference("jpn", AudioCodec.Aac())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class VideoPreference(
|
||||
val codec: VideoCodec,
|
||||
@ -25,22 +37,26 @@ data class AudioPreference(
|
||||
|
||||
object Preference {
|
||||
fun getProcesserPreference(): ProcesserPreference {
|
||||
var preference: ProcesserPreference = ProcesserPreference()
|
||||
CoordinatorEnv.preference.ifExists {
|
||||
var preference: ProcesserPreference = ProcesserPreference.default()
|
||||
CoordinatorEnv.preference.ifExists({
|
||||
val text = readText()
|
||||
try {
|
||||
val result = Gson().fromJson(text, ProcesserPreference::class.java)
|
||||
preference = result
|
||||
val result = Gson().fromJson(text, PeferenceConfig::class.java)
|
||||
preference = result.processer
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}, orElse = {
|
||||
CoordinatorEnv.preference.writeText(Gson().toJson(PeferenceConfig(preference)))
|
||||
})
|
||||
return preference
|
||||
}
|
||||
}
|
||||
|
||||
private fun File.ifExists(block: File.() -> Unit) {
|
||||
private fun File.ifExists(block: File.() -> Unit, orElse: () -> Unit = {}) {
|
||||
if (this.exists()) {
|
||||
block()
|
||||
} else {
|
||||
orElse()
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package no.iktdev.mediaprocessing.coordinator.controller
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint
|
||||
import org.springframework.boot.actuate.health.Status
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/system")
|
||||
class ReadinessController(
|
||||
private val healthEndpoint: HealthEndpoint
|
||||
) {
|
||||
|
||||
@GetMapping("/ready")
|
||||
fun ready(): ResponseEntity<String> {
|
||||
val health = healthEndpoint.health()
|
||||
|
||||
return if (health.status == Status.UP) {
|
||||
ResponseEntity.ok("READY")
|
||||
} else {
|
||||
ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.body("NOT_READY: ${health.status}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
spring.output.ansi.enabled=always
|
||||
logging.level.org.apache.kafka=INFO
|
||||
logging.level.root=INFO
|
||||
logging.level.Exposed=OFF
|
||||
logging.level.org.springframework.web.socket.config.WebSocketMessageBrokerStats = WARN
|
||||
management.endpoints.web.exposure.include=*
|
||||
management.endpoint.health.show-details=always
|
||||
management.endpoints.web.base-path=/actuator
|
||||
25
apps/coordinator/src/main/resources/application.yml
Normal file
25
apps/coordinator/src/main/resources/application.yml
Normal file
@ -0,0 +1,25 @@
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
flyway:
|
||||
enabled: true
|
||||
locations: classpath:flyway
|
||||
baseline-on-migrate: true
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
org.apache.kafka: INFO
|
||||
Exposed: OFF
|
||||
org.springframework.web.socket.config.WebSocketMessageBrokerStats: WARN
|
||||
@ -25,4 +25,9 @@ management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: mappings
|
||||
include:
|
||||
- mappings
|
||||
- health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
@ -24,9 +24,10 @@ repositories {
|
||||
dependencies {
|
||||
|
||||
/*Spring boot*/
|
||||
implementation("org.springframework.boot:spring-boot-starter")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-webflux")
|
||||
implementation("org.springframework:spring-tx")
|
||||
|
||||
// implementation("org.springframework.kafka:spring-kafka:3.0.1")
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
package no.iktdev.mediaprocessing.processer.controller
|
||||
|
||||
import org.springframework.boot.actuate.health.HealthEndpoint
|
||||
import org.springframework.boot.actuate.health.Status
|
||||
import org.springframework.http.HttpStatus
|
||||
import org.springframework.http.ResponseEntity
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/system")
|
||||
class ReadinessController(
|
||||
private val healthEndpoint: HealthEndpoint
|
||||
) {
|
||||
|
||||
@GetMapping("/ready")
|
||||
fun ready(): ResponseEntity<String> {
|
||||
val health = healthEndpoint.health()
|
||||
|
||||
return if (health.status == Status.UP) {
|
||||
ResponseEntity.ok("READY")
|
||||
} else {
|
||||
ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
|
||||
.body("NOT_READY: ${health.status}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +0,0 @@
|
||||
spring.output.ansi.enabled=always
|
||||
logging.level.org.apache.kafka=INFO
|
||||
logging.level.root=INFO
|
||||
logging.level.Exposed=OFF
|
||||
logging.level.org.springframework.web.socket.config.WebSocketMessageBrokerStats = WARN
|
||||
24
apps/processer/src/main/resources/application.yml
Normal file
24
apps/processer/src/main/resources/application.yml
Normal file
@ -0,0 +1,24 @@
|
||||
spring:
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
flyway:
|
||||
enabled: true
|
||||
locations: classpath:flyway
|
||||
baseline-on-migrate: true
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
org.apache.kafka: INFO
|
||||
Exposed: OFF
|
||||
org.springframework.web.socket.config.WebSocketMessageBrokerStats: WARN
|
||||
33
apps/processer/src/test/resources/application.yml
Normal file
33
apps/processer/src/test/resources/application.yml
Normal file
@ -0,0 +1,33 @@
|
||||
spring:
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
flyway:
|
||||
enabled: false
|
||||
locations: classpath:flyway
|
||||
autoconfigure:
|
||||
exclude:
|
||||
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
|
||||
|
||||
output:
|
||||
ansi:
|
||||
enabled: always
|
||||
|
||||
springdoc:
|
||||
swagger-ui:
|
||||
path: /open/swagger-ui
|
||||
|
||||
logging:
|
||||
level:
|
||||
org.springframework.web.socket.config.WebSocketMessageBrokerStats: WARN
|
||||
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: DEBUG
|
||||
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include:
|
||||
- mappings
|
||||
- health
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
@ -27,6 +27,11 @@ val exposedVersion = "0.61.0"
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
|
||||
|
||||
implementation("com.github.pgreze:kotlin-process:1.3.1")
|
||||
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
||||
implementation(libs.exfl)
|
||||
@ -34,9 +39,7 @@ dependencies {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
||||
implementation("com.google.code.gson:gson:2.8.9")
|
||||
implementation("org.json:json:20231013")
|
||||
implementation("org.springframework.boot:spring-boot-starter-websocket:2.6.3")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||
implementation("org.flywaydb:flyway-core")
|
||||
implementation("org.flywaydb:flyway-mysql")
|
||||
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package no.iktdev.mediaprocessing.shared.common.database
|
||||
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.springframework.boot.actuate.health.Health
|
||||
import org.springframework.boot.actuate.health.HealthIndicator
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
|
||||
import org.springframework.stereotype.Component
|
||||
import javax.sql.DataSource
|
||||
|
||||
@Component
|
||||
@ConditionalOnBean(DataSource::class)
|
||||
class ExposedHealthIndicator : HealthIndicator {
|
||||
|
||||
override fun health(): Health {
|
||||
return try {
|
||||
transaction {
|
||||
exec("SELECT 1") { rs ->
|
||||
if (rs.next()) rs.getInt(1) else null
|
||||
}
|
||||
}
|
||||
Health.up().build()
|
||||
} catch (e: Exception) {
|
||||
Health.down(e).build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
package no.iktdev.mediaprocessing.shared.common.database.queries
|
||||
|
||||
import no.iktdev.mediaprocessing.shared.common.database.tables.FilesTable
|
||||
import no.iktdev.mediaprocessing.shared.common.database.withTransaction
|
||||
import no.iktdev.mediaprocessing.shared.common.dto.FileTableItem
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
|
||||
class FilesTableQueries {
|
||||
fun getFiles(): List<FileTableItem> {
|
||||
return withTransaction {
|
||||
FilesTable.selectAll()
|
||||
.mapNotNull {
|
||||
FileTableItem(
|
||||
name = it[FilesTable.name],
|
||||
uri = it[FilesTable.uri],
|
||||
checksum = it[FilesTable.checksum],
|
||||
identifiedAt = it[FilesTable.identifiedAt],
|
||||
)
|
||||
}
|
||||
}.getOrElse { emptyList() }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package no.iktdev.mediaprocessing.shared.common.database.tables
|
||||
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.sql.Column
|
||||
import org.jetbrains.exposed.sql.javatime.datetime
|
||||
|
||||
object FilesTable: IntIdTable("FILES") {
|
||||
val name: Column<String> = varchar("NAME", 255)
|
||||
val uri: Column<String> = text("URI")
|
||||
val checksum: Column<String> = char("CHECKSUM", 64)
|
||||
val identifiedAt: Column<java.time.LocalDateTime> = datetime("IDENTIFIED_AT")
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
package no.iktdev.mediaprocessing.shared.common.dto
|
||||
|
||||
import java.time.LocalDateTime
|
||||
|
||||
data class FileTableItem(
|
||||
val name: String,
|
||||
val uri: String,
|
||||
val checksum: String,
|
||||
val identifiedAt: LocalDateTime,
|
||||
)
|
||||
Loading…
Reference in New Issue
Block a user