{ "assetKey": "a06-f018-changestreams-false-wiring", "kind": "terminal", "command": "set -e\nD=$(mktemp -d)\ntrap 'rm -rf \"$D\"' EXIT\n\nprintf %s '' > \"$D/logback-off.xml\"\n\ncat > \"$D/ChangeStreamWiringProbe.java\" <<'JAVA'\nimport static org.mockito.Mockito.mock;\n\nimport com.mongodb.client.MongoClients;\nimport dev.caskeleton.adapter.outbound.mongo.api.consistency.MongoConsistencyRegistry;\nimport dev.caskeleton.adapter.outbound.mongo.api.observation.MongoOperationObserver;\nimport dev.caskeleton.adapter.outbound.mongo.autoconfigure.MongoPlatformAutoConfiguration;\nimport dev.caskeleton.adapter.outbound.mongo.autoconfigure.MongoPlatformSettings;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.MongoChangeStreamSubscription;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.MongoResumeCheckpointStore;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.MongoResumeTokenCodec;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.consumer.MongoChangeStreamSource;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.consumer.ReactiveMongoChangeStreamConsumer;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.projector.MongoChangeDeduplicationStore;\nimport dev.caskeleton.adapter.outbound.mongo.changestream.projector.MongoChangeProjector;\nimport dev.caskeleton.adapter.outbound.mongo.failure.MongoFailureTranslator;\nimport dev.caskeleton.adapter.outbound.mongo.imperative.MongoCollectionProfileRegistry;\nimport org.springframework.boot.autoconfigure.AutoConfigurations;\nimport org.springframework.boot.test.context.assertj.AssertableApplicationContext;\nimport org.springframework.boot.test.context.runner.ApplicationContextRunner;\nimport org.springframework.data.mongodb.core.MongoTemplate;\nimport org.springframework.data.mongodb.core.ReactiveMongoTemplate;\nimport org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;\nimport org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;\n\npublic final class ChangeStreamWiringProbe {\n\n private static final String ENABLED = \"ca-skeleton.persistence-mongo.enabled=true\";\n private static final String FLAG = \"ca-skeleton.persistence-mongo.platform.change-streams=true\";\n\n /** The whole auto-configuration, not the nested class: the flag lives on the outer one. */\n private static final ApplicationContextRunner BASE =\n new ApplicationContextRunner()\n .withConfiguration(AutoConfigurations.of(MongoPlatformAutoConfiguration.class))\n .withBean(MongoTemplate.class, ChangeStreamWiringProbe::blocking)\n .withBean(MongoConsistencyRegistry.class, MongoConsistencyRegistry::standard)\n .withBean(\n MongoCollectionProfileRegistry.class,\n () -> MongoCollectionProfileRegistry.builder().register(\"events\", \"events\").build())\n .withBean(MongoFailureTranslator.class, () -> mock(MongoFailureTranslator.class))\n .withBean(MongoOperationObserver.class, () -> mock(MongoOperationObserver.class));\n\n public static void main(String[] args) {\n System.out.println(\"[모듈 opt-in 없이]\");\n report(\"기본 \", BASE.withBean(ReactiveMongoTemplate.class,\n ChangeStreamWiringProbe::reactive));\n System.out.println();\n\n ApplicationContextRunner on = BASE.withPropertyValues(ENABLED);\n System.out.println(\"[opt-in, 리액티브 템플릿만]\");\n report(\"기본 \", on.withBean(ReactiveMongoTemplate.class,\n ChangeStreamWiringProbe::reactive));\n report(\"change-streams=true \", on.withBean(ReactiveMongoTemplate.class,\n ChangeStreamWiringProbe::reactive).withPropertyValues(FLAG));\n System.out.println();\n\n System.out.println(\"[opt-in, 배포가 공급해야 하는 다섯을 함께]\");\n report(\"기본 \", withFive(on.withBean(ReactiveMongoTemplate.class,\n ChangeStreamWiringProbe::reactive)));\n report(\"change-streams=true \", withFive(on.withBean(ReactiveMongoTemplate.class,\n ChangeStreamWiringProbe::reactive)).withPropertyValues(FLAG));\n System.out.println();\n\n System.out.println(\"[opt-in, 리액티브 템플릿 없이]\");\n report(\"기본 \", on);\n System.exit(0);\n }\n\n private static ApplicationContextRunner withFive(ApplicationContextRunner runner) {\n return runner\n .withBean(MongoChangeStreamSubscription.class,\n () -> MongoChangeStreamSubscription.of(\"probe\", \"events\"))\n .withBean(MongoResumeCheckpointStore.class, () -> mock(MongoResumeCheckpointStore.class))\n .withBean(MongoResumeTokenCodec.class, () -> mock(MongoResumeTokenCodec.class))\n .withBean(MongoChangeProjector.class, () -> mock(MongoChangeProjector.class))\n .withBean(MongoChangeDeduplicationStore.class,\n () -> mock(MongoChangeDeduplicationStore.class));\n }\n\n private static void report(String label, ApplicationContextRunner runner) {\n runner.run(context -> System.out.println(\" \" + label\n + \" 드라이버쪽=\" + present(context, MongoChangeStreamSource.class)\n + \" 소비자=\" + present(context, ReactiveMongoChangeStreamConsumer.class)\n + \" 설정빈=\" + present(context, MongoPlatformSettings.class)\n + flag(context)));\n }\n\n private static String flag(AssertableApplicationContext context) {\n if (context.getBeanNamesForType(MongoPlatformSettings.class).length == 0) {\n return \"\";\n }\n return \" changeStreams()=\" + context.getBean(MongoPlatformSettings.class).changeStreams();\n }\n\n private static String present(AssertableApplicationContext context, Class type) {\n return context.getBeanNamesForType(type).length > 0 ? \"있음\" : \"없음\";\n }\n\n private static MongoTemplate blocking() {\n return new MongoTemplate(\n new SimpleMongoClientDatabaseFactory(\n MongoClients.create(\"mongodb://127.0.0.1:27017\"), \"wiring-probe\"));\n }\n\n private static ReactiveMongoTemplate reactive() {\n return new ReactiveMongoTemplate(\n new SimpleReactiveMongoDatabaseFactory(\n com.mongodb.reactivestreams.client.MongoClients.create(\"mongodb://127.0.0.1:27017\"),\n \"wiring-probe\"));\n }\n}\nJAVA\n\nCACHE=/root/.gradle/caches/modules-2/files-2.1\nLOCK=src/adapter/outbound/persistence-mongo/gradle.lockfile\nCP=src/adapter/outbound/persistence-mongo/build/classes/java/main\nwhile IFS= read -r line; do\n coord=${line%%=*}; confs=${line#*=}\n case \",$confs,\" in *\",testRuntimeClasspath,\"*) ;; *) continue ;; esac\n g=${coord%%:*}; r=${coord#*:}; n=${r%%:*}; v=${r##*:}\n jar=$(find \"$CACHE/$g/$n/$v\" -name '*.jar' ! -name '*sources*' ! -name '*javadoc*' 2>/dev/null | head -1)\n [ -n \"$jar\" ] && CP=\"$CP:$jar\"\ndone < <(grep -E '^[a-zA-Z0-9._-]+:[^=]+=' \"$LOCK\")\n\njavac -encoding UTF-8 -cp \"$CP\" -d \"$D\" \"$D/ChangeStreamWiringProbe.java\"\njava -XX:+EnableDynamicAgentLoading -Dlogback.configurationFile=\"$D/logback-off.xml\" \\\n -Dstdout.encoding=UTF-8 -cp \"$D:$CP\" ChangeStreamWiringProbe 2>/dev/null", "cwd": "/shared/codebase/clean-architecture-backend-template", "exitCode": 0, "executedAt": "2026-09-02T08:19:48+00:00", "sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916", "raw": "evidence/raw/a06-f018-changestreams-false-wiring.txt", "svg": "evidence/rendered/a06-f018-changestreams-false-wiring.svg", "rawSha256": "ee8bcb3995b4c5019e707e9b9a08ae524712622b7afdac3cf84102f82e39781d", "lines": 13, "redaction": "none — 밀폐 탐침 실행 출력, 자격증명 없음" }