The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
66 lines
5.0 KiB
Plaintext
66 lines
5.0 KiB
Plaintext
# 주제: messaging-admin-api 가 선언한 "토폴로지 불일치 시 기동 실패" 보장이
|
|
# 어떤 배선에서도 실행되지 않는다
|
|
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
|
|
|
|
# 선언된 보장 (messaging-admin-api/src/main)
|
|
# TopologyIssue.java:9-12
|
|
# "A {@link Severity#BLOCKING} issue means the destination cannot deliver its declared
|
|
# guarantee — replication factor 1 on a destination promising durability is not a warning,
|
|
# it is a promise the platform cannot keep — so the context refuses to start."
|
|
# TopologyIssue.Severity.BLOCKING javadoc (:25)
|
|
# "The destination cannot deliver a declared guarantee; startup must fail."
|
|
# TopologyValidationReport.requireAcceptable() javadoc (:68-71)
|
|
# "Fails startup when any blocking issue was found."
|
|
|
|
# command: git grep -n "requireAcceptable" -- src
|
|
# exit: 0
|
|
src/messaging/messaging-admin-api/src/main/java/.../TopologyValidationReport.java:73: public void requireAcceptable() {
|
|
src/messaging/messaging-admin-runtime/src/test/java/.../TopologyValidatorTest.java:113: assertThatThrownBy(report::requireAcceptable)
|
|
src/messaging/messaging-admin-runtime/src/test/java/.../TopologyValidatorTest.java:126: assertThatCode(report::requireAcceptable).doesNotThrowAnyException();
|
|
src/messaging/messaging-kafka/src/test/java/.../KafkaTopologyValidationIT.java:95: assertThatThrownBy(report::requireAcceptable)
|
|
src/messaging/messaging-kafka/src/test/java/.../KafkaTopologyValidationIT.java:111: assertThatCode(report::requireAcceptable)
|
|
# => 선언 1 + 테스트 호출 4. src/main 호출 0건.
|
|
|
|
# command: git grep -n "validateTopology" -- src
|
|
# exit: 0
|
|
src/messaging/messaging-admin-runtime/src/main/java/.../DefaultMessagingAdminService.java:106: public TopologyValidationReport validateTopology() {
|
|
src/messaging/messaging-admin-runtime/src/main/java/.../MessagingAdminService.java:32: TopologyValidationReport validateTopology();
|
|
# => 인터페이스 선언 + 구현. 호출부 0건 (src/main, src/test 모두).
|
|
|
|
# command: 스타터가 만드는 admin 빈 전수 (MessagingAdminAutoConfiguration.java)
|
|
# @ConditionalOnProperty(prefix="app.messaging.admin", name="enabled", havingValue="true")
|
|
# :37 DestructiveOperationGuard destructiveOperationGuard() -> new DestructiveOperationGuard(false)
|
|
# :56 AdminOperationJournal adminOperationJournal() -> new InMemoryAdminOperationJournal()
|
|
# :69 MessagingAdminDurabilityValidator … (InitializingBean — 기동 시 실행됨)
|
|
# :83 CompositeTopologyValidator compositeTopologyValidator(BrokerTopologyInspector)
|
|
# @ConditionalOnBean(BrokerTopologyInspector.class)
|
|
# => MessagingAdminService / DefaultMessagingAdminService 빈은 없다.
|
|
# CompositeTopologyValidator 빈은 만들어지지만 그것을 호출하는 빈이 없다.
|
|
# 따라서 부팅된 애플리케이션에서 validateTopology() 도 requireAcceptable() 도 실행되지 않는다.
|
|
|
|
# 대조군 — 같은 스타터에서 "기동 실패" 를 실제로 구현한 검사가 있다:
|
|
# MessagingAdminDurabilityValidator implements InitializingBean
|
|
# afterPropertiesSet() -> validate() -> 프로덕션 프로파일 + !journal.isDurable() 이면
|
|
# MessagingConfigurationException("ADMIN_JOURNAL_NOT_DURABLE")
|
|
# => 저널 쪽에는 기동 실패 배선이 있고, 토폴로지 쪽에는 없다. 패턴은 이미 같은 파일에 있다.
|
|
|
|
# ---- 추가: TopologyManagementMode 는 프로덕션 코드에서 완전히 미사용 ----
|
|
# command: git grep -n "TopologyManagementMode" -- src
|
|
# exit: 0
|
|
src/messaging/messaging-admin-api/src/main/java/.../TopologyManagementMode.java:14:public enum TopologyManagementMode {
|
|
src/messaging/messaging-admin-runtime/src/test/java/.../TopologyValidatorTest.java:9 (import)
|
|
src/messaging/messaging-admin-runtime/src/test/java/.../TopologyValidatorTest.java:156,163,169
|
|
# => 자기 선언 + 테스트 4건. 이 타입의 필드/파라미터/설정 프로퍼티가 저장소에 하나도 없다.
|
|
# enum javadoc 은 "VALIDATE_ONLY in production, always" 라고 쓰지만,
|
|
# 이 모드를 읽어 분기하는 코드가 존재하지 않으므로 강제하는 주체가 없다.
|
|
|
|
# ---- 운영자용 표면도 프로덕션 소비자가 없다 ----
|
|
# command: git grep -n "isFullyAccounted\|fellShortOfTheEstimate\|isResumption\|describeImpact" -- src
|
|
RedrivePlan.describeImpact() : 선언 + RedrivePlan 내부 1 + 테스트 2 (src/main 외부 호출 0)
|
|
ReplayPlan.describeImpact() : 선언 + 테스트 2 (src/main 호출 0)
|
|
ReplayResult.fellShortOfTheEstimate() : 선언 + 테스트 1 (src/main 호출 0)
|
|
RedriveResult.isFullyAccounted() : 선언 + 테스트 2 (src/main 호출 0)
|
|
AdminOperationLease.isResumption() : 선언 + 테스트 1 (src/main 호출 0)
|
|
# => 계획 시점 영향 요약, 추정치 미달 신호, 후보 정산 누락 신호, 재개 여부 —
|
|
# "운영자가 결정을 내리기 위한 표면" 전체가 테스트에서만 호출된다.
|