feat: add production capability foundations

This commit is contained in:
donghyeon-ka
2026-07-31 23:50:44 +09:00
parent b3add0162d
commit 567422f2e5
757 changed files with 132385 additions and 2146 deletions
@@ -1,7 +1,7 @@
# HTTP Client Production Capability Deep Design
- 작성일: 2026-07-27
- 상태: 상세 설계 완료, Phase 0/1 기반legacy deadline R1 구현, R2 미구현
- 상태: 상세 설계 완료, Phase 0/1 기반·legacy deadline R1·canonical zero-binding 구현, R2 미구현
- 기준: Java 21, Spring Boot 4.0.0, Gradle 멀티모듈 Clean Architecture
- 대상 leaf: `adapter-outbound-httpclient`
- 구현 추적: typed operation/target foundation, legacy JDK 안전 결함과 active logical deadline
@@ -28,11 +28,16 @@
- client별 bounded live-worker admission, non-cooperative worker의 slot retention, shutdown 시
active task cancellation과 신규 admission 차단;
- worker MDC 복사/정리와 retry ThreadLocal lifecycle 정렬.
- strict canonical expected-state/binding/provider map binder와 exact provider/destination/catalog
resolver;
- `DISABLED_VERIFIED` descriptor와 zero-binding HTTP runtime resource 0 composition;
- `httpclient-static-buffered=NOT_IMPLEMENTED` fail-closed ACTIVE admission;
- legacy settings/configuration의 global Spring scan 분리와 explicit migration binder.
아직 구현되지 않은 범위:
- application feature-specific production port와 실제 upstream anti-corruption adapter;
- canonical binding/expected-state/full profile tuple/card registry와 zero-binding resource 0 계약;
- full compatibility profile tuple/scenario registry와 release-eligible readiness evidence;
- Apache HC5 pool/acquire/lifetime/idle provider;
- Apache engine phase별 deadline 전달, wire hard cancellation과 connection quarantine;
- DNS/address/SSRF/TLS/mTLS/proxy/auth/secret lifecycle;
@@ -42,7 +47,8 @@
따라서 현재 `OutboundHttpClient`는 migration용 JDK R1 이하 facade이며 HTTP capability R2가 아니다.
legacy 실행 경로는 active logical deadline을 사용하지만 operation catalog와 engine phase
deadline을 아직 사용하지 않는다. 이 단면만으로 hard cancellation이나 R2를 주장하지 않는다.
deadline을 아직 사용하지 않는다. Canonical ACTIVE도 현재 `NOT_IMPLEMENTED` card에서 실패한다.
이 단면만으로 hard cancellation이나 R2를 주장하지 않는다.
## 1. 설계 판정
@@ -147,11 +153,12 @@ production capability는 아니다.
dependency별 configuration에서 `baseline(...)`을 직접 호출하도록 안내한다. repository 전체에서
이를 호출하는 production consumer는 없다.
다만 “binding 0개”가 HTTP 관련 bean 0개라는 뜻은 아니다. Component scan이 이 configuration을
읽으면 `OutboundHttpSettings`, shutdown guard, `RestClient`/builder 차단 BeanPostProcessor,
error mapper, logger와 retry policy 같은 global infrastructure bean은 생성된다. Named
client/semantic-port binding은 없는데 required global timeout 설정과 전역 부작용은 존재하는
비대칭 상태다.
초기 조사 시점에는 component scan이 `OutboundHttpSettings`, shutdown guard,
`RestClient`/builder 차단 BeanPostProcessor, error mapper, logger와 retry policy를 생성해
“binding 0개”와 “HTTP resource 0개”가 일치하지 않았다. Phase 1 구현에서 이 결함은 폐쇄됐다.
현재 settings와 두 legacy configuration은 global scan 대상이 아니며 canonical composition은
immutable configuration, registry, resolver와 sanitized `DISABLED_VERIFIED` descriptor만 만든다.
기본 `application.yml``application-test.yml`도 legacy `app.outbound.http.*`를 선언하지 않는다.
다만 sample에는 이미 다음 seam이 있다.
@@ -4893,6 +4900,11 @@ inbound/use-case budget
## 33. Configuration design
2026-07-28 구현 단면은 canonical expected-state/binding/provider map의 strict binding, exact
provider/destination/code-owned catalog resolution과 `httpclient-static-buffered` card derivation까지
포함한다. 아래 full provider tuple의 pool/security/TLS/auth 필드는 아직 bind/runtime model로
구현되지 않았다.
### 33.1 Canonical activation shape
상위 capability platform과 같은 canonical prefix를 사용한다.
@@ -5229,7 +5241,15 @@ Base URI, proxy endpoint, SSL bundle/secret reference 변경은 운영 영향이
### 33.7 Legacy migration
현재 `app.outbound.http.*`는 migration-only alias다.
`app.outbound.http.*` canonical application configuration에 포함되지 않는 migration-only
입력이다.
현재 구현은 global `@ConfigurationPropertiesScan`을 제거하고
`OutboundHttpSettings.bindLegacy(Binder)`/직접 생성자만 남겼다. Canonical composition은
expected state가 DISABLED여도 legacy property가 하나라도 보이면 silent no-op 대신
fail-closed한다. Legacy fork는 canonical composition 밖에서 migration binder와 configuration을
명시적으로 import해야 한다. 아래 deprecation warning, one-destination conversion,
release-window removal은 후속 migration 단계다.
1. legacy만 있으면 deprecation warning과 함께 immutable legacy settings로 변환;
2. canonical과 legacy가 동시에 있으면 값이 같아도 startup failure;
@@ -5257,6 +5277,10 @@ Application은 adapter type, `RestClient`, Apache type을 알지 못한다.
### 34.2 Zero-binding contract
이 절의 resource 0 계약은 `HttpClientCompositionConfigTest`
`OptionalAdapterBeanGatingTest`로 구현됐다. 기본 composition은 inert registry/resolver/descriptor
외에 HTTP runtime bean을 만들지 않으며 `DISABLED_VERIFIED`만 게시한다.
Binding이 없으면 다음이 모두 0개여야 한다.
- engine client와 connection manager;