1
0

refactor: architecture

Signed-off-by: Alan Brault <alan.brault@visus.io>
This commit is contained in:
2026-03-02 08:08:20 -05:00
parent b316d0fbb4
commit 506a6095e1
4 changed files with 36 additions and 23 deletions

View File

@@ -6,11 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema
import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponse
import io.swagger.v3.oas.annotations.tags.Tag import io.swagger.v3.oas.annotations.tags.Tag
import io.visus.demos.kotlinapi.api.dto.HealthResponse import io.visus.demos.kotlinapi.api.dto.HealthResponse
import io.visus.demos.kotlinapi.api.mappers.HealthResponseMapper
import io.visus.demos.kotlinapi.domain.model.HealthStatus
import io.visus.demos.kotlinapi.domain.model.Status
import io.visus.demos.kotlinapi.domain.service.HealthService import io.visus.demos.kotlinapi.domain.service.HealthService
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.GetMapping
@@ -19,7 +15,7 @@ import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@Tag(name = "Health", description = "Health check endpoints") @Tag(name = "Health", description = "Health check endpoints")
class HealthController( class HealthController(
private val healthCheckServices: List<HealthService>, private val healthCheckService: HealthService,
) { ) {
@GetMapping("/health", produces = [MediaType.APPLICATION_JSON_VALUE]) @GetMapping("/health", produces = [MediaType.APPLICATION_JSON_VALUE])
@Operation( @Operation(
@@ -48,17 +44,5 @@ class HealthController(
), ),
], ],
) )
fun health(): ResponseEntity<HealthResponse> { fun health(): ResponseEntity<HealthResponse> = healthCheckService.check()
val componentHealths = healthCheckServices.map { it.check() }
val healthStatus = HealthStatus.fromComponents(componentHealths)
val response = HealthResponseMapper.map(healthStatus)
val httpStatus =
when (healthStatus.status) {
Status.UP -> HttpStatus.OK
Status.DOWN, Status.DEGRADED -> HttpStatus.SERVICE_UNAVAILABLE
}
return ResponseEntity.status(httpStatus).body(response)
}
} }

View File

@@ -0,0 +1,7 @@
package io.visus.demos.kotlinapi.domain.port
import io.visus.demos.kotlinapi.domain.model.ComponentHealth
interface HealthIndicator {
fun check(): ComponentHealth
}

View File

@@ -1,7 +1,29 @@
package io.visus.demos.kotlinapi.domain.service package io.visus.demos.kotlinapi.domain.service
import io.visus.demos.kotlinapi.domain.model.ComponentHealth import io.visus.demos.kotlinapi.api.dto.HealthResponse
import io.visus.demos.kotlinapi.api.mappers.HealthResponseMapper
import io.visus.demos.kotlinapi.domain.port.HealthIndicator
import io.visus.demos.kotlinapi.domain.model.HealthStatus
import io.visus.demos.kotlinapi.domain.model.Status
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.stereotype.Service
interface HealthService { @Service
fun check(): ComponentHealth class HealthService(
private val healthIndicators: List<HealthIndicator>,
) {
fun check(): ResponseEntity<HealthResponse> {
val componentHealths = healthIndicators.map { it.check() }
val healthStatus = HealthStatus.fromComponents(componentHealths)
val response = HealthResponseMapper.map(healthStatus)
val httpStatus =
when (healthStatus.status) {
Status.UP -> HttpStatus.OK
Status.DOWN, Status.DEGRADED -> HttpStatus.SERVICE_UNAVAILABLE
}
return ResponseEntity.status(httpStatus).body(response)
}
} }

View File

@@ -3,14 +3,14 @@ package io.visus.demos.kotlinapi.infrastructure.health
import com.mongodb.client.MongoClient import com.mongodb.client.MongoClient
import io.visus.demos.kotlinapi.domain.model.ComponentHealth import io.visus.demos.kotlinapi.domain.model.ComponentHealth
import io.visus.demos.kotlinapi.domain.model.ComponentStatus import io.visus.demos.kotlinapi.domain.model.ComponentStatus
import io.visus.demos.kotlinapi.domain.service.HealthService import io.visus.demos.kotlinapi.domain.port.HealthIndicator
import org.bson.Document import org.bson.Document
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
@Service @Service
class MongoHealthService( class MongoHealthService(
private val mongoClient: MongoClient, private val mongoClient: MongoClient,
) : HealthService { ) : HealthIndicator {
override fun check(): ComponentHealth = override fun check(): ComponentHealth =
try { try {
val command = Document("ping", 1) val command = Document("ping", 1)