Files
document-haness/docs/clean-architecture-backend-template/final/evidence/rendered/a-validator-that-demands-tls-and-an-assembly-that-omits-it.svg
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

188 lines
35 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="3472" viewBox="0 0 1200 3472" role="img">
<title>terminal evidence</title>
<desc>Terminal-style rendering generated from retained command output. Sensitive-looking values are redacted in the visual asset.</desc>
<rect x="1" y="1" width="1198" height="3470" rx="14" fill="#0d1117" stroke="#30363d"/>
<rect x="1" y="1" width="1198" height="44" rx="14" fill="#161b22"/>
<rect x="1" y="30" width="1198" height="14" fill="#161b22"/>
<circle cx="24" cy="22" r="6" fill="#ff5f57"/>
<circle cx="44" cy="22" r="6" fill="#febc2e"/>
<circle cx="64" cy="22" r="6" fill="#28c840"/>
<text x="92" y="27" fill="#8b949e" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace">terminal evidence</text>
<text x="24" y="68" fill="#c9d1d9" font-size="15" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">$ set -e
set -o pipefail
K=src/messaging/messaging-kafka/src/main/java/dev/caskeleton/messaging/kafka
A=src/messaging/me</tspan><tspan x="24" dy="22">ssaging-spring-boot-starter/src/main/java/dev/caskeleton/messaging/autoconfigure
B=src/app-bootstrap/src/main/java/dev/c</tspan><tspan x="24" dy="22">askeleton/bootstrap/messaging
strip() { sed -E &#x27;s#^src/[^:]*/src/(main|test|testFixtures)/[^:]*/([^:/]+):([0-9]+):# \1 </tspan><tspan x="24" dy="22">· \2:\3 #&#x27;; }
cut_range() { awk -v f=&quot;$2&quot; -v a=&quot;$3&quot; -v b=&quot;$4&quot; &#x27;NR&gt;=a &amp;&amp; NR&lt;=b {printf &quot; %s:%d %s\n&quot;, f, NR, $0}&#x27; &quot;$1&quot;;</tspan><tspan x="24" dy="22"> }
echo &quot;# 운영 프로파일에 KafkaProfileValidator 가 거는 두 요구&quot;
cut_range $K/KafkaProfileValidator.java KafkaProfileV</tspan><tspan x="24" dy="22">alidator.java 51 58
echo
echo &quot;# 그 검증기가 기동에서 도는 경로와, 그 거부를 지키는 테스트&quot;
git grep -n &#x27;kafkaProfileSt</tspan><tspan x="24" dy="22">artupValidation&#x27; -- &#x27;src/**/*.java&#x27; | strip
git grep -n &#x27;implements InitializingBean\|afterPropertiesSet&#x27; -- &#x27;**/Startup</tspan><tspan x="24" dy="22">ProfileValidation.java&#x27; | strip
git grep -n &#x27;aProductionKafkaBrokerWithoutTransportSecurityFailsStartup&#x27; -- &#x27;src/**/*.ja</tspan><tspan x="24" dy="22">va&#x27; | strip
echo
echo &quot;# 두 조립부를 켜는 프로퍼티&quot;
git grep -n &#x27;name = &quot;enabled&quot;, havingValue = &quot;true&quot;&#x27; -- &#x27;src/**/*.j</tspan><tspan x="24" dy="22">ava&#x27; | grep -iE &#x27;messaging&#x27; | strip
git grep -n &#x27;&quot;kafka&quot;, KafkaMessagingAutoConfiguration.class&#x27; -- &#x27;src/**/*.java&#x27; | st</tspan><tspan x="24" dy="22">rip
grep -n &#x27;^@ConditionalOnProperty&#x27; $B/KafkaSenderConfig.java | sed -E &#x27;s#^([0-9]+):# main · KafkaSenderConfig.java:</tspan><tspan x="24" dy="22">\1 #&#x27;
echo -n &quot; 출하 기본값 : &quot;
grep -n &#x27;APP_MESSAGING_ENABLED&#x27; src/app-bootstrap/src/main/resources/application.yml | </tspan><tspan x="24" dy="22">head -1 | sed &#x27;s#^#application.yml:#&#x27;
echo
echo &quot;# 프로덕션에서 KafkaProducer 를 만드는 두 자리 — 설정 맵 원문 그대로&quot;</tspan><tspan x="24" dy="22">
grep -n &#x27;@Bean\|@ConditionalOnMissingBean&#x27; $A/KafkaMessagingAutoConfiguration.java \
| awk -F: &#x27;$1&gt;=126 &amp;&amp; $1&lt;=130&#x27; |</tspan><tspan x="24" dy="22"> sed -E &#x27;s#^([0-9]+): *# KafkaMessagingAutoConfiguration.java:\1 #&#x27;
cut_range $A/KafkaMessagingAutoConfiguration.java </tspan><tspan x="24" dy="22">KafkaMessagingAutoConfiguration.java 139 153
echo
grep -n &#x27;@Bean(name = &quot;kafkaSeamProducer&quot;\|@ConditionalOnMissingBean(n</tspan><tspan x="24" dy="22">ame&#x27; $B/KafkaSenderConfig.java \
| sed -E &#x27;s#^([0-9]+): *# KafkaSenderConfig.java:\1 #&#x27;
cut_range $B/KafkaSenderConf</tspan><tspan x="24" dy="22">ig.java KafkaSenderConfig.java 64 81 | grep -v &#x27;^ KafkaSenderConfig.java:7[0-6]&#x27;
echo
echo &quot;# security.protocol 을 넣</tspan><tspan x="24" dy="22">는 프로덕션 코드 — 상수명과 리터럴 양쪽으로&quot;
git grep -n &#x27;SECURITY_PROTOCOL\|&quot;security\.protocol&quot;\|SslConfigs\|SaslConf</tspan><tspan x="24" dy="22">igs\|CommonClientConfigs&#x27; -- &#x27;src/**/*.java&#x27; \
| grep &#x27;/main/&#x27; | strip
echo
echo &quot;# KafkaSecurityConfigurer.configure</tspan><tspan x="24" dy="22"> 가 자격 종류마다 하는 일&quot;
awk &#x27;NR&gt;=88 &amp;&amp; NR&lt;=115 &amp;&amp; (/properties.put\(/ || /case BrokerCredentialProfile/ || /throw new</tspan><tspan x="24" dy="22">/) {printf &quot; KafkaSecurityConfigurer.java:%d %s\n&quot;, NR, $0}&#x27; \
$K/KafkaSecurityConfigurer.java
echo
echo &quot;# 그 클래</tspan><tspan x="24" dy="22">스가 빈이 되기까지의 조건 사슬&quot;
awk &#x27;NR&gt;=105 &amp;&amp; NR&lt;=112 {printf &quot; KafkaMessagingAutoConfiguration.java:%d %s\n&quot;, NR, $0</tspan><tspan x="24" dy="22">}&#x27; $A/KafkaMessagingAutoConfiguration.java
git grep -n &#x27;ConditionalOnBean(CredentialProvider.class)\|CredentialRuntimeRe</tspan><tspan x="24" dy="22">gistry credentialRuntimeRegistry&#x27; -- &#x27;src/**/*.java&#x27; | strip
n=$(git grep -ln &#x27;implements CredentialProvider&#x27; -- &#x27;src/**</tspan><tspan x="24" dy="22">/*.java&#x27; | grep -c &#x27;/main/&#x27; || true)
echo &quot; CredentialProvider 를 구현하는 main 클래스 : $n 건&quot;
echo &quot; 그 인터페이스를</tspan><tspan x="24" dy="22"> 구현하는 자리 전부 :&quot;
git grep -n &#x27;implements CredentialProvider&#x27; -- &#x27;src/**/*.java&#x27; | strip
echo
echo &quot;# 그 빈을 파라</tspan><tspan x="24" dy="22">미터나 필드로 받는 코드 (빈을 만드는 팩토리 자신은 뺀다)&quot;
hits=$(git grep -n &#x27;KafkaSecurityConfigurer&#x27; -- &#x27;src/**/*.java</tspan><tspan x="24" dy="22">&#x27; \
| grep -v &#x27;/KafkaSecurityConfigurer.java:&#x27; \
| grep -v &#x27;public KafkaSecurityConfigurer kafkaSecurityConfigurer&#x27; </tspan><tspan x="24" dy="22">\
| grep -v &#x27;return new KafkaSecurityConfigurer&#x27; | grep -v &#x27;import &#x27; | grep &#x27;/main/&#x27; || true)
if [ -z &quot;$hits&quot; ]; then </tspan><tspan x="24" dy="22">echo &quot; main 에서 0 건&quot;; else echo &quot;$hits&quot; | strip; fi
echo &quot; getBean · ObjectProvider · 빈 이름 문자열로 가져가는 자</tspan><tspan x="24" dy="22">리 :&quot;
g=$(git grep -n &#x27;getBean(KafkaSecurityConfigurer\|ObjectProvider&lt;KafkaSecurityConfigurer&gt;\|&quot;kafkaSecurityConfigure</tspan><tspan x="24" dy="22">r&quot;&#x27; -- &#x27;src/**/*.java&#x27; || true)
if [ -z &quot;$g&quot; ]; then echo &quot; 0 건&quot;; else echo &quot;$g&quot; | strip; fi
echo
echo &quot;# 조립을 확</tspan><tspan x="24" dy="22">인하는 테스트가 단언하는 것과, 실 브로커 시험이 붙는 컨테이너&quot;
git grep -n &#x27;void selectingKafkaAssemblesOnlyKafka\|void </tspan><tspan x="24" dy="22">aSelectedTransportAssemblesAPublisher&#x27; -- &#x27;src/**/*.java&#x27; | strip
git grep -n &#x27;hasSingleBean\|doesNotHaveBean&#x27; -- &#x27;**/Me</tspan><tspan x="24" dy="22">ssagingStarterOffContractTest.java&#x27; | strip
git grep -n &#x27;new KafkaContainer(&#x27; -- &#x27;src/**/MessagingLiveRoundTripQualifica</tspan><tspan x="24" dy="22">tionTest.java&#x27; | strip
</tspan></text>
<text x="24" y="882" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">cwd: /shared/codebase/clean-architecture-backend-template</tspan></text>
<text x="24" y="904" fill="#8b949e" font-size="13" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0">time: 2026-09-03T12:25:08+00:00 · exit 0</tspan></text>
<line x1="24" y1="918" x2="1176" y2="918" stroke="#30363d"/>
<text x="24" y="958" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 운영 프로파일에 KafkaProfileValidator 가 거는 두 요구</tspan></text>
<text x="24" y="980" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:51 if (profile.production() &amp;&amp; !profile.tlsEnabled()) {</tspan></text>
<text x="24" y="1002" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:52 throw new IllegalArgumentException(</tspan></text>
<text x="24" y="1024" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:53 &quot;a production Kafka connection requires TLS: &quot; + profile.broker());</tspan></text>
<text x="24" y="1046" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:54 }</tspan></text>
<text x="24" y="1068" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:55 if (profile.production() &amp;&amp; !profile.authenticationEnabled()) {</tspan></text>
<text x="24" y="1090" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:56 throw new IllegalArgumentException(</tspan></text>
<text x="24" y="1112" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:57 &quot;a production Kafka connection requires broker authentication: &quot; + profile.broker());</tspan></text>
<text x="24" y="1134" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaProfileValidator.java:58 }</tspan></text>
<text x="24" y="1156" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1178" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 검증기가 기동에서 도는 경로와, 그 거부를 지키는 테스트</tspan></text>
<text x="24" y="1200" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · KafkaMessagingAutoConfiguration.java:55 kafkaProfileStartupValidation(</tspan></text>
<text x="24" y="1222" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · StartupProfileValidation.java:19 * &lt;p&gt;Validation runs as {@code afterPropertiesSet} rather than on an application eve</tspan><tspan x="24" dy="22">nt, so the</tspan></text>
<text x="24" y="1266" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · StartupProfileValidation.java:31 final class StartupProfileValidation&lt;T&gt; implements InitializingBean {</tspan></text>
<text x="24" y="1288" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · StartupProfileValidation.java:43 public void afterPropertiesSet() {</tspan></text>
<text x="24" y="1310" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingConfigurationBindingTest.java:235 void aProductionKafkaBrokerWithoutTransportSecurityFailsStartup() {</tspan></text>
<text x="24" y="1332" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1354" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 두 조립부를 켜는 프로퍼티</tspan></text>
<text x="24" y="1376" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingBridgeRootAutoConfiguration.java:21 @ConditionalOnProperty(prefix = &quot;app.messaging&quot;, name = &quot;enabled&quot;, having</tspan><tspan x="24" dy="22">Value = &quot;true&quot;)</tspan></text>
<text x="24" y="1420" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingAdminAutoConfiguration.java:27 @ConditionalOnProperty(prefix = &quot;app.messaging.admin&quot;, name = &quot;enabled&quot;, havin</tspan><tspan x="24" dy="22">gValue = &quot;true&quot;)</tspan></text>
<text x="24" y="1464" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingPlatformRootAutoConfiguration.java:28 @ConditionalOnProperty(prefix = MessagingSettings.PREFIX, name = &quot;enabl</tspan><tspan x="24" dy="22">ed&quot;, havingValue = &quot;true&quot;)</tspan></text>
<text x="24" y="1508" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingProviderSelection.java:48 &quot;kafka&quot;, KafkaMessagingAutoConfiguration.class,</tspan></text>
<text x="24" y="1530" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · KafkaSenderConfig.java:38 @ConditionalOnProperty(name = &quot;app.messaging.broker&quot;, havingValue = &quot;kafka&quot;)</tspan></text>
<text x="24" y="1552" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 출하 기본값 : application.yml:949: enabled: ${APP_MESSAGING_ENABLED:false}</tspan></text>
<text x="24" y="1574" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="1596" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 프로덕션에서 KafkaProducer 를 만드는 두 자리 — 설정 맵 원문 그대로</tspan></text>
<text x="24" y="1618" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:128 @Bean(destroyMethod = &quot;close&quot;)</tspan></text>
<text x="24" y="1640" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:129 @ConditionalOnMissingBean</tspan></text>
<text x="24" y="1662" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:139 java.util.Map&lt;String, Object&gt; config = new java.util.HashMap&lt;&gt;();</tspan></text>
<text x="24" y="1684" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:140 config.put(</tspan></text>
<text x="24" y="1706" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:141 org.apache.kafka.clients.producer.ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,</tspan></text>
<text x="24" y="1728" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:142 bootstrapServers);</tspan></text>
<text x="24" y="1750" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:143 config.put(</tspan></text>
<text x="24" y="1772" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:144 org.apache.kafka.clients.producer.ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,</tspan></text>
<text x="24" y="1794" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:145 org.apache.kafka.common.serialization.ByteArraySerializer.class);</tspan></text>
<text x="24" y="1816" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:146 config.put(</tspan></text>
<text x="24" y="1838" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:147 org.apache.kafka.clients.producer.ProducerConfig.VALUE_SERIALIZER_CLASS_CONFI</tspan><tspan x="24" dy="22">G,</tspan></text>
<text x="24" y="1882" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:148 org.apache.kafka.common.serialization.ByteArraySerializer.class);</tspan></text>
<text x="24" y="1904" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:149 // Durability is not a default worth inheriting: acks=1 loses an accepted publish</tspan><tspan x="24" dy="22"> to a leader</tspan></text>
<text x="24" y="1948" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:150 // failover, which is exactly the outcome an outbox exists to prevent.</tspan></text>
<text x="24" y="1970" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:151 config.put(org.apache.kafka.clients.producer.ProducerConfig.ACKS_CONFIG, &quot;all&quot;);</tspan></text>
<text x="24" y="1992" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:152 config.put(org.apache.kafka.clients.producer.ProducerConfig.ENABLE_IDEMPOTENCE_CO</tspan><tspan x="24" dy="22">NFIG, true);</tspan></text>
<text x="24" y="2036" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:153 return new org.apache.kafka.clients.producer.KafkaProducer&lt;&gt;(config);</tspan></text>
<text x="24" y="2058" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2080" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:61 @Bean(name = &quot;kafkaSeamProducer&quot;, destroyMethod = &quot;close&quot;)</tspan></text>
<text x="24" y="2102" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:62 @ConditionalOnMissingBean(name = &quot;kafkaSeamProducer&quot;)</tspan></text>
<text x="24" y="2124" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:64 Map&lt;String, Object&gt; config = new HashMap&lt;&gt;();</tspan></text>
<text x="24" y="2146" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:65 config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, String.join(&quot;,&quot;, settings.brokers()));</tspan></text>
<text x="24" y="2168" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:66 config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);</tspan></text>
<text x="24" y="2190" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:67 config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);</tspan></text>
<text x="24" y="2212" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:68 config.put(ProducerConfig.ACKS_CONFIG, &quot;all&quot;);</tspan></text>
<text x="24" y="2234" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:69 config.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true);</tspan></text>
<text x="24" y="2256" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:77 config.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 10_000);</tspan></text>
<text x="24" y="2278" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:78 config.put(ProducerConfig.LINGER_MS_CONFIG, 0);</tspan></text>
<text x="24" y="2300" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:79 config.put(ProducerConfig.REQUEST_TIMEOUT_MS_CONFIG, 15_000);</tspan></text>
<text x="24" y="2322" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:80 config.put(ProducerConfig.DELIVERY_TIMEOUT_MS_CONFIG, 30_000);</tspan></text>
<text x="24" y="2344" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSenderConfig.java:81 return new KafkaProducer&lt;&gt;(config);</tspan></text>
<text x="24" y="2366" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2388" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># security.protocol 을 넣는 프로덕션 코드 — 상수명과 리터럴 양쪽으로</tspan></text>
<text x="24" y="2410" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · KafkaSecurityConfigurer.java:32 public static final String SECURITY_PROTOCOL = &quot;security.protocol&quot;;</tspan></text>
<text x="24" y="2432" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · KafkaSecurityConfigurer.java:80 properties.put(SECURITY_PROTOCOL, securityProtocol(profile, credential));</tspan></text>
<text x="24" y="2454" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2476" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># KafkaSecurityConfigurer.configure 가 자격 종류마다 하는 일</tspan></text>
<text x="24" y="2498" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:90 case BrokerCredentialProfile.SaslScram scram -&gt; {</tspan></text>
<text x="24" y="2520" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:92 properties.put(SASL_MECHANISM, &quot;SCRAM-SHA-512&quot;);</tspan></text>
<text x="24" y="2542" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:93 properties.put(SASL_JAAS_CONFIG, scramJaas(scram.credentialId(), resolved));</tspan></text>
<text x="24" y="2564" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:95 case BrokerCredentialProfile.OAuth2 oauth -&gt; {</tspan></text>
<text x="24" y="2586" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:99 throw new dev.caskeleton.messaging.api.error.MessagingConfigurationException(</tspan></text>
<text x="24" y="2608" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:106 case BrokerCredentialProfile.MutualTls ignored -&gt; properties.put(SASL_MECHANISM, &quot;NONE&quot;</tspan><tspan x="24" dy="22">);</tspan></text>
<text x="24" y="2652" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:107 case BrokerCredentialProfile.UsernamePassword plain -&gt; {</tspan></text>
<text x="24" y="2674" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:109 properties.put(SASL_MECHANISM, &quot;PLAIN&quot;);</tspan></text>
<text x="24" y="2696" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:110 properties.put(SASL_JAAS_CONFIG, plainJaas(plain.credentialId(), resolved));</tspan></text>
<text x="24" y="2718" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:112 case BrokerCredentialProfile.Nkey ignored -&gt;</tspan></text>
<text x="24" y="2740" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaSecurityConfigurer.java:113 throw new IllegalArgumentException(</tspan></text>
<text x="24" y="2762" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="2784" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 클래스가 빈이 되기까지의 조건 사슬</tspan></text>
<text x="24" y="2806" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:105 @Bean</tspan></text>
<text x="24" y="2828" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:106 @ConditionalOnMissingBean</tspan></text>
<text x="24" y="2850" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:107 @org.springframework.boot.autoconfigure.condition.ConditionalOnBean(</tspan></text>
<text x="24" y="2872" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:108 CredentialRuntimeRegistry.class)</tspan></text>
<text x="24" y="2894" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:109 public KafkaSecurityConfigurer kafkaSecurityConfigurer(</tspan></text>
<text x="24" y="2916" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:110 CredentialRuntimeRegistry credentials, BrokerTlsPolicy tlsPolicy) {</tspan></text>
<text x="24" y="2938" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:111 return new KafkaSecurityConfigurer(credentials, tlsPolicy);</tspan></text>
<text x="24" y="2960" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> KafkaMessagingAutoConfiguration.java:112 }</tspan></text>
<text x="24" y="2982" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingCoreAutoConfiguration.java:315 @ConditionalOnBean(CredentialProvider.class)</tspan></text>
<text x="24" y="3004" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main · MessagingCoreAutoConfiguration.java:317 public CredentialRuntimeRegistry credentialRuntimeRegistry(CredentialProvide</tspan><tspan x="24" dy="22">r provider) {</tspan></text>
<text x="24" y="3048" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> CredentialProvider 를 구현하는 main 클래스 : 0 건</tspan></text>
<text x="24" y="3070" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 그 인터페이스를 구현하는 자리 전부 :</tspan></text>
<text x="24" y="3092" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · CredentialRuntimeRegistryTest.java:21 private static final class CountingProvider implements CredentialProvider {</tspan></text>
<text x="24" y="3114" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="3136" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 그 빈을 파라미터나 필드로 받는 코드 (빈을 만드는 팩토리 자신은 뺀다)</tspan></text>
<text x="24" y="3158" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> main 에서 0 건</tspan></text>
<text x="24" y="3180" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> getBean · ObjectProvider · 빈 이름 문자열로 가져가는 자리 :</tspan></text>
<text x="24" y="3202" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> 0 건</tspan></text>
<text x="24" y="3224" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"></tspan></text>
<text x="24" y="3246" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"># 조립을 확인하는 테스트가 단언하는 것과, 실 브로커 시험이 붙는 컨테이너</tspan></text>
<text x="24" y="3268" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingStarterOffContractTest.java:118 void selectingKafkaAssemblesOnlyKafka() {</tspan></text>
<text x="24" y="3290" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingStarterOffContractTest.java:172 void aSelectedTransportAssemblesAPublisher() {</tspan></text>
<text x="24" y="3312" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingStarterOffContractTest.java:127 assertThat(context).hasSingleBean(KafkaMessagingAutoConfigurati</tspan><tspan x="24" dy="22">on.class);</tspan></text>
<text x="24" y="3356" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingStarterOffContractTest.java:130 .doesNotHaveBean(RabbitMessagingAutoConfiguration.class);</tspan></text>
<text x="24" y="3378" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingStarterOffContractTest.java:189 assertThat(context).hasSingleBean(MessagePublisher.class);</tspan></text>
<text x="24" y="3400" fill="#e6edf3" font-size="14" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" xml:space="preserve"><tspan x="24" dy="0"> test · MessagingLiveRoundTripQualificationTest.java:66 @Container static final KafkaContainer KAFKA = new KafkaContainer(&quot;a</tspan><tspan x="24" dy="22">pache/kafka:4.1.0&quot;);</tspan></text>
</svg>