Bluetape4k AWS Part 2: 핵심 모듈과 AWS 서비스 지원 현황

이 글은 bluetape4k-aws 시리즈의 2편입니다. Part 1에서는
프로젝트 개요와 기본 모델을 다뤘습니다. 이번 글에서는 핵심 모듈인
bluetape4k-aws-java와 bluetape4k-aws-kotlin이 어떤 반복 작업을 줄이는지 살펴봅니다.
핵심은 AWS SDK를 다시 구현하는 것이 아닙니다. AWS Java SDK v2와 AWS Kotlin SDK는 그대로 쓰되,
Kotlin/JVM 서비스에서 반복되는 클라이언트 생성과 코루틴 연결, 요청 모델 구성을 편의 함수로 제공합니다. Java SDK v2
쪽에서는 CompletableFuture 기반 비동기 클라이언트를 suspend 함수로 연결하고, S3 대용량 전송에는 CRT 기반
비동기 클라이언트와 S3TransferManager를 조합합니다. Kotlin SDK 쪽에서는 네이티브 suspend 클라이언트를
유지하면서 공유 HTTP 엔진 선택지, withXxxClient 생명주기 도우미, 서비스별 DSL 빌더를 제공합니다.

Java SDK v2 방식
섹션 제목: “Java SDK v2 방식”AWS Java SDK v2를 직접 사용하면 동기 클라이언트와 비동기 클라이언트의 실행 모델을 나눠야 하고,
비동기 클라이언트에서는 HTTP 클라이언트 선택과 CompletableFuture 조합이 따라옵니다. S3처럼 파일 크기와
처리량이 중요한 작업에서는 CRT 기반 S3 비동기 클라이언트와 TransferManager 구성까지 함께 고려해야 합니다.
bluetape4k-aws-java는 이 결정을 숨기지 않습니다. 대신 반복되는 조립 지점을 미리 준비합니다.
일반 비동기 클라이언트 팩터리의 기본 HTTP 클라이언트는 현재 Netty입니다. SdkAsyncHttpClientProvider.AwsCrt와
awsCrtAsyncHttpClientOf를 사용하면 CRT 비동기 HTTP 클라이언트를 명시적으로 선택할 수 있습니다. S3 대용량
전송은 CRT 중심으로 구성합니다. S3ClientFactory.CrtAsync.create는 S3AsyncClient.crtBuilder()를 사용하고,
S3ClientFactory.TransferManager.create는 이 CRT 기반 비동기 클라이언트를 만들어
S3TransferManager에 연결합니다.
또 하나의 기본값은 실행기입니다. Java 버전의 TransferManager.create는
Executors.newVirtualThreadPerTaskExecutor()를 기본 실행기로 사용합니다. 파일 전송처럼 블로킹 작업과
비동기 완료 처리가 섞이는 지점에 가상 스레드를 적용할 수 있습니다.
import io.bluetape4k.aws.s3.S3ClientFactoryimport io.bluetape4k.aws.s3.transfer.downloadFileimport io.bluetape4k.aws.s3.transfer.uploadFileimport software.amazon.awssdk.regions.Regionimport java.nio.file.Path
suspend fun mirrorObject(bucket: String, key: String, source: Path, target: Path) { val transferManager = S3ClientFactory.TransferManager.create( region = Region.AP_NORTHEAST_2, )
transferManager.uploadFile(bucket, key, source) transferManager.downloadFile(bucket, key, target)}TransferManager 자체는 AWS SDK가 제공합니다. bluetape4k-aws-java는 CRT 기반 S3 비동기 클라이언트, 가상
스레드 실행기, 비동기·코루틴 확장 함수를 서비스 코드에서 반복해 조립하지 않도록 팩터리와 도우미를 제공합니다.
작은 객체나 문자열 중심의 S3 작업은 코루틴 확장 함수를 사용할 수 있습니다. Java SDK v2 비동기 클라이언트는
CompletableFuture를 반환하지만, 확장 함수는 .await()로 완료를 기다리는 suspend API를 제공합니다.
import io.bluetape4k.aws.s3.S3ClientFactoryimport io.bluetape4k.aws.s3.getAsStringimport io.bluetape4k.aws.s3.putAsString
suspend fun writeAndRead(bucket: String, key: String): String { val client = S3ClientFactory.Async.create()
client.putAsString(bucket, key, "hello from bluetape4k-aws") return client.getAsString(bucket, key)}이 패턴은 S3에만 적용되지 않습니다. DynamoDB Enhanced Async Table의 스캔·쿼리를 Flow로 받거나 SQS
송신·수신·삭제, SNS 발행, SES 메일 전송, KMS 암호화·복호화, CloudWatch 메트릭·로그, Kinesis 레코드,
STS 자격 확인·역할 위임 같은 작업도 같은 방식으로 제공합니다. Java SDK v2의 서비스 지원 범위를 유지하면서
코루틴 기반 Kotlin 서비스에서 사용할 수 있게 하는 것이 목적입니다.
Kotlin SDK 방식
섹션 제목: “Kotlin SDK 방식”bluetape4k-aws-kotlin은 출발점이 다릅니다. AWS Kotlin SDK의 서비스 연산은 이미 suspend 함수입니다.
그래서 Java SDK v2처럼 CompletableFuture를 코루틴으로 바꾸는 일이 중심이 아닙니다. 여기서는 클라이언트 생성,
HTTP 엔진 소유권, 요청 모델 빌더, 자원 생명주기를 명확히 하는 일이 더 중요합니다.
HttpClientEngineProvider.defaultHttpEngine은 명시적으로 공유할 수 있는 CRT 엔진을 반환하고,
HttpClientEngineProvider.OkHttp.httpEngine은 공유 OkHttp 엔진을 제공합니다. 두 엔진은 외부에서 관리하는
싱글턴이므로 여러 클라이언트가 의도적으로 전송 계층을 공유할 때만 전달해야 합니다. 단일 클라이언트에서는
httpClient를 생략해 AWS Kotlin SDK가 엔진 생명주기를 소유하게 하거나 withXxxClient 도우미를 사용합니다.
import aws.smithy.kotlin.runtime.net.url.Urlimport io.bluetape4k.aws.kotlin.s3.putFromPathimport io.bluetape4k.aws.kotlin.s3.withS3Clientimport java.nio.file.Path
suspend fun uploadReport(path: Path) { withS3Client( endpointUrl = Url.parse("http://localhost:4566"), region = "ap-northeast-2", ) { client -> client.putFromPath("reports", "daily/report.csv", path) }}withS3Client, withSqsClient, withDynamoDbClient 같은 도우미는 클라이언트를 만들고 블록을 실행한 뒤
클라이언트를 닫습니다. 장기 사용 클라이언트가 필요하면 s3ClientOf, sqsClientOf 같은 팩터리를 직접 사용하고
애플리케이션 종료 시 명시적으로 닫아야 합니다. 일회성 클라이언트와 애플리케이션 범위 클라이언트의 수명 주기를
구분한 것입니다.
Kotlin 쪽 서비스 도우미는 파일·바이트·문자열 중심의 S3 함수, 큐 URL 중심의 SQS 송수신 함수, DynamoDB 항목
매핑·배치 실행·요청 빌더를 제공합니다. Kinesis의 recordFlow는 샤드 하나를 지속해서 폴링하고
Flow<Record>로 내보냅니다. 샤드 반복자 만료와 조절 제한 재시도도 이 처리 흐름 안에서 다룹니다.
import io.bluetape4k.aws.kotlin.kinesis.KinesisStartingPositionimport io.bluetape4k.aws.kotlin.kinesis.recordFlow
suspend fun consumeShard(client: aws.sdk.kotlin.services.kinesis.KinesisClient) { client.recordFlow( streamName = "orders", shardId = "shardId-000000000000", position = KinesisStartingPosition.TrimHorizon, ).collect { record -> println(record.data.decodeToString()) }}AWS 서비스 지원 범위
섹션 제목: “AWS 서비스 지원 범위”핵심 모듈은 S3, SQS, SNS, DynamoDB, KMS, SES/SESv2, CloudWatch, CloudWatch Logs, Kinesis, STS뿐 아니라 EventBridge, EventBridge Scheduler, Bedrock Runtime, Secrets Manager, Parameter Store의 반복 호출 패턴도 다룹니다. Java 모듈은 S3 Vectors와 RDS IAM 토큰 도우미도 제공합니다. Spring Boot와 Ktor 모듈은 이 핵심 API 위에 프레임워크별 진입점을 추가합니다.

| 서비스 | Java SDK v2 | Kotlin SDK | 대표 편의 기능 |
|---|---|---|---|
| S3 | 동기·비동기·코루틴, CRT 비동기, TransferManager | suspend 클라이언트, 파일·문자열·바이트 도우미 | 대용량 전송, 파일 업로드·다운로드, 객체 목록 조회 |
| S3 Vectors | 선택적 코루틴 파사드 | 미지원 | 벡터 버킷·인덱스 조회와 벡터 쓰기·조회·검색 |
| DynamoDB | Enhanced Client, 비동기 테이블, 코루틴·Flow | 테이블·항목·배치 도우미, 모델 DSL | 항목 변환, 배치 쓰기, 스캔·쿼리 |
| SQS | 비동기·코루틴 큐 작업 | suspend 송신·수신·배치 도우미 | 큐 URL 중심 송신·수신·삭제 |
| SNS | 주제 발행, SMS, 푸시 | suspend 발행·구독 도우미 | 주제 생성, 발행, 구독 |
| SES/SESv2 | 메일 전송 도우미 | 일반·원시·템플릿·대량 전송 도우미 | 메일 요청 빌더와 전송 API |
| KMS | 동기·비동기 클라이언트 빌더, 요청 DSL | 암호화·복호화·데이터 키 도우미 | 키 작업 DSL |
| CloudWatch/Logs | 메트릭·로그 이벤트 코루틴 확장 | metricDatum·inputLogEvent DSL | 메트릭과 로그 이벤트 발행 |
| Kinesis | 레코드 쓰기·조회 코루틴 확장 | recordFlow, putRecord 도우미 | 샤드 폴링, 재시도·지수 백오프 |
| EventBridge/Scheduler | 이벤트 발행·일정 작업 도우미 | 이벤트 발행·일정 작업 도우미 | 이벤트 요청과 일정 작업 모델 DSL |
| Bedrock Runtime | 동기·비동기·코루틴 호출 도우미 | 네이티브 suspend 호출 도우미 | 모델 호출 요청·응답 처리 |
| Secrets Manager/Parameter Store | 비동기·코루틴 조회 도우미 | 네이티브 suspend 조회 도우미 | 시크릿·파라미터 조회와 요청 DSL |
| STS | 역할 위임, 호출자 자격, 세션 토큰 | suspend STS 도우미 | 자격 확인, 임시 자격 증명 |
| RDS IAM | 인증 토큰 도우미 | 미지원 | Java SDK 기반 RDS IAM 인증 토큰 생성 |
라이브러리가 여러 서비스의 도우미를 제공하더라도 애플리케이션은 실제 사용하는 AWS 서비스 아티팩트만 선택해야 합니다.
의존성 모델
섹션 제목: “의존성 모델”aws-java와 aws-kotlin 빌드 파일은 서비스별 AWS SDK 의존성을 compileOnly로 선언합니다. Java 모듈은
Bedrock Runtime, DynamoDB Enhanced, S3, S3 Vectors, S3 Transfer Manager, SES/SESv2, Secrets Manager,
SNS, SQS, Parameter Store, KMS, CloudWatch, CloudWatch Logs, Kinesis, EventBridge, Scheduler, RDS, STS를
이 방식으로 선언합니다. Kotlin 모듈도 S3 Vectors와 RDS를 제외한 대응 서비스 의존성을 compileOnly로 둡니다.
이 구조에서는 핵심 모듈이 여러 서비스의 도우미를 컴파일할 수 있지만 실제 런타임 클래스패스는 애플리케이션이
결정합니다. S3와 SQS만 사용하는 서비스는 Kinesis와 SES 의존성을 추가할 필요가 없습니다. BOM은 지원 아티팩트의
버전을 정렬하고, 애플리케이션은 사용하는 AWS SDK 아티팩트만 implementation으로 선택합니다.

compileOnly는 핵심 모듈의 컴파일 경계를 제공하고, 런타임 서비스 의존성은 애플리케이션이 선택합니다.언제 어느 모듈을 쓸까
섹션 제목: “언제 어느 모듈을 쓸까”Java SDK v2의 서비스 지원이 필요하거나 S3 대용량 전송을 TransferManager, CRT 비동기 클라이언트, 가상 스레드와
함께 사용하려면 bluetape4k-aws-java를 선택합니다. S3 전송에 필요한 HTTP 클라이언트, 비동기 클라이언트,
실행기, 코루틴 연결을 공통 팩터리로 구성할 수 있습니다.
AWS Kotlin SDK의 네이티브 suspend 연산을 유지하려면 bluetape4k-aws-kotlin을 선택합니다. SDK 소유 엔진과
명시적으로 공유하는 CRT·OkHttp 엔진을 구분할 수 있고, withXxxClient 생명주기 도우미와 서비스별 DSL 빌더를
사용할 수 있습니다.
Spring Boot 4나 Ktor 3에서 속성 바인딩, 자동 구성, 리스너 런타임 같은 프레임워크 연결이 필요하면 Part 3에서 다루는 통합 모듈을 사용합니다. Part 2의 핵심 모듈은 SDK와 프레임워크 사이의 반복 코드를 줄이고, 런타임에 포함할 서비스 의존성은 애플리케이션이 선택하게 합니다.
참고자료
섹션 제목: “참고자료”- 저장소: bluetape4k-aws
- README: README.md
- Java 모듈 README: aws-java/README.md
- Kotlin 모듈 README: aws-kotlin/README.md
- Java S3 팩터리: S3ClientFactory.kt
- Java 비동기 HTTP 공급자: SdkAsyncHttpClientProvider.kt
- Java S3 TransferManager 코루틴 확장: S3TransferManagerCoroutinesExtensions.kt
- Kotlin HTTP 엔진 공급자: HttpClientEngineProvider.kt
- Kotlin Kinesis Flow 도우미: KinesisRecordFlow.kt
- 의존성 선언: aws-java/build.gradle.kts, aws-kotlin/build.gradle.kts
마무리
섹션 제목: “마무리”bluetape4k-aws-java와 bluetape4k-aws-kotlin은 같은 통합 문제를 서로 다른 SDK 실행 모델에서 해결합니다.
Java 모듈은 Java SDK v2 비동기 API를 코루틴으로 연결하고 CRT 기반 S3 전송과 가상 스레드 실행기를 구성합니다.
Kotlin 모듈은 네이티브 suspend 모델을 유지하면서 클라이언트 생명주기, 공유 HTTP 엔진, 요청 DSL을 제공합니다.
다음 글에서는 이 핵심 모듈 위에 Spring Boot 4와 Ktor 3가 제공하는 자동 구성, SQS 리스너, Ktor SigV4 플러그인, 예제 애플리케이션의 프레임워크 연결을 살펴봅니다.
댓글
GitHub 계정으로 의견을 남기거나 reaction을 남길 수 있습니다.