# 주제: messaging-kafka 34개 main 타입 중 무엇이 조립되고 무엇이 조립되지 않는가
# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916

# command: git grep -nE "new ([a-zA-Z0-9_.]+\.)?<T>\s*\(" -- src   (T별 집계)
  KafkaMessagingTransport            src/main=1  src/test+jmh=12    <- 스타터가 3-arg 로 생성
  KafkaSecurityConfigurer            src/main=1  src/test+jmh=2
  KafkaProfileValidator              src/main=1  src/test+jmh=1
  KafkaTransactionProfileValidator   src/main=1  src/test+jmh=0
  KafkaPublishFailureClassifier      src/main=2  src/test+jmh=1
  KafkaPublishMapper                 src/main=2  src/test+jmh=0     (transport/transactional 내부)
  KafkaHeaderMapper                  src/main=2  src/test+jmh=4     (두 매퍼 내부)
  KafkaTransactionalPublisher        src/main=1  src/test+jmh=1     (자기 정적 팩토리)
  KafkaDeliveryMapper                src/main=1  src/test+jmh=1     (registrar 내부)
  KafkaSettlementQueue               src/main=1  src/test+jmh=0     (registrar 내부)
  KafkaPartitionRetryScheduler       src/main=1  src/test+jmh=0     (registrar 내부)
  PartitionWorkCoordinator           src/main=1  src/test+jmh=6     (registrar 내부)
  ContiguousPartitionOffsetTracker   src/main=1  src/test+jmh=2     (registrar 내부)
  KafkaRetryMetadataMapper           src/main=2  src/test+jmh=3
  -----
  KafkaConsumerRegistrar             src/main=0  src/test+jmh=6     <- 테스트에서만
  KafkaOffsetResetExecutor           src/main=0  src/test+jmh=2     <- 테스트에서만
  KafkaReplayPlanner                 src/main=0  src/test+jmh=1     <- 테스트에서만
  SpringKafkaTransactionalProcessor  src/main=0  src/test+jmh=1     <- 테스트에서만
  -----
  KafkaBatchConsumerRegistrar        src/main=0  src/test+jmh=0     <- **어디에서도 생성되지 않음**
  KafkaRetryExecutor                 src/main=0  src/test+jmh=0     <- **어디에서도**
  KafkaRetryTopicPublisher           src/main=0  src/test+jmh=0     <- **어디에서도**
  KafkaDeadLetterPublisher           src/main=0  src/test+jmh=0     <- **어디에서도**
  KafkaReplayCapability              src/main=0  src/test+jmh=0     <- **어디에서도**
  KafkaTopologyInspector             src/main=0  src/test+jmh=0     <- 인터페이스, 구현 0

# src/main 에서 이 leaf 의 타입을 만드는 외부 지점 (전수)
  KafkaMessagingAutoConfiguration.java:42   new KafkaProfileValidator()
  KafkaMessagingAutoConfiguration.java:75   new KafkaTransactionProfileValidator()
  KafkaMessagingAutoConfiguration.java:86   new KafkaPublishFailureClassifier()
  KafkaMessagingAutoConfiguration.java:111  new KafkaSecurityConfigurer(credentials, tlsPolicy)
  KafkaMessagingAutoConfiguration.java:168  new KafkaMessagingTransport("kafka", 1L, producer)
  MessagingConfigurationCompiler.java:116   new KafkaBrokerProfile(...)
# => 외부에서 생성되는 것은 검증기 3 + 보안 설정기 1 + 전송 1 + 프로필 1 = 6개뿐이다.

# ---- 소비 불가가 타입으로 표현되어 있다 ----
# KafkaMessagingTransport.java:74-92  (스타터가 쓰는 3-arg 생성자)
#   public KafkaMessagingTransport(String brokerName, long generation, Producer<byte[],byte[]> producer) {
#     this(brokerName, generation, producer,
#         spec -> {
#           throw new MessagingCapabilityUnavailableException(
#               "KAFKA_CONSUMER_NOT_CONFIGURED",
#               "this Kafka transport was created without a consumer factory");
#         });
#   }
# KafkaMessagingTransport.java:159-167
#   public TransportConsumerRegistration register(TransportConsumerSpec spec) {
#     ...
#     return consumerFactory.apply(spec);      // 3-arg 경로에서는 항상 throw
#   }
# => 부팅된 애플리케이션에서 transport.register(...) 는 KAFKA_CONSUMER_NOT_CONFIGURED 로 실패한다.
#    조용히 아무 일도 안 하는 것이 아니라 이름 붙은 오류로 거절한다.
#    "소비 경로가 배선되지 않았다"(EVD-316)가 이 leaf 에서 타입으로 표현된 형태다.

# ---- 토폴로지 인스펙터: 두 인터페이스, 구현 0 ----
# command: git grep -n "BrokerTopologyInspector" -- src
#   admin-runtime/BrokerTopologyInspector.java:14   (선언)
#   CompositeTopologyValidator:21,29 / DefaultMessagingAdminService:54,80   (소비)
#   MessagingAdminAutoConfiguration:5,81,83                                  (@ConditionalOnBean)
#   TopologyValidatorTest.java:133   new BrokerTopologyInspector() { ... }   <- 유일한 구현, 테스트 익명클래스
# command: git grep -n "KafkaTopologyInspector" -- src
#   messaging-kafka/KafkaTopologyInspector.java:13  (선언)   <- 그 외 등장 0
#
# 두 인터페이스의 모양이 다르다:
#   BrokerTopologyInspector : Optional<DestinationTopology> describe(String), String topologyVersion()
#   KafkaTopologyInspector  : int partitionCount(String), short replicationFactor(String),
#                             Map<String,String> configuration(String), List<String> topics()
#
# 실제로 브로커 토폴로지를 읽는 코드는 컨테이너 IT 안의 private static 헬퍼다:
# KafkaTopologyValidationIT.java:42-61
#   private static DestinationTopology describe(String topic) {
#     try (Admin admin = KafkaContainerFixture.admin()) {
#       Map<String, TopicDescription> described = admin.describeTopics(List.of(topic))...;
#       ...
#       return new DestinationTopology(topic, description.partitions().size(), replication, Map.of(), true);
#     } catch (...) { return DestinationTopology.absent(topic); }
#   }
# => 어느 인터페이스도 구현하지 않는다.
#
# 판정: analysis/messaging/messaging-admin-api.md §17 첫 항목("BLOCKING 이면 기동 실패"가 미배선)을
#      고치려 해도 **줄 인스펙터가 없다.** Kafka leaf 는 그 자리에 다른 모양의 인터페이스를
#      선언만 해 두었고, 실제로 동작하는 20줄은 테스트의 private 메서드로만 존재한다.

# ---- 이 leaf 를 import 하는 외부 파일은 3개뿐 ----
#   messaging-spring-boot-starter/.../CompiledMessagingConfiguration.java
#   messaging-spring-boot-starter/.../KafkaMessagingAutoConfiguration.java
#   messaging-spring-boot-starter/.../MessagingConfigurationCompiler.java
