2026-09-21 15:40:58 +08:00
|
|
|
|
package com.gzzn.omms.msgexchange.ingress
|
|
|
|
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper
|
|
|
|
|
|
import com.gzzn.omms.msgexchange.processing.FlightProjectionPort
|
|
|
|
|
|
import io.micronaut.http.HttpResponse
|
|
|
|
|
|
import io.micronaut.http.HttpStatus
|
|
|
|
|
|
import io.micronaut.http.MediaType
|
|
|
|
|
|
import io.micronaut.http.annotation.Controller
|
|
|
|
|
|
import io.micronaut.http.annotation.Get
|
|
|
|
|
|
import io.micronaut.http.annotation.Produces
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* `GET /all/flights`:从 Redis 查询投影读当前全部动态航班,不含共享航班(`US-12`、`C-11`)。
|
|
|
|
|
|
*
|
|
|
|
|
|
* 数据只从投影来,不回落 PG:查询与网页客户端必须读同一份,不然两边会看到不同的航班
|
|
|
|
|
|
* (`INV-11`)。投影读不出来就返回错误——空列表会被前端当成"现在没有航班"(`US-12` AC2)。
|
|
|
|
|
|
*
|
2026-09-23 11:23:37 +08:00
|
|
|
|
* 成功:裸 JSON 数组、不套旧系统的 `ResponseDto`;失败:503 加错误对象(`C-11`)。
|
|
|
|
|
|
* 数组元素与 `KAFKA:schd` 同形,都是日计划 `FLTR` 转成的 JSON(`C-9`、`C-11`)。
|
2026-09-21 15:40:58 +08:00
|
|
|
|
*/
|
|
|
|
|
|
@Controller("/all/flights")
|
|
|
|
|
|
class FlightQueryController(
|
|
|
|
|
|
private val projection: FlightProjectionPort,
|
|
|
|
|
|
private val mapper: ObjectMapper,
|
|
|
|
|
|
) {
|
|
|
|
|
|
private val log = org.slf4j.LoggerFactory.getLogger(FlightQueryController::class.java)
|
|
|
|
|
|
|
|
|
|
|
|
@Get
|
|
|
|
|
|
@Produces(MediaType.APPLICATION_JSON)
|
|
|
|
|
|
fun all(): HttpResponse<String> =
|
|
|
|
|
|
try {
|
|
|
|
|
|
HttpResponse.ok(mapper.writeValueAsString(nonSharedFlights()))
|
|
|
|
|
|
} catch (e: Exception) {
|
|
|
|
|
|
// 读投影失败(Redis 不可用、未接通、载荷读不动)一律报错:这里没有可信的兜底数据源
|
|
|
|
|
|
val reason = e.message ?: e.javaClass.simpleName
|
|
|
|
|
|
log.error("GET /all/flights unavailable reason={}", reason, e)
|
|
|
|
|
|
HttpResponse.status<String>(HttpStatus.SERVICE_UNAVAILABLE)
|
|
|
|
|
|
.body(mapper.writeValueAsString(mapOf("error" to PROJECTION_UNAVAILABLE, "reason" to reason)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 共享航班由 `MAID`(主航班 FLID)非空标识,随主航班下发,不单独出现在列表里
|
|
|
|
|
|
* (`US-06` AC2 的主/共享关系,见 docs/implementation.md「航班域」)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
private fun nonSharedFlights(): List<com.fasterxml.jackson.databind.JsonNode> =
|
|
|
|
|
|
projection.readAll()
|
|
|
|
|
|
.map { mapper.readTree(it) }
|
2026-09-23 11:23:37 +08:00
|
|
|
|
.filter { it.path("MAID").asText("").isBlank() }
|
2026-09-21 15:40:58 +08:00
|
|
|
|
|
|
|
|
|
|
private companion object {
|
|
|
|
|
|
private const val PROJECTION_UNAVAILABLE = "FLIGHT_PROJECTION_UNAVAILABLE"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|