feat: redis, fileserver, httpclient 런타임 시점 구현 추가

This commit is contained in:
donghyeon-ka
2026-07-28 14:26:54 +09:00
parent 7363b2aa1e
commit b3add0162d
257 changed files with 30430 additions and 1357 deletions
+22 -6
View File
@@ -2,12 +2,12 @@
메시징(broker publish + outbox) 아웃바운드 어댑터 모듈. 패키지 루트:
`dev.caskeleton.adapter.outbound.messaging`. `:adapter:outbound:support` 에 의존해 공유
correlation / fail-open 의존성 로깅을 재사용한다.
correlation / fail-open 의존성 로깅을 일반 publisher에서 재사용한다. outbox relay 실패는 이
모듈이 별도의 typed report adapter로 구조화한다.
허용/금지 의존 정책은 `src/build.gradle`
`allowedProjectDependencies['adapter:outbound:messaging']` 항목이 SSOT 다(이 모듈은 아직 별도
CLAUDE.md 를 두지 않았다). 이 문서는 코드 주석에서 덜어낸 **설계 결정의 근거**를 모아둔 참조용
기록이다.
허용/금지 의존 정책은 `src/config/architecture/modules.json`과 이 모듈
[CLAUDE.md](CLAUDE.md)가 소유한다. 이 문서는 코드 주석에서 덜어낸 **설계 결정의 근거**를 모아둔
참조용 기록이다.
## 모듈 개요
@@ -41,4 +41,20 @@ application-core 포트(`MessagePublisher` / `OutboxMessagePublishPort`) 뒤에
`MessagePublisher` 는 fail-open 어댑터-로컬 발행기로, 발행 실패를 correlationId 와 함께
로깅하고 삼켜(→ `:adapter:outbound:support``FailOpenDependencyLogger`) outbox/retry 로
위임하므로 core 5xx 가 되지 않는다. 내구성 있는 전달이 필요하면 `OutboxMessagePublishPort`
쓴다. 반환 타입을 void 로 둬 broker SDK 타입이 어댑터 밖으로 새지 않는다(B7).
쓴다. `OutboxMessagePublishAdapter`는 envelope mapping + broker send만 수행하며 runtime 예외를
그대로 전파하고 checked 예외는 cause를 보존해 감싼다. 성공 DEBUG나 실패 WARN을 남기지 않는다.
반환 타입을 void 로 둬 broker SDK 타입이 어댑터 밖으로 새지 않는다(B7).
## OutboxRelayFailureReport 구조화 ERROR
`MessagingConfig`는 broker 활성 여부와 무관하게 정확히 하나의
`Slf4jOutboxRelayFailureReportAdapter`를 등록한다. broker 설정이 blank면 안전한
`dependency_name=disabled`를 쓴다. 이 adapter는 confirmed FAILED/DEAD report 하나를 SLF4J 2 fluent
ERROR 하나로 렌더링한다.
공통 field는 `error.code`, `error.category`, `dependency_name`,
`dependency_type=messaging`, `outcome`, `event_id`, `event_type`, `aggregate_id`,
`correlation_id`, `attempt_count`, `runbook_link`다. retry report만 `next_attempt_at`을 추가한다.
payload/idempotency key/envelope/exception-derived field는 받거나 렌더링하지 않고 cause만 throwable로
붙인다. logging 내부 `RuntimeException`은 adapter와 use case 양쪽에서 방어하므로 persisted
FAILED/DEAD outcome을 바꾸지 않는다.