Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/176-outbound-messaging-module-inventory.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

239 lines
15 KiB
Plaintext

adapter-outbound-messaging — 모듈 인벤토리
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T06:23:18+00:00
=== tracked file 총계 ===
$ git ls-files 'adapter/outbound/messaging' | wc -l
69
exit=0
$ for d in $(git ls-files 'adapter/outbound/messaging/src' | sed 's|^adapter/outbound/messaging/src/||' | cut -d/ -f1 | sort -u); do n=$(git ls-files "adapter/outbound/messaging/src/$d" | wc -l); l=$(git ls-files "adapter/outbound/messaging/src/$d" | xargs wc -l 2>/dev/null | tail -1 | awk '{print $1}'); echo "$d: $n files, $l LOC"; done
main: 46 files, 4607 LOC
test: 19 files, 3670 LOC
exit=0
=== 패키지 배치 ===
$ git ls-files 'adapter/outbound/messaging/src/main' | grep '\.java$' | sed 's|.*/dev/caskeleton/||' | xargs -n1 dirname | sort | uniq -c | sort -rn
5 adapter/outbound/messaging/kafka
5 adapter/outbound/messaging/envelope
5 adapter/outbound/messaging/core
4 adapter/outbound/messaging/outbox
4 adapter/outbound/messaging/destination
3 adapter/outbound/messaging/contract
2 adapter/outbound/messaging/realtime
2 adapter/outbound/messaging/config
2 adapter/outbound/messaging/autoconfigure
2 adapter/outbound/messaging
exit=0
$ git ls-files 'adapter/outbound/messaging/src/test' | grep '\.java$' | sed 's|.*/dev/caskeleton/||' | xargs -n1 dirname | sort | uniq -c | sort -rn
3 adapter/outbound/messaging/envelope
2 adapter/outbound/messaging/qualification
2 adapter/outbound/messaging/outbox
2 adapter/outbound/messaging/kafka
2 adapter/outbound/messaging/destination
2 adapter/outbound/messaging/contract
1 adapter/outbound/messaging/core
1 adapter/outbound/messaging/config
1 adapter/outbound/messaging
exit=0
=== main 전체 (크기순) ===
$ git ls-files 'adapter/outbound/messaging/src/main' | grep '\.java$' | xargs wc -l | sort -rn
4246 total
701 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/LocalJsonSchemaRegistry.java
548 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/DeterministicEnvelopeWriter.java
274 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogCompiler.java
263 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/CompiledIntegrationEventContract.java
248 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/DestinationBindingCompiler.java
238 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/DestinationBindingSettings.java
235 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/config/MessagingCapabilityCardRegistry.java
232 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/JsonSchemaIntegrationEventEncoder.java
204 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/config/CompiledMessagingDescriptor.java
132 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/PartitionKeyV1.java
108 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/kafka/BrokerAddress.java
105 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/destination/CompiledPublicationBinding.java
91 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/contract/ContractCatalogDigest.java
79 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/MessagingConfig.java
78 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/realtime/RealtimeFanoutEnvelopeJson.java
70 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/outbox/OutboxEnvelopeJson.java
65 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/outbox/Slf4jOutboxRelayFailureReportAdapter.java
61 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/core/OutboundMessagePublisher.java
60 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/realtime/MessagingDurableFanoutAdapter.java
56 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/EnvelopeAdmissionLimits.java
52 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/autoconfigure/MessagingOffAutoConfigurationImportFilter.java
48 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/kafka/KafkaAdapterSettings.java
41 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/outbox/OutboxMessagePublishAdapter.java
36 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/envelope/EnvelopeHashV1.java
32 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/kafka/KafkaAdapterConfig.java
31 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/kafka/KafkaMessageBroker.java
25 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/core/OutboundMessage.java
24 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/autoconfigure/MessagingBridgeRootAutoConfiguration.java
20 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/outbox/DisabledOutboxMessagePublisher.java
20 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/core/MessageBroker.java
20 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/MessagingSettings.java
19 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/kafka/KafkaSender.java
17 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/core/DisabledMessagePublisher.java
13 adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/core/MessagePublisher.java
exit=0
=== 비 Java ===
$ git ls-files 'adapter/outbound/messaging' | grep -v '\.java$'
adapter/outbound/messaging/CLAUDE.md
adapter/outbound/messaging/README.md
adapter/outbound/messaging/build.gradle
adapter/outbound/messaging/gradle.lockfile
adapter/outbound/messaging/src/main/resources/META-INF/spring.factories
adapter/outbound/messaging/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/authority.sha256
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/applicator
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/content
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/core
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/format-annotation
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/format-assertion
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/meta-data
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/unevaluated
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/meta/validation
adapter/outbound/messaging/src/main/resources/contracts/messaging/meta/draft-2020-12/draft/2020-12/schema
adapter/outbound/messaging/src/test/resources/contracts/messaging/test.event/v1.invalid.json
adapter/outbound/messaging/src/test/resources/contracts/messaging/test.event/v1.schema.json
adapter/outbound/messaging/src/test/resources/contracts/messaging/test.event/v1.valid.json
exit=0
=== 레지스트리 ===
$ python3 -c "
import json;d=json.load(open('config/architecture/modules.json'))
for m in d['modules']:
if m['id']=='adapter-outbound-messaging': print(json.dumps(m,ensure_ascii=False,indent=2))
"
{
"id": "adapter-outbound-messaging",
"gradle_path": ":adapter:outbound:messaging",
"source_path": "src/adapter/outbound/messaging",
"allowed_dependencies": [
"domain-core",
"application-core",
"shared-contract",
"adapter-outbound-support"
],
"runtime_memberships": [
"app-bootstrap"
]
}
exit=0
=== build.gradle ===
$ cat -n 'adapter/outbound/messaging/build.gradle'
1
2 dependencies {
3 implementation project(':application-core')
4 implementation project(':shared-contract')
5 implementation project(':adapter:outbound:support')
6
7 implementation 'org.springframework.boot:spring-boot-autoconfigure'
8 implementation 'org.springframework.boot:spring-boot-starter-json'
9 implementation('com.networknt:json-schema-validator:3.0.2') {
10 exclude group: 'com.fasterxml.jackson.dataformat', module: 'jackson-dataformat-yaml'
11 }
12 implementation 'org.slf4j:slf4j-api'
13 annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
14 }
15 tasks.withType(JavaCompile).configureEach { options.encoding = 'UTF-8' }
16 tasks.withType(Test).configureEach {
17 systemProperty 'messaging.commonEvidenceSchema',
18 rootProject.file('config/messaging/evidence/build-evidence-manifest-v1.schema.json')
19 .absolutePath
20 }
21
22 configurations.configureEach {
23 exclude group: 'tools.jackson.dataformat', module: 'jackson-dataformat-yaml'
24 exclude group: 'org.yaml', module: 'snakeyaml'
25 exclude group: 'org.snakeyaml', module: 'snakeyaml-engine'
26 }
27
28 tasks.register('verifyJsonSchemaRuntimeGraph') {
29 group = 'verification'
30 description = 'Verifies the closed Jackson 3 / NetworkNT graph contains no YAML or Jackson 2 runtime.'
31 doLast {
32 Set<String> modules = configurations.runtimeClasspath.incoming.resolutionResult
33 .allComponents
34 .findAll { it.moduleVersion != null }
35 .collect {
36 "${it.moduleVersion.group}:${it.moduleVersion.name}:${it.moduleVersion.version}"
37 .toString()
38 } as Set
39 List<String> forbidden = modules.findAll { String coordinate ->
40 String lowered = coordinate.toLowerCase(Locale.ROOT)
41 lowered.contains('yaml') ||
42 lowered.startsWith('org.yaml:') ||
43 lowered.startsWith('org.snakeyaml:') ||
44 lowered ==~ /com\.fasterxml\.jackson\.core:jackson-(core|databind):.*/
45 }.sort()
46 if (!forbidden.isEmpty()) {
47 throw new GradleException(
48 "Messaging JSON runtime contains forbidden Jackson 2/YAML modules: ${forbidden}")
49 }
50 [
51 'com.networknt:json-schema-validator:3.0.2',
52 'tools.jackson.core:jackson-core:3.0.2',
53 'tools.jackson.core:jackson-databind:3.0.2'
54 ].each { String required ->
55 if (!modules.contains(required)) {
56 throw new GradleException(
57 "Messaging JSON runtime is missing required locked module ${required}")
58 }
59 }
60 // Jackson 3 intentionally retains the 2.x-namespace annotations artifact. It is not a
61 // Jackson 2 databind/runtime engine and is part of the official Jackson 3 BOM graph.
62 }
63 }
64
65 tasks.named('check') {
66 dependsOn tasks.named('verifyJsonSchemaRuntimeGraph')
67 }
68
69 def messagingCompiledContractsQualification = registerStrictQualificationTest(
70 name: 'messagingCompiledContractsQualificationTest',
71 sourceSet: sourceSets.test,
72 requiredClasses: [
73 'dev.caskeleton.adapter.outbound.messaging.config.MessagingCapabilityCardRegistryTest',
74 'dev.caskeleton.adapter.outbound.messaging.contract.ContractCatalogCompilerTest',
75 'dev.caskeleton.adapter.outbound.messaging.contract.ContractCatalogDigestTest',
76 'dev.caskeleton.adapter.outbound.messaging.destination.DestinationBindingCompilerTest',
77 'dev.caskeleton.adapter.outbound.messaging.destination.PartitionKeyV1Test'
78 ],
79 junitXmlOutput: rootProject.layout.buildDirectory.dir(
80 'test-results/messaging-evidence/compiled'),
81 binaryResultsOutput: rootProject.layout.buildDirectory.dir(
82 'test-results/messaging-evidence-binary/compiled'),
83 description: 'Runs exact Messaging compiled-contract qualification tests.')
84 messagingCompiledContractsQualification.configure {
85 dependsOn ':prepareMessagingContractEvidence'
86 }
87
88 def messagingJsonSchemaV1Qualification = registerStrictQualificationTest(
89 name: 'messagingJsonSchemaV1QualificationTest',
90 sourceSet: sourceSets.test,
91 requiredClasses: [
92 'dev.caskeleton.adapter.outbound.messaging.envelope.LocalJsonSchemaRegistryTest',
93 'dev.caskeleton.adapter.outbound.messaging.envelope.JsonSchemaIntegrationEventEncoderTest',
94 'dev.caskeleton.adapter.outbound.messaging.envelope.EnvelopeAdversarialCorpusTest',
95 'dev.caskeleton.adapter.outbound.messaging.qualification.MessagingEvidenceManifestSchemaValidatorTest'
96 ],
97 junitXmlOutput: rootProject.layout.buildDirectory.dir(
98 'test-results/messaging-evidence/json-schema'),
99 binaryResultsOutput: rootProject.layout.buildDirectory.dir(
100 'test-results/messaging-evidence-binary/json-schema'),
101 description: 'Runs exact Messaging JSON Schema v1 qualification tests.')
102 messagingJsonSchemaV1Qualification.configure {
103 dependsOn ':prepareMessagingContractEvidence'
104 }
exit=0
=== leaf 밖 소비자 ===
$ git grep -l 'dev.caskeleton.adapter.outbound.messaging' -- . | grep -v '^adapter/outbound/messaging/' | sed 's|/src/.*||' | sort | uniq -c
5 app-bootstrap
1 build.gradle
exit=0