feat(ingress): 实现 JDBC 信箱轮询、入站持久化与对拍测试 (U05)
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package com.gzzn.omms.msgexchange.infra.health
|
||||
|
||||
import com.gzzn.omms.msgexchange.delivery.DeliveryPort
|
||||
import com.gzzn.omms.msgexchange.infra.redis.FlightRedisClient
|
||||
import io.micronaut.context.BeanProvider
|
||||
import io.micronaut.core.async.publisher.Publishers
|
||||
import io.micronaut.health.HealthStatus
|
||||
import io.micronaut.management.health.indicator.HealthIndicator
|
||||
import io.micronaut.management.health.indicator.HealthResult
|
||||
import jakarta.inject.Singleton
|
||||
import org.reactivestreams.Publisher
|
||||
|
||||
/**
|
||||
* U12(R05):阶段 A 关键依赖的自定义健康指示器——
|
||||
* Redis(flightInfo 权威存储)与 Kafka(投递端口)。经 BeanProvider 可选解析:
|
||||
* 缺 bean(如未用 stub 也未实装)时指示 DOWN 而非启动失败;
|
||||
* UP 判据为真实 ping(false/异常 → DOWN),而非仅 bean 存在(复审 P1 修正)。
|
||||
*/
|
||||
@Singleton
|
||||
class FlightRedisHealthIndicator(
|
||||
private val redis: BeanProvider<FlightRedisClient>,
|
||||
) : HealthIndicator {
|
||||
|
||||
override fun getResult(): Publisher<HealthResult> =
|
||||
Publishers.just(redisHealth(if (redis.isPresent) redis.get() else null))
|
||||
}
|
||||
|
||||
@Singleton
|
||||
class KafkaDeliveryHealthIndicator(
|
||||
private val port: BeanProvider<DeliveryPort>,
|
||||
) : HealthIndicator {
|
||||
|
||||
override fun getResult(): Publisher<HealthResult> =
|
||||
Publishers.just(kafkaHealth(if (port.isPresent) port.get() else null))
|
||||
}
|
||||
|
||||
/** ping 判定独立成纯函数便于单测:client 为 null = bean 缺失;ping false/异常 = DOWN。 */
|
||||
internal fun redisHealth(client: FlightRedisClient?): HealthResult =
|
||||
healthOf("redis-flight-store", "flight store", client?.let {
|
||||
try { it.ping() } catch (e: Exception) { false }
|
||||
})
|
||||
|
||||
internal fun kafkaHealth(port: DeliveryPort?): HealthResult =
|
||||
healthOf("kafka-delivery", "delivery port", port?.let {
|
||||
try { it.ping() } catch (e: Exception) { false }
|
||||
})
|
||||
|
||||
private fun healthOf(name: String, what: String, pingOk: Boolean?): HealthResult {
|
||||
val (status, message) = when (pingOk) {
|
||||
null -> HealthStatus.DOWN to "$what bean missing (stub off, impl pending)"
|
||||
false -> HealthStatus.DOWN to "$what ping failed"
|
||||
true -> HealthStatus.UP to "$what ping ok"
|
||||
}
|
||||
return HealthResult.builder(name).status(status).details(mapOf("message" to message)).build()
|
||||
}
|
||||
Reference in New Issue
Block a user