Sub-scope 09 (mongo) security + failure + observation + client - manifest and probes revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5 generatedAt=2026-08-30T00:22:02+00:00 cwd=/shared/codebase/clean-architecture-backend-template/src === OWNED FILES === 70bb70e58ac29b6c1401715556b3bc999ecdde08 main/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactory.java 122 bd752d8017c85a8a179ec33f6bcac31a191938d2 main/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureClassifier.java 165 078eb6624daee4e12077317fe7f0f40c1484583f main/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureTranslator.java 136 42607f5e5692a704b40fb16f8e8deef7bc4eca8d main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoDriverFailureView.java 96 305db8f20852d5d4a5b31e6bd9e5a563113f0a4e main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureClassification.java 84 fa7ee1fdb4d8b87db62636665e163d6efa54ade3 main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureClassifier.java 30 c97bee6755b406ce235b0db2f1ddafd5b43a8ad7 main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureExtractor.java 63 68f7019d768d09bab77c4062d58011f9a3072517 main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailurePhase.java 41 247affc2e97d358eec04ebe39096e749afc74e62 main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureTranslator.java 32 cb66127e79ac161b23cbf8397da1fb23eaf1f2cc main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java 104 d58c2b1109ea4c6d3b37a84048c1baded4c0e23f main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoCommandObservationListener.java 72 6833f38c54a5a82ab91515c7f1706d9436771525 main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java 43 95d47f6c83dfba0486a290c12061062e10e4139a main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java 76 b31b95daae98c9d222b03def13571c20b567fe3b main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationRedactor.java 48 862d03f5a8c6df8a6edf80b61dc19cab616e7004 main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoPoolObservationListener.java 79 da98d619400a5428052ebffb23918ed829b7eedb main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoSdamObservationListener.java 76 1eefc12534906eb0a5fe89f5f3679e5b0154073a main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialReference.java 74 c2630cf7b6e8e81348ab1e38337b9ad2d743ad5e main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialResolver.java 43 07772c4569a6e77a17f172a688c2c9ae385d3ade main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java 50 97e58d6d456edf916972c8cdc6f96f65ad74f605 main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoPrincipalRole.java 63 ff75d970bf3da211faa9ca538dd11ae8834ac76c main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java 54 5966a708bf8282bc8a1d1734978e16caaddf5ee1 main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidator.java 69 7e3139a9e13624b6640938d0cf316819f464386c main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminApproval.java 57 416ae3c05c952d61268619061f066000964c6ec6 main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditPhase.java 21 4ce978358da0817f3f4c89392e3ba2c1f348c717 main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditRecord.java 103 365d9d2a76e8da168df5e4b6c3ae5b444315fc2f main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuthorization.java 58 b0e6c2311cd23484f1694797e6dca247440d245d main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminCommand.java 103 3f7a8e9e0ea5e0921c87ef9d5cd10863acbac1dd main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminGateway.java 155 bb4c1d808aac7a9db42f3faf73fbb848ad4462bc main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminOperation.java 69 2ea0b6961acfdaffa37d6f2c4ed1ae41b407efb1 main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuard.java 58 c669128d19905192760fa6461e382e803b171466 test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java 155 8cade411549e57554ef2af67d8c4a75d0edc7b8e test/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureClassifierTest.java 85 31cfe2e045e67d31200371cb577c1027756872e8 test/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureExtractorTest.java 85 c3c0bedd5f340edde465bdae5531be9550b9f16e test/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailurePhaseClassificationTest.java 114 9cd42c63fc963e16f864877619d7bda9f2dbdb71 test/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoNetworkFaultLaneTest.java 206 8fd453d853874984528c4ddfea935bd63c481ed3 test/java/dev/caskeleton/adapter/outbound/mongo/failure/TranslatorCarriesOperationContextTest.java 70 ec8897a4907ed8bfd3209d83beb030d1c5446ce4 test/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConventionTest.java 67 355d56a96e8c76c519b6239bcd39e67f30ccf867 test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialIdentityTest.java 108 64f8ff90b050f7347dd58bf2e7d21e672d5d41a2 test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoProductionSecurityContractTest.java 176 48ddb5c88db513fed1666dea0b712cf6d11615d7 test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityIntegrationLaneTest.java 173 bd76cc9d30bd033639a5911c9f965838c7784ecb test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidatorTest.java 115 3ca3a9db79b2f5ff033b25d659da79850d39c4b2 test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoTlsLaneTest.java 164 9ab88fab1970f5bbdcc009269b0de14188701e21 test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditStateMachineTest.java 250 e080d8c0e10b9ee0999c0170fdd0e2a4457d80cf test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuardTest.java 117 production: 30 test: 14 production LOC: 2244 total === 8.1 reachability: what the auto-configuration builds from these four packages === $ grep -n 'ClientSettings\|CredentialResolver\|SecurityProfile\|FailureTranslator\|FailureClassifier\|Observ\|Redactor\|AdminGateway' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java 5:import dev.caskeleton.adapter.outbound.mongo.api.observation.MongoOperationObserver; 6:import dev.caskeleton.adapter.outbound.mongo.failure.DefaultMongoFailureClassifier; 7:import dev.caskeleton.adapter.outbound.mongo.failure.DefaultMongoFailureTranslator; 8:import dev.caskeleton.adapter.outbound.mongo.failure.MongoFailureClassifier; 9:import dev.caskeleton.adapter.outbound.mongo.failure.MongoFailureTranslator; 14:import dev.caskeleton.adapter.outbound.mongo.observation.MicrometerMongoOperationObserver; 85: public MongoFailureClassifier mongoFailureClassifier() { 86: return new DefaultMongoFailureClassifier(); 92: public MongoFailureTranslator mongoFailureTranslator(MongoFailureClassifier classifier) { 93: return new DefaultMongoFailureTranslator(classifier); 104: public MongoOperationObserver mongoOperationObserver(ObjectProvider registries) { 107: ? MongoOperationObserver.none() 108: : new MicrometerMongoOperationObserver(registry, "default"); 117: MongoFailureTranslator translator, 118: MongoOperationObserver observer) { 298: MongoFailureTranslator translator, 299: MongoOperationObserver observer) { 335: ObjectProvider exit=0 === 8.1b does the platform actually build the driver client from its own factory? === $ git grep -n 'MongoClientSettingsFactory' -- 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactory.java:38:public final class MongoClientSettingsFactory { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactory.java:51: public MongoClientSettingsFactory( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:28:class MongoClientSettingsFactoryTest { adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:38: new MongoClientSettingsFactory( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:60: new MongoClientSettingsFactory( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:74: new MongoClientSettingsFactory( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:95: new MongoClientSettingsFactory(settings, ACTIVE, resolver(resolved)).create(); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:110: new MongoClientSettingsFactory( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/client/MongoClientSettingsFactoryTest.java:120: new MongoClientSettingsFactory( exit=0 $ git grep -n 'MongoClientSettings\|MongoClient\b\|MongoClients' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/client/MongoClientSettingsFactory.java' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:8:import org.springframework.boot.mongodb.autoconfigure.MongoClientSettingsBuilderCustomizer; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:15: * settings builder, and nothing ever called it. Boot builds the {@code MongoClient} from its own adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:38: public MongoClientSettingsBuilderCustomizer mongoDriverObservabilityCustomizer( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/nativecap/MongoNativeCapabilityGateway.java:6: *

There is no {@code MongoClient}, {@code MongoDatabase} or {@code MongoCollection} adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:3:import com.mongodb.MongoClientSettings; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:26: public MongoClientSettings.Builder apply(MongoClientSettings.Builder builder) { exit=0 $ git grep -rn 'MongoClientSettingsFactory\|MongoCredentialResolver' -- '../app-bootstrap' '../adapter' 2>/dev/null | grep -v persistence-mongo | head exit=0 === 8.1c are the driver observability listeners ever installed? === $ git grep -n 'MongoDriverObservabilityConfiguration' -- 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:3:import dev.caskeleton.adapter.outbound.mongo.observation.MongoDriverObservabilityConfiguration; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:14: *

{@link MongoDriverObservabilityConfiguration} could add command, SDAM and pool listeners to a adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:45: MongoDriverObservabilityConfiguration observability = adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java:46: new MongoDriverObservabilityConfiguration(registry, profile); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:14:public final class MongoDriverObservabilityConfiguration { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:20: public MongoDriverObservabilityConfiguration(MeterRegistry registry, String mongoProfile) { adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityWiringTest.java:19: *

{@code MongoDriverObservabilityConfiguration} could attach command, SDAM and pool listeners to exit=0 $ git grep -n 'MongoCommandObservationListener\|MongoSdamObservationListener\|MongoPoolObservationListener' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/observation/' exit=1 $ git grep -n 'addCommandListener\|addClusterListener\|addConnectionPoolListener' -- 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:28: builder.addCommandListener(new MongoCommandObservationListener(registry, mongoProfile)); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:31: cluster.addClusterListener(new MongoSdamObservationListener(registry, mongoProfile))); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:34: pool.addConnectionPoolListener( exit=0 === 8.1d is the security profile validator called at startup? === $ git grep -n 'MongoSecurityProfileValidator\|MongoSecurityProfile\b\|requireDistinctCredentials' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:335: ObjectProvider adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:9:import dev.caskeleton.adapter.outbound.mongo.security.MongoSecurityProfile; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:10:import dev.caskeleton.adapter.outbound.mongo.security.MongoSecurityProfileValidator; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:28: private final MongoSecurityProfile runtimeSecurity; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:41: MongoSecurityProfile runtimeSecurity, adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:62: new MongoSecurityProfileValidator().validate(runtimeSecurity); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:117: new MongoSecurityProfileValidator() adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java:118: .requireDistinctCredentials(runtimeSecurity.credential(), admin)); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialReference.java:46: * MongoSecurityProfileValidator#requireDistinctCredentials}, is always called with a runtime role adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:13:public record MongoSecurityProfile( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:20: public MongoSecurityProfile { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:27: public static MongoSecurityProfile production( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:29: return new MongoSecurityProfile( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:38: public static MongoSecurityProfile production( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:40: return new MongoSecurityProfile(true, true, true, credential, grantedPrivileges); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:44: public static MongoSecurityProfile local(MongoCredentialReference credential) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfile.java:45: return new MongoSecurityProfile(false, false, false, credential, Set.of()); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidator.java:14:public final class MongoSecurityProfileValidator { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidator.java:21: public void validate(MongoSecurityProfile profile) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidator.java:57: public void requireDistinctCredentials( exit=0 $ git grep -n 'MongoCredentialRotationPolicy\|validateRotation' -- 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationRegistry.java:5:import dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationRegistry.java:31: private final MongoCredentialRotationPolicy rotationPolicy; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationRegistry.java:35: public MongoClientGenerationRegistry(MongoCredentialRotationPolicy rotationPolicy, Clock clock) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationRegistry.java:68: rotationPolicy.validateRotation(existing.credential(), replacement); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:417: dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy.class) adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:419: dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy rotationPolicy, adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialReference.java:51: * MongoCredentialRotationPolicy} always knew that: it compares roles on its own line, right after adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java:14:public record MongoCredentialRotationPolicy(Duration drainTimeout, boolean failClosedOnOverlap) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java:16: public MongoCredentialRotationPolicy { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java:24: public static MongoCredentialRotationPolicy standard() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java:25: return new MongoCredentialRotationPolicy(Duration.ofSeconds(30), true); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialRotationPolicy.java:34: public void validateRotation( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationConcurrencyTest.java:8:import dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy; adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoClientGenerationConcurrencyTest.java:43: new MongoClientGenerationRegistry(MongoCredentialRotationPolicy.standard(), FIXED); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformPropertiesTest.java:13:import dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy; adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformPropertiesTest.java:136: MongoCredentialRotationPolicy.standard(), adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformPropertiesTest.java:156: MongoCredentialRotationPolicy.standard(), adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/RotationOrderingTest.java:8:import dev.caskeleton.adapter.outbound.mongo.security.MongoCredentialRotationPolicy; adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/RotationOrderingTest.java:41: new MongoClientGenerationRegistry(MongoCredentialRotationPolicy.standard(), FIXED); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialIdentityTest.java:21: *

{@code MongoCredentialRotationPolicy} is the counter-evidence that the role was never meant to adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialIdentityTest.java:90: new MongoCredentialRotationPolicy(java.time.Duration.ofSeconds(30), true) adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialIdentityTest.java:91: .validateRotation( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidatorTest.java:101: MongoCredentialRotationPolicy policy = MongoCredentialRotationPolicy.standard(); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidatorTest.java:105: assertThatThrownBy(() -> policy.validateRotation(current, current)) adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/MongoSecurityProfileValidatorTest.java:109: policy.validateRotation( exit=0 === 8.2 the observation allowlist: enforced by code, or only asserted by a test? === $ git grep -n 'requireAllowed\|allowedTagNames\|forbiddenTagNames\|MongoObservationConvention' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/search/MongoSearchQuery.java:48: public void requireAllowedPaths(Set allowedPaths) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/sharding/ShardAwareQueryValidator.java:59: public MongoRoutingClassification requireAllowedRead( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/MongoAggregationProfile.java:86: public void requireAllowed(MongoAggregationStageDescriptor descriptor) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/aggregation/PolicyAwareMongoAggregationExecutor.java:49: plan.stages().forEach(profile::requireAllowed); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:40: public MongoObservationConvention convention() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoDriverObservabilityConfiguration.java:41: return MongoObservationConvention.standard(); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:17:public final class MongoObservationConvention { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:44: private MongoObservationConvention() {} adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:47: public static MongoObservationConvention standard() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:48: return new MongoObservationConvention(); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:52: public Set allowedTagNames() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:57: public Set forbiddenTagNames() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoObservationConvention.java:66: public void requireAllowed(String tagName) { exit=0 $ grep -n 'Tags.of' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/*.java adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:46: Tags.of( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:72: this.outcomeTags = Tags.of("result", "unknown", "failureCategory", "none"); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:77: outcomeTags = Tags.of("result", outcome.name(), "failureCategory", "none"); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:83: Tags.of( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoCommandObservationListener.java:63: Tags.of( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoPoolObservationListener.java:40: Tags tags = Tags.of("mongoProfile", mongoProfile); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoPoolObservationListener.java:60: .tags(Tags.of("mongoProfile", mongoProfile, "failureCategory", event.getReason().name())) adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoSdamObservationListener.java:46: .tags(Tags.of("mongoProfile", mongoProfile)) adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MongoSdamObservationListener.java:61: .tags(Tags.of("mongoProfile", mongoProfile)) exit=0 $ git grep -n 'redactor.describe\|\.describe(' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/api/error/MongoPersistenceException.java:24: summary + " [" + Objects.requireNonNull(failureContext, "failureContext").describe() + "]"); exit=0 === 8.2b the admin gateway's two audit paths === $ grep -n 'private void audit' -A 12 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminGateway.java 127: private void audit(MongoAdminAuditRecord record) { 128- try { 129- auditSink.accept(record); 130- } catch (RuntimeException sinkFailed) { 131- throw MongoOperationRejectedException.of( 132- "admin.audit", 133- "the admin audit sink refused the " 134- + record.phase() 135- + " record; an administrative operation that cannot be audited does not run"); 136- } 137- } 138- 139- /** exit=0 $ grep -n 'public void dryRun' -A 8 adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminGateway.java 145: public void dryRun(MongoAdminOperation operation, String target, String operator, String reason) { 146- authorization.require(operation); 147- auditSink.accept( 148- MongoAdminAuditRecord.dryRun(operation, target, operator, reason, clock.instant())); 149- } 150- 151- /** The guard this gateway was constructed under. */ 152- public MongoAdminRuntimeGuard guard() { 153- return guard; exit=0 === 8.2c traceId === $ grep -rn 'traceId' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/api/observation/MongoOperationObservation.java adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/api/observation/MongoOperationObservation.java:22: String traceId(); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:91: public String traceId() { exit=0 $ git grep -n 'traceId()' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/api/observation/MongoOperationObservation.java:22: String traceId(); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/api/observation/NoOpMongoOperationObserver.java:42: public String traceId() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/imperative/DefaultMongoImperativeExecutor.java:129: observation.failure(translated.failureContext().withTraceId(observation.traceId())); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/observation/MicrometerMongoOperationObserver.java:91: public String traceId() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/reactive/DefaultReactiveMongoExecutor.java:169: observation.failure(translated.failureContext().withTraceId(observation.traceId())); exit=0 === 8.3 duplicate / unused mechanisms === $ git grep -n 'unrecognisedServerCode\|MongoFailureClassification.nonRetryable\|classify(failure)' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureClassifier.java:139: return MongoFailureClassification.nonRetryable(category); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureClassification.java:57: public static MongoFailureClassification nonRetryable(MongoFailureCategory category) { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureClassification.java:70: public static MongoFailureClassification unrecognisedServerCode() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureClassifier.java:28: return classify(failure); exit=0 $ git grep -n 'MongoAdminAuditRecord.applied\|adminGatewayAllowed\|MongoAdminApproval.of' -- 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminApproval.java:31: public static MongoAdminApproval of( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditRecord.java:98: public static MongoAdminAuditRecord applied( adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuard.java:55: public boolean adminGatewayAllowed() { adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditStateMachineTest.java:138: MongoAdminApproval.of(rehearsal, "approver", NOW.plus(Duration.ofMinutes(10))); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditStateMachineTest.java:157: MongoAdminApproval.of(approved, "approver", NOW.plusSeconds(600)), adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditStateMachineTest.java:167: MongoAdminApproval approval = MongoAdminApproval.of(command, "approver", NOW.plusSeconds(600)); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminAuditStateMachineTest.java:187: MongoAdminApproval.of(command, "approver", NOW.minusSeconds(1)), adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuardTest.java:48: assertThat(guard.adminGatewayAllowed()).isTrue(); adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuardTest.java:101: MongoAdminAuditRecord.applied( adapter/outbound/persistence-mongo/src/test/java/dev/caskeleton/adapter/outbound/mongo/security/admin/MongoAdminRuntimeGuardTest.java:106: MongoAdminAuditRecord.applied( exit=0 $ git grep -n 'MongoFailureExtractor' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureExtractor.java:21:public final class MongoFailureExtractor { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/MongoFailureExtractor.java:26: private MongoFailureExtractor() {} adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringMongoTransactionSessionFactory.java:22:import dev.caskeleton.adapter.outbound.mongo.failure.MongoFailureExtractor; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringMongoTransactionSessionFactory.java:225: MongoDriverFailureView view = MongoFailureExtractor.viewOf(failure).orElse(null); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringReactiveMongoTransactionSessionFactory.java:21:import dev.caskeleton.adapter.outbound.mongo.failure.MongoFailureExtractor; adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringReactiveMongoTransactionSessionFactory.java:176: MongoDriverFailureView view = MongoFailureExtractor.viewOf(failure).orElse(null); exit=0 $ git grep -n 'DefaultMongoFailureTranslator.standard\|new DefaultMongoFailureTranslator\|new DefaultMongoFailureClassifier' -- 'adapter/outbound/persistence-mongo/src/main' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:86: return new DefaultMongoFailureClassifier(); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java:93: return new DefaultMongoFailureTranslator(classifier); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureTranslator.java:46: public static DefaultMongoFailureTranslator standard() { adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/failure/DefaultMongoFailureTranslator.java:47: return new DefaultMongoFailureTranslator(new DefaultMongoFailureClassifier()); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringMongoTransactionSessionFactory.java:52: this(template, consistency, new DefaultMongoFailureClassifier()); adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/transaction/SpringReactiveMongoTransactionSessionFactory.java:53: this(template, consistency, new DefaultMongoFailureClassifier()); exit=0 === 8.4 lane / documentation drift === $ grep -n 'lane(' adapter/outbound/persistence-mongo/build.gradle 107: lane('mongoReplicaSetTest') { 113: lane('mongoFailoverTest') { 119: lane('mongoMigrationTest') { 125: lane('mongoCompatibilityTest') { 130: lane('mongoSecurityIntegrationTest') { 139: lane('mongoPerformanceTest') { exit=0 $ grep -n 'mongodb-security-integration\|mongodb-failover' adapter/outbound/persistence-mongo/build.gradle 96: 'mongodb-failover', 99: 'mongodb-security-integration' 114: tag = 'mongodb-failover' 131: tag = 'mongodb-security-integration' exit=0 === 8.1e REPO-WIDE: who builds the MongoClient, and is the platform factory reachable? === $ git grep -rn 'MongoClientSettingsFactory' -- . | grep -v 'adapter/outbound/persistence-mongo/src' exit=1 $ git grep -rln 'MongoCredentialResolver' -- . | grep -v 'adapter/outbound/persistence-mongo/src' adapter/outbound/persistence-mongo/CLAUDE.md exit=0 $ git grep -rn 'spring.data.mongodb.uri\|spring.mongodb.uri' -- . | head -20 adapter/outbound/persistence-mongo/README.md:37:spring.data.mongodb.uri=mongodb://localhost:27017/portfolio adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/MongoPersistenceSettings.java:10: * own standard {@code spring.mongodb.uri} (owned by Spring Boot's {@code MongoProperties}), which adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/security/MongoCredentialResolver.java:11: * spring.mongodb.uri}, which is an ordinary property — in configuration, in the image and in every exit=0 $ cat adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoDriverObservabilityAutoConfiguration.java package dev.caskeleton.adapter.outbound.mongo.autoconfigure; import dev.caskeleton.adapter.outbound.mongo.observation.MongoDriverObservabilityConfiguration; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.mongodb.autoconfigure.MongoClientSettingsBuilderCustomizer; import org.springframework.context.annotation.Bean; /** * Attaches the driver's observation listeners to the client Boot builds. * *

{@link MongoDriverObservabilityConfiguration} could add command, SDAM and pool listeners to a * settings builder, and nothing ever called it. Boot builds the {@code MongoClient} from its own * customizers, so the listeners were a method with no caller: the pool-checkout, server-selection * and primary-change metrics the operations documentation refers to were never emitted. * *

Separate from {@code MongoPlatformAutoConfiguration} because it is conditional on something * else — a {@link MeterRegistry}. A listener with nowhere to publish costs work on every command, * so a deployment without metrics gets no listeners rather than silent ones. * *

These tag by driver event. The platform's own observation tags by operation. The two measure * different things on purpose, and neither is derived from the other, so a command appears once in * each rather than twice in one. */ @org.springframework.context.annotation.Configuration(proxyBeanMethods = false) @ConditionalOnProperty( prefix = "ca-skeleton.persistence-mongo", name = "enabled", havingValue = "true") public class MongoDriverObservabilityAutoConfiguration { /** The customizer Boot applies when it builds the client. */ @Bean @ConditionalOnBean(MeterRegistry.class) @ConditionalOnMissingBean(name = "mongoDriverObservabilityCustomizer") public MongoClientSettingsBuilderCustomizer mongoDriverObservabilityCustomizer( MeterRegistry registry, org.springframework.beans.factory.ObjectProvider properties) { String profile = properties.getIfAvailable(MongoPlatformSettings::empty).profiles().keySet().stream() .findFirst() .orElse("default"); MongoDriverObservabilityConfiguration observability = new MongoDriverObservabilityConfiguration(registry, profile); return observability::apply; } } exit=0 $ sed -n '325,375p' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java * first transaction. * *

Conditional on a {@link MongoTopologyProbe} bean, because the check is about the server this * deployment actually talks to, and only a composition root knows how to reach it. */ @Bean @ConditionalOnBean(MongoTopologyProbe.class) public InitializingBean mongoPlatformStartupCheck( MongoPlatformSettings properties, MongoTopologyProbe probe, ObjectProvider runtimeSecurity, ObjectProvider adminCredential, ObjectProvider schemaVersionRange) { return () -> { properties.validate(); var security = runtimeSecurity.getIfAvailable(); var admin = adminCredential.getIfAvailable(); var versions = schemaVersionRange.getIfAvailable(); if (security == null || admin == null || versions == null) { // Fail closed rather than validate a subset. A partial startup check reports success for // the parts nobody supplied, which is the shape the missing wiring already had. throw new IllegalStateException( "the Mongo platform is enabled and a topology probe is present, but the security" + " profile, admin credential reference or schema version range is not configured;" + " the startup validator cannot answer with only part of its inputs"); } new MongoStartupValidator( properties, probe, security, admin, // From settings, not literals. These were `true, true`, which told the validator that // transactions and change streams were both wanted whatever the deployment had // configured — and then validated the topology against that invented answer. properties.transactions(), properties.changeStreams(), versions) .validate(); }; } /** * Refuses a platform that is on with no way to look at the server it talks to (MNG-INT-003). * *

{@code mongoPlatformStartupCheck} above is conditioned on a {@link MongoTopologyProbe}, * which is right — the check is about the live server, and only a composition root knows how to * reach it. But a condition is also an exit: a deployment that enables the platform and supplies * no probe got no validation at all, silently, and not supplying a bean is exactly what an exit=0 $ sed -n '55,70p;110,125p' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoStartupValidator.java /** * Runs every startup check. * * @throws MongoOperationRejectedException naming the first failed condition */ public void validate() { properties.validate(); new MongoSecurityProfileValidator().validate(runtimeSecurity); requireDeclaredTopologyMatchesReality(); requireCapabilitiesForEnabledFeatures(); requireDistinctAdminCredential(); requireSupportedSchemaRange(); } private void requireDeclaredTopologyMatchesReality() { properties } } private void requireDistinctAdminCredential() { Optional.ofNullable(adminCredential) .ifPresent( admin -> new MongoSecurityProfileValidator() .requireDistinctCredentials(runtimeSecurity.credential(), admin)); } private void requireSupportedSchemaRange() { if (schemaVersionRange.minimumSupported().compareTo(schemaVersionRange.current()) > 0) { throw MongoOperationRejectedException.of( "startup.schema", "the configured schema version range is inverted"); } exit=0 === 8.1f the four AutoConfiguration entries this leaf registers === $ cat adapter/outbound/persistence-mongo/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports dev.caskeleton.adapter.outbound.mongo.MongoRootAutoConfiguration exit=0