docs: 统一中间件定位与 JDBC 轮询主路径口径
Align README, architecture, design, config comments, and ingress docs with the upstream message-processing middleware model: external CIIMS write to CMINMSGS, JDBC poll as production ingress, HTTP /cminmsgs/send as compat. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+12
-6
@@ -12,7 +12,8 @@ import java.time.Instant
|
||||
* ACM2-12 仓储接口(接口驱动,主泵/调度循环可单测;Micronaut Data JDBC 实装属 U05 批次)。
|
||||
* 存储边界:自有 PostgreSQL(datasources.default)= 本文件除 CminmsgInboxRepository 外
|
||||
* 的全部接口(消息管道 PROC_STATE/MSG_EVENT、PUMP_JOB、REQ_TRACK、21 类 REF_MASTER);
|
||||
* 共享 MySQL 信箱(CMINMSGS 收 / COUTMSGS 出)经信箱封装访问,仅 DML、不建表;
|
||||
* 共享 MySQL 信箱(CMINMSGS / COUTMSGS)经信箱封装访问,仅 DML、不建表;
|
||||
* 主路径=上游外部写 CMINMSGS → 本系统 JDBC 轮询读;compat=insertRaw HTTP 写;
|
||||
* Redis = 航班动态 + 快照 gen(RefDataRepository 目标实现);FLIGHT_STATE 缓做。
|
||||
*/
|
||||
interface ProcStateRepository {
|
||||
@@ -148,15 +149,20 @@ interface FlightStateRepository {
|
||||
}
|
||||
|
||||
/**
|
||||
* 收报信箱(共享 MySQL CMINMSGS,仅 DML——ACM2-12:库属他人系统,本系统不建表)。
|
||||
* 事务模型:insertRaw = 外部副作用「信箱落信」(成功即返回其主键 CMINMSGS_ID)→
|
||||
* 随后自有 PG 建 PROC_STATE(PENDING) 入队;PG 建行失败以共享库
|
||||
* DATE_PROCESSED IS NULL 重扫补建。backfillOnSuccess 为处理成功后的外部回填
|
||||
* (DATE_PROCESSED/STATUS,最终一致、失败重试+告警)。
|
||||
* 共享信箱 CMINMSGS 访问(ACM2-12:库属他人系统,本系统不建表)。
|
||||
*
|
||||
* **主路径(生产)**:`pollNew` / `rawOf` — JDBC 轮询/读取上游外部写入的报文(U05 InboxPoller)。
|
||||
* **compat 路径**:`insertRaw` — HTTP `POST /cminmsgs/send` 辅助写(手工/对拍,非主拓扑)。
|
||||
*
|
||||
* 入队模型:发现或 compat 写得到 CMINMSGS_ID → 自有 PG 建 PROC_STATE(PENDING);
|
||||
* PG 建行失败以共享库 DATE_PROCESSED IS NULL 重扫补建。
|
||||
* `backfillOnSuccess` = 处理成功后的外部回填(DATE_PROCESSED/STATUS,最终一致)。
|
||||
*/
|
||||
interface CminmsgInboxRepository {
|
||||
/** compat HTTP 写路径:向共享信箱插入原文(U16 契约对拍)。 */
|
||||
fun insertRaw(rawXml: String): Long
|
||||
|
||||
/** 主路径/处理:按 CMINMSGS_ID 读取上游已落信的原文 XML。 */
|
||||
fun rawOf(cminmsgsId: Long): String?
|
||||
|
||||
fun backfillOnSuccess(cminmsgsId: Long, sndr: String, type: String, styp: String, seqn: Long)
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
/**
|
||||
* U07(U01 遗留 stub):内存仓储装配——仅当 `msgx.stubs=true`(dev/影子冒烟)时生效
|
||||
* (@Requires),让「启动 + 收报 + 主泵/投递循环 + /beans 端到端」在无 MySQL/Redis/Kafka 时可跑。
|
||||
* (@Requires),让「启动 + compat HTTP 写 + 主泵/投递循环 + /beans 端到端」在无 MySQL/Redis/Kafka 时可跑。
|
||||
* 与真实 Micronaut Data 实装按模块替换;切换点条件显式,不误入生产。
|
||||
*/
|
||||
@Requires(property = "msgx.stubs", value = "true")
|
||||
|
||||
@@ -8,7 +8,8 @@ import io.micronaut.http.annotation.Post
|
||||
import io.micronaut.http.annotation.Produces
|
||||
|
||||
/**
|
||||
* ACMA-8 契约冻结:端点路径与响应语义不变。现役 Controller 返回记录 ID(原文落库后)。
|
||||
* ACMA-8 契约冻结:compat HTTP 写路径 `POST /cminmsgs/send`(手工/对拍)。
|
||||
* 生产主路径 = JDBC 轮询共享 CMINMSGS(InboxPoller,U05),非本 Controller。
|
||||
*/
|
||||
@Controller
|
||||
class InboxController(private val inbox: InboxService) {
|
||||
|
||||
@@ -5,21 +5,20 @@ import com.gzzn.omms.msgexchange.nextgen.infra.persistence.ProcStateRepository
|
||||
import jakarta.inject.Singleton
|
||||
import java.time.Instant
|
||||
|
||||
/** ACMA-8 流程 1:入站接收。响应语义 = “已持久化”(与现役一致);不解析报文(I3)。 */
|
||||
/** ACMA-8 流程 1 · compat 写路径:HTTP 落信 + PG 入队(非生产主拓扑;主路径=InboxPoller JDBC 轮询,U05)。 */
|
||||
@Singleton
|
||||
class InboxService(
|
||||
private val inbox: CminmsgInboxRepository,
|
||||
private val procState: ProcStateRepository,
|
||||
// TODO(U05 批次): 事务模型(ACM2-12)——insertRaw 为共享信箱外部写(成功即返回 ID),
|
||||
// 随后自有 PG 建 PROC_STATE(PENDING);两写跨库,PG 建行失败以共享库
|
||||
// DATE_PROCESSED IS NULL 重扫补建;pump 唤醒仅加速,崩溃后主泵 1s 轮询兜底。
|
||||
// TODO(U05): 主路径 InboxPoller — JDBC 轮询 DATE_PROCESSED IS NULL → procState.insert;
|
||||
// compat 路径 insertRaw + PG 入队跨库;PG 失败以共享库重扫补建;wakePump 仅加速。
|
||||
) {
|
||||
private val log = org.slf4j.LoggerFactory.getLogger(InboxService::class.java)
|
||||
|
||||
data class Receipt(val cminmsgsId: Long, val receivedAt: Instant)
|
||||
|
||||
fun accept(rawXml: String): Receipt {
|
||||
val id = inbox.insertRaw(rawXml) // 信箱外部写(ACM2-12,与 PG 跨库)
|
||||
val id = inbox.insertRaw(rawXml) // compat:共享信箱外部写(ACM2-12,与 PG 跨库)
|
||||
procState.insert(id) // 自有 PG 入队;接收层无唯一约束(I3)
|
||||
wakePump()
|
||||
log.info("accepted cminmsgsId={}", id)
|
||||
|
||||
Reference in New Issue
Block a user