Files
document-haness/docs/clean-architecture-backend-template/final/evidence/raw/260-messaging-admin-plane-assembly.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

82 lines
3.4 KiB
Plaintext

# evidence 260 — messaging-admin-plane-assembly
# revision: a24ece9cf797f7ea647e33bf846b115208ed1ba5
# cwd: /shared/codebase/clean-architecture-backend-template/src/messaging
# command: grep -vE "^import " messaging-spring-boot-starter/src/main/java/dev/caskeleton/messaging/autoconfigure/MessagingAdminAutoConfiguration.java
# ---- raw output ----
package dev.caskeleton.messaging.autoconfigure;
/**
* Wires the admin plane, and only when a deployment has explicitly asked for it.
*
* <p>Off unless {@code app.messaging.admin.enabled=true}. An application that acquires the admin
* plane by adding a starter to its classpath is exactly the situation the plane's guards exist to
* prevent — the guards would still refuse an unapproved operation, but the beans would be reachable
* from any code in the process.
*
* <p>{@link dev.caskeleton.messaging.admin.runtime.DestructiveMessagingAdmin} is deliberately
* absent from this class. No bean for it is ever auto-configured: an operator tool that needs purge
* or delete registers one itself, with an admin credential this runtime does not hold.
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "app.messaging.admin", name = "enabled", havingValue = "true")
public class MessagingAdminAutoConfiguration {
/**
* Returns the guard that authorises non-destructive admin operations.
*
* @return the guard
*/
@Bean
@ConditionalOnMissingBean
public DestructiveOperationGuard destructiveOperationGuard() {
// false: an application runtime never holds an admin credential, so the guard refuses the
// operations that would need one. An operator tool overrides this bean with true.
return new DestructiveOperationGuard(false);
}
/**
* Returns a single-process journal so a development runtime starts without extra wiring.
*
* <p>It declares itself non-durable, and {@link MessagingAdminDurabilityValidator} refuses to let
* a production profile start on it. That pairing is deliberate: the convenient default stays
* convenient for local work and becomes a startup failure — naming what to supply — the moment
* the deployment claims to be production. The previous default was an indistinguishable {@code
* ConcurrentHashMap} that silently let two replicas execute the same approval.
*
* @return the in-memory journal
*/
@Bean
@ConditionalOnMissingBean
public AdminOperationJournal adminOperationJournal() {
return new InMemoryAdminOperationJournal();
}
/**
* Returns the validator that refuses a production profile on a non-durable journal.
*
* @param journal the journal in use
* @param environment the Spring environment
* @return the validator
*/
@Bean
@ConditionalOnMissingBean
public MessagingAdminDurabilityValidator messagingAdminDurabilityValidator(
AdminOperationJournal journal, org.springframework.core.env.Environment environment) {
return new MessagingAdminDurabilityValidator(journal, environment);
}
/**
* Returns the topology validator, when the application supplied a broker inspector.
*
* @param inspector reads the broker's current topology
* @return the composite validator
*/
@Bean
@ConditionalOnBean(BrokerTopologyInspector.class)
@ConditionalOnMissingBean
public CompositeTopologyValidator compositeTopologyValidator(BrokerTopologyInspector inspector) {
return new CompositeTopologyValidator(inspector);
}
}