fix(config): fail fast on invalid operation-day zone
运营日时区只认 PARAM:msgx.operation-day.zone:JobRunner、HistorySweepJob、JdbcSnapshotLogRepository.purgeBefore 改走注入的 OperationDayProps;ScheduleProcessor/AdftProcessor 删除「非法值回退字面量」;新增 @Context 启动自检 OperationDayZoneCheck,配置错位在启动时暴露。 验证:./gradlew test 126 tests / 0 fail(新增 OperationDayPropsTest 覆盖合法解析与非法即失败)。
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package com.gzzn.omms.msgexchange.config
|
||||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.ZoneId
|
||||
|
||||
/**
|
||||
* 运营日时区只有一个出处(`PARAM:msgx.operation-day.zone`):能解析就解析,
|
||||
* 解析不了必须让启动失败,**不允许回退到代码字面量**——回退会把配置错位藏起来,
|
||||
* 让运营日按错误的时区计算。
|
||||
*/
|
||||
class OperationDayPropsTest {
|
||||
|
||||
@Test
|
||||
fun `configured zone resolves to the IANA zone`() {
|
||||
val props = OperationDayProps().apply { zone = "Asia/Shanghai" }
|
||||
|
||||
assertEquals(ZoneId.of("Asia/Shanghai"), props.zoneId())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid zone fails fast instead of falling back to a literal`() {
|
||||
val props = OperationDayProps().apply { zone = "Not/AZone" }
|
||||
|
||||
val failure = assertThrows(IllegalStateException::class.java) { props.zoneId() }
|
||||
|
||||
assertTrue(failure.message!!.contains("msgx.operation-day.zone"))
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gzzn.omms.msgexchange.jobs
|
||||
|
||||
import com.gzzn.omms.msgexchange.config.HistoryProps
|
||||
import com.gzzn.omms.msgexchange.config.OperationDayProps
|
||||
import com.gzzn.omms.msgexchange.domain.EventType
|
||||
import com.gzzn.omms.msgexchange.domain.flight.FlightState
|
||||
import com.gzzn.omms.msgexchange.domain.flight.HistoryCandidate
|
||||
@@ -50,7 +51,7 @@ class HistorySweepJobTest {
|
||||
fun `history store not connected must delete zero rows`() {
|
||||
val f = seededFlight("F1", deleted = true, idleDays = 30)
|
||||
val events = StubMsgEvents()
|
||||
val job = HistorySweepJob(f, events, HistoryProps().apply { historyStoreEnabled = false })
|
||||
val job = HistorySweepJob(f, events, HistoryProps().apply { historyStoreEnabled = false }, OperationDayProps())
|
||||
|
||||
val outcome = job.run(now)
|
||||
|
||||
@@ -71,7 +72,7 @@ class HistorySweepJobTest {
|
||||
val events = StubMsgEvents()
|
||||
val store = RecordingHistoryStore().apply { confirmed.add("F1") } // 只有 F1 归档确认成功
|
||||
val job = HistorySweepJob(
|
||||
f, events, HistoryProps().apply { historyStoreEnabled = true }, historyStore = store,
|
||||
f, events, HistoryProps().apply { historyStoreEnabled = true }, OperationDayProps(), historyStore = store,
|
||||
)
|
||||
|
||||
val outcome = job.run(now)
|
||||
@@ -90,7 +91,7 @@ class HistorySweepJobTest {
|
||||
val events = StubMsgEvents()
|
||||
val store = RecordingHistoryStore()
|
||||
val job = HistorySweepJob(
|
||||
f, events, HistoryProps().apply { historyStoreEnabled = true }, historyStore = store,
|
||||
f, events, HistoryProps().apply { historyStoreEnabled = true }, OperationDayProps(), historyStore = store,
|
||||
)
|
||||
|
||||
job.run(now)
|
||||
@@ -108,7 +109,7 @@ class HistorySweepJobTest {
|
||||
var cutoff: Instant? = null
|
||||
val purge = com.gzzn.omms.msgexchange.infra.persistence.SnapshotLogPurge { instant -> cutoff = instant; 7 }
|
||||
val job = HistorySweepJob(
|
||||
f, StubMsgEvents(), HistoryProps().apply { historyStoreEnabled = false }, snapLogPurge = purge,
|
||||
f, StubMsgEvents(), HistoryProps().apply { historyStoreEnabled = false }, OperationDayProps(), snapLogPurge = purge,
|
||||
)
|
||||
|
||||
val outcome = job.run(now)
|
||||
|
||||
Reference in New Issue
Block a user