Health
This commit is contained in:
parent
6d4fb2d35f
commit
45b1327345
@ -29,8 +29,10 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
/*Spring boot*/
|
/*Spring boot*/
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
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-actuator")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-websocket:2.6.3")
|
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||||
|
implementation("org.springframework:spring-tx")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
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
|
enabled: true
|
||||||
locations: classpath:flyway
|
locations: classpath:flyway
|
||||||
baseline-on-migrate: true
|
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:
|
logging:
|
||||||
level:
|
level:
|
||||||
|
|||||||
@ -25,4 +25,9 @@ management:
|
|||||||
endpoints:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: mappings
|
include:
|
||||||
|
- mappings
|
||||||
|
- health
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
||||||
@ -22,12 +22,12 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val exposedVersion = "0.61.0"
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
/*Spring boot*/
|
/*Spring boot*/
|
||||||
implementation("org.springframework.boot:spring-boot-starter")
|
implementation("org.springframework.boot:spring-boot-starter")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
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-actuator")
|
||||||
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
implementation("org.springframework.boot:spring-boot-starter-websocket")
|
||||||
implementation("org.springframework:spring-tx")
|
implementation("org.springframework:spring-tx")
|
||||||
@ -49,11 +49,6 @@ dependencies {
|
|||||||
implementation(project(mapOf("path" to ":shared:ffmpeg")))
|
implementation(project(mapOf("path" to ":shared:ffmpeg")))
|
||||||
implementation(project(mapOf("path" to ":shared:common")))
|
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")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib")
|
||||||
|
|||||||
@ -1,16 +1,28 @@
|
|||||||
package no.iktdev.mediaprocessing.coordinator
|
package no.iktdev.mediaprocessing.coordinator
|
||||||
|
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.GsonBuilder
|
|
||||||
import no.iktdev.mediaprocessing.ffmpeg.dsl.AudioCodec
|
import no.iktdev.mediaprocessing.ffmpeg.dsl.AudioCodec
|
||||||
import no.iktdev.mediaprocessing.ffmpeg.dsl.VideoCodec
|
import no.iktdev.mediaprocessing.ffmpeg.dsl.VideoCodec
|
||||||
import no.iktdev.mediaprocessing.shared.common.silentTry
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
|
data class PeferenceConfig(
|
||||||
|
val processer: ProcesserPreference
|
||||||
|
)
|
||||||
|
|
||||||
data class ProcesserPreference(
|
data class ProcesserPreference(
|
||||||
val videoPreference: VideoPreference? = null,
|
val videoPreference: VideoPreference? = null,
|
||||||
val audioPreference: AudioPreference? = 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(
|
data class VideoPreference(
|
||||||
val codec: VideoCodec,
|
val codec: VideoCodec,
|
||||||
@ -25,22 +37,26 @@ data class AudioPreference(
|
|||||||
|
|
||||||
object Preference {
|
object Preference {
|
||||||
fun getProcesserPreference(): ProcesserPreference {
|
fun getProcesserPreference(): ProcesserPreference {
|
||||||
var preference: ProcesserPreference = ProcesserPreference()
|
var preference: ProcesserPreference = ProcesserPreference.default()
|
||||||
CoordinatorEnv.preference.ifExists {
|
CoordinatorEnv.preference.ifExists({
|
||||||
val text = readText()
|
val text = readText()
|
||||||
try {
|
try {
|
||||||
val result = Gson().fromJson(text, ProcesserPreference::class.java)
|
val result = Gson().fromJson(text, PeferenceConfig::class.java)
|
||||||
preference = result
|
preference = result.processer
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
}
|
}, orElse = {
|
||||||
|
CoordinatorEnv.preference.writeText(Gson().toJson(PeferenceConfig(preference)))
|
||||||
|
})
|
||||||
return preference
|
return preference
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun File.ifExists(block: File.() -> Unit) {
|
private fun File.ifExists(block: File.() -> Unit, orElse: () -> Unit = {}) {
|
||||||
if (this.exists()) {
|
if (this.exists()) {
|
||||||
block()
|
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:
|
endpoints:
|
||||||
web:
|
web:
|
||||||
exposure:
|
exposure:
|
||||||
include: mappings
|
include:
|
||||||
|
- mappings
|
||||||
|
- health
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
show-details: always
|
||||||
@ -24,9 +24,10 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
/*Spring boot*/
|
/*Spring boot*/
|
||||||
implementation("org.springframework.boot:spring-boot-starter")
|
|
||||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
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.boot:spring-boot-starter-webflux")
|
||||||
|
implementation("org.springframework:spring-tx")
|
||||||
|
|
||||||
// implementation("org.springframework.kafka:spring-kafka:3.0.1")
|
// 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 {
|
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("com.github.pgreze:kotlin-process:1.3.1")
|
||||||
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
implementation("io.github.microutils:kotlin-logging-jvm:2.0.11")
|
||||||
implementation(libs.exfl)
|
implementation(libs.exfl)
|
||||||
@ -34,9 +39,7 @@ dependencies {
|
|||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
|
||||||
implementation("com.google.code.gson:gson:2.8.9")
|
implementation("com.google.code.gson:gson:2.8.9")
|
||||||
implementation("org.json:json:20231013")
|
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-core")
|
||||||
implementation("org.flywaydb:flyway-mysql")
|
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