Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/307-admin-runtime-two-topology-stacks.txt
T
DongHyeonkaandClaude Opus 5 b2963105a8 docs(keycloak-session-store): import the session-storage lab as a new project
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>
2026-09-04 22:51:59 +09:00

81 lines
5.2 KiB
Plaintext

# 주제: messaging-admin-runtime 안에 완결된 토폴로지 검증 스택이 두 벌 있고,
# 문서화된 판단이 서로 어긋나며, 둘 다 프로덕션 호출부가 없다
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
# ---- Stack A ----
# BrokerTopologyInspector (SPI)
# -> CompositeTopologyValidator.validate(List<TopologyManifest>)
# -> TopologyValidator.compare(manifest, observed) -> List<TopologyIssue> (severity 있음)
# -> TopologyValidationReport
# -> requireAcceptable() -> MessagingConfigurationException("TOPOLOGY_MISMATCH")
#
# ---- Stack B ----
# TopologyValidationRuntime.TopologyReader (SPI)
# -> TopologyValidationRuntime.validate(List<TopologyManifest>)
# -> TopologyManifest.differencesFrom(...) -> List<String> (severity 없음)
# -> 직접 throw MessageTopologyException("TOPOLOGY_MISMATCH")
# ---- 두 스택이 어긋나는 지점 ----
# (1) 파티션 수가 선언보다 **많을** 때
# Stack A — TopologyValidator.java:58-66
# } else if (observed.partitions() > manifest.partitions()) {
# // Scaling a topic up is a legitimate operation; refusing to start would punish it.
# issues.add(TopologyIssue.advisory(...));
# }
# 클래스 javadoc:16-18 "A partition count that is *higher* than declared is advisory rather
# than blocking: extra partitions do not break durability, and someone
# scaling a topic up deliberately should not be met with a refusal to start."
# Stack B — TopologyManifest.differencesFrom (messaging-admin-api/TopologyManifest.java:57-59)
# if (actualPartitions != partitions) { differences.add("partitions expected … but found …"); }
# -> 많든 적든 차이면 problems 에 들어가고 TopologyValidationRuntime:53-57 이 예외를 던진다.
# => 토픽을 의도적으로 스케일 업한 배포에 대해 A 는 기동을 허용하고 B 는 거부한다.
# A 쪽에는 그 판단의 근거가 주석으로 명시되어 있다.
#
# (2) physicalName 불일치 — A 는 BLOCKING 으로 검사(TopologyValidator:45-49), B 는 검사하지 않는다.
# (3) severity — A 는 BLOCKING/ADVISORY 구분, B 는 전부 치명.
# (4) 예외 타입 — A: MessagingConfigurationException, B: MessageTopologyException. 코드 문자열은
# 둘 다 "TOPOLOGY_MISMATCH" 로 같다.
# (5) 부재 처리 — A: DestinationTopology.absent(...) 후 BLOCKING issue,
# B: reader.read() == null -> "… does not exist" 문자열.
# ---- 두 스택 모두 프로덕션 호출부가 없다 ----
# command: git grep -n "TopologyValidationRuntime\|TopologyReader\|ObservedTopology" -- src
# src/main 등장: TopologyValidationRuntime.java 자기 자신뿐 (18,20,27,42,62,70,80,83)
# 나머지는 전부 TopologyValidationRuntimeTest.java
# => Stack B: 프로덕션 호출부 0건.
#
# command: git grep -n "validateTopology" -- src (EVD-302 재확인)
# MessagingAdminService:32 (선언) + DefaultMessagingAdminService:106 (구현). 호출 0건.
# => Stack A: 프로덕션 호출부 0건.
# ---- 오케스트레이션 계층이 어디에서도 생성되지 않는다 ----
# command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?<T>\s*\(" -- src (T별 집계)
DefaultMessagingAdminService src/main=0 src/test=0 <-- 어디에서도 생성되지 않음
ReplayService src/main=0 src/test=0 <-- 어디에서도 생성되지 않음
RedriveService src/main=0 src/test=1 (RedriveResumptionTest 만)
CompositeTopologyValidator src/main=1 src/test=1 (스타터)
TopologyValidator src/main=1 src/test=6 (CompositeTopologyValidator 내부 필드)
TopologyValidationRuntime src/main=0 src/test=4
InMemoryAdminOperationJournal src/main=1 src/test=3 (스타터)
JdbcAdminOperationJournal src/main=0 src/test=2
#
# src/main 생성 상세 (전 저장소에서 2건뿐):
# MessagingAdminAutoConfiguration.java:57 new InMemoryAdminOperationJournal();
# MessagingAdminAutoConfiguration.java:84 new CompositeTopologyValidator(inspector);
#
# => DefaultMessagingAdminService 257줄 — 계획/승인/저널/실행을 잇는 유일한 오케스트레이터이며
# 클래스 javadoc 이 "Execution runs four checks, in this order, and the order is the point" 이라고
# 쓰는 그 클래스 — 는 프로덕션에서도 테스트에서도 인스턴스화되지 않는다. 실행 커버리지 0.
# ApprovedPlanExecutionTest 11건은 Approved*Plan 타입을 직접 검증하며 이 서비스를 거치지 않는다.
# ---- DestructiveMessagingAdmin 은 구현체가 없다 ----
# command: git grep -n "DestructiveMessagingAdmin" -- src
# DestructiveMessagingAdmin.java:21 (선언)
# MessagingAdminService.java:21 ({@link} 참조)
# MessagingAdminAutoConfiguration.java:22 ({@link} 참조)
# command: git grep -n "DestructiveMessagingAdmin.Approved\|new Approved(\|DestructiveResult" -- src
# (선언 파일 제외 후 출력 없음)
# => implements 0건, Approved/DestructiveResult 사용 0건.
# DestructiveOperation 5개 상수 중 PURGE / OFFSET_RESET / DELETE_DESTINATION 3개는
# 이 저장소 어디에도 실행 경로가 없다. (REPLAY/REDRIVE 만 서비스가 있다.)