# feat(cdc): Remittance Outbox + Debezium CDC + payout-worker + 결과 컨슈머 end-to-end 추가 - #10
Merged
Merged
Conversation
…머 end-to-end 추가 ### Summary 송금 생성 시 `remittance_events` outbox를 같은 트랜잭션으로 기록하고, Debezium CDC로 Kafka 토픽(`remittance.paid`)에 발행하는 흐름을 추가했습니다. 신규 `payout-worker`가 해당 이벤트를 소비해 송금사 API 호출 후 `payout_outbox`를 기록하고, 다시 Debezium으로 `remittance.payout.completed/failed`를 발행합니다. `remittance-api`는 결과 토픽을 소비해 상태를 `COMPLETED/FAILED`로 전이합니다. --- ### Changes #### 1) remittance-api: Outbox 발행 + Kafka 결과 소비 - `remittance-api/src/main/kotlin/com/openremit/api/application/remittance/RemittanceCreateUseCase.kt` - `markPaid` 이후 `remittance_events` outbox INSERT 추가 (동일 트랜잭션) - `remittance-api/src/main/kotlin/com/openremit/api/domain/RemittanceEvent.kt` (신규) - `remittance-api/src/main/kotlin/com/openremit/api/infrastructure/persistence/RemittanceEventRepository.kt` (신규) - `remittance-api/src/main/resources/db/migration/V4__remittance_events.sql` (신규) - `remittance-api/src/main/kotlin/com/openremit/api/infrastructure/kafka/RemittancePayoutResultConsumer.kt` (신규) - `remittance.payout.completed/failed` 소비 - `remittance-api/src/main/kotlin/com/openremit/api/application/remittance/RemittanceCompletionService.kt` (신규) - `PAID -> PROCESSING -> COMPLETED/FAILED` 전이 처리 (terminal 상태 재처리 skip) - `remittance-api/src/main/kotlin/com/openremit/api/RemittanceApiApplication.kt` - `@EnableKafka` 추가 - `remittance-api/src/main/resources/application.yaml` - Kafka consumer 설정 추가 - `remittance-api/build.gradle.kts` - Kafka runtime/test 의존성 추가 #### 2) common: 이벤트 계약 추가 - `common/src/main/kotlin/com/openremit/common/events/RemittanceEvents.kt` (신규) - `RemittancePaidEvent` - `RemittancePayoutCompletedEvent` - `RemittancePayoutFailedEvent` - `RemittanceEventTopics` #### 3) payout-worker 모듈 구현 - `payout-worker/build.gradle.kts` - Spring Boot/JPA/Flyway/Kafka/Web/Validation/Testcontainers 의존성 구성 - `payout-worker/src/main/kotlin/com/openremit/payout/PayoutWorkerApplication.kt` (신규) - `payout-worker/src/main/resources/application.yaml` (신규) - `payout-worker/src/main/resources/db/migration/V1__payout_tables.sql` (신규) - `payout_attempts`(remittance_id UNIQUE 멱등성) - `payout_outbox` - `payout-worker/src/main/kotlin/com/openremit/payout/infrastructure/kafka/RemittancePaidConsumer.kt` (신규) - `payout-worker/src/main/kotlin/com/openremit/payout/application/PayoutProcessor.kt` (신규) - 송금사 호출 결과를 `payout_outbox`에 기록 - `payout-worker/src/main/kotlin/com/openremit/payout/infrastructure/client/PayoutClient.kt` (신규) - `payout-worker/src/main/kotlin/com/openremit/payout/domain/PayoutAttempt.kt` (신규) - `payout-worker/src/main/kotlin/com/openremit/payout/domain/PayoutOutboxEvent.kt` (신규) - `payout-worker/src/main/kotlin/com/openremit/payout/infrastructure/persistence/*.kt` (신규) #### 4) 인프라/docker-compose: Debezium + mock payout + MySQL binlog 설정 - `docker-compose.yml` - MySQL binlog/GTID 옵션 추가 - `mock-payout-api` 추가 (`9998`) - Kafka dual listener(`9092` host, `29092` internal) 구성 - `debezium` + `debezium-register` 서비스 추가 - `debezium/openremit-outbox-connector.json` (신규) - `remittance_events`, `payout_outbox` 대상 outbox event router 설정 - `mysql-init/01-debezium-user.sql` (신규) - `mock-payout/mappings/payout-success.json` (신규) #### 5) 테스트 추가/보강 - `remittance-api/src/test/kotlin/com/openremit/api/remittance/RemittanceCreateIntegrationTest.kt` - 송금 생성 시 outbox 1건 기록 검증 추가 - `remittance-api/src/test/kotlin/com/openremit/api/remittance/RemittancePayoutResultConsumerIntegrationTest.kt` (신규) - completed/failed 이벤트 소비 후 상태 전이 검증 - `remittance-api/src/test/kotlin/com/openremit/api/TestcontainersConfig.kt` - Kafka container bootstrap 주입 추가 - `payout-worker/src/test/kotlin/com/openremit/payout/PayoutWorkerIntegrationTest.kt` (신규) - `remittance.paid` 소비 → payout 호출 → outbox 기록 검증 - `payout-worker/src/test/kotlin/com/openremit/payout/PayoutWorkerTestcontainersConfig.kt` (신규) #### 6) 문서 업데이트 - `README.md` - Outbox + Debezium 이벤트 흐름 다이어그램/설명 추가 - docker-compose 기반 E2E 검증 절차 추가 --- ### Checklist - [x] remittance outbox(`remittance_events`) 저장 추가 - [x] Debezium connector 설정 추가 - [x] payout-worker 신규 구현 (consume/process/outbox) - [x] remittance-api 결과 consumer/상태 전이 서비스 추가 - [x] Kafka/Testcontainers 기반 통합 테스트 추가 - [x] README 운영/검증 가이드 반영 --- ### How to Test ```bash # 1) 통합 테스트 ./gradlew build # 2) 로컬 CDC E2E 인프라 docker compose up -d # 3) 앱 실행 ./gradlew :remittance-api:bootRun ./gradlew :payout-worker:bootRun # 4) Debezium connector 상태 확인 curl -sS http://localhost:8083/connectors/openremit-outbox/status
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
송금 생성 시
remittance_eventsoutbox를 같은 트랜잭션으로 기록하고, Debezium CDC로 Kafka 토픽(remittance.paid)에 발행하는 흐름을 추가했습니다. 신규payout-worker가 해당 이벤트를 소비해 송금사 API 호출 후payout_outbox를 기록하고, 다시 Debezium으로remittance.payout.completed/failed를 발행합니다.remittance-api는 결과 토픽을 소비해 상태를COMPLETED/FAILED로 전이합니다.Changes
1) remittance-api: Outbox 발행 + Kafka 결과 소비
remittance-api/src/main/kotlin/com/openremit/api/application/remittance/RemittanceCreateUseCase.ktmarkPaid이후remittance_eventsoutbox INSERT 추가 (동일 트랜잭션)remittance-api/src/main/kotlin/com/openremit/api/domain/RemittanceEvent.kt(신규)remittance-api/src/main/kotlin/com/openremit/api/infrastructure/persistence/RemittanceEventRepository.kt(신규)remittance-api/src/main/resources/db/migration/V4__remittance_events.sql(신규)remittance-api/src/main/kotlin/com/openremit/api/infrastructure/kafka/RemittancePayoutResultConsumer.kt(신규)remittance.payout.completed/failed소비remittance-api/src/main/kotlin/com/openremit/api/application/remittance/RemittanceCompletionService.kt(신규)PAID -> PROCESSING -> COMPLETED/FAILED전이 처리 (terminal 상태 재처리 skip)remittance-api/src/main/kotlin/com/openremit/api/RemittanceApiApplication.kt@EnableKafka추가remittance-api/src/main/resources/application.yamlremittance-api/build.gradle.kts2) common: 이벤트 계약 추가
common/src/main/kotlin/com/openremit/common/events/RemittanceEvents.kt(신규)RemittancePaidEventRemittancePayoutCompletedEventRemittancePayoutFailedEventRemittanceEventTopics3) payout-worker 모듈 구현
payout-worker/build.gradle.ktspayout-worker/src/main/kotlin/com/openremit/payout/PayoutWorkerApplication.kt(신규)payout-worker/src/main/resources/application.yaml(신규)payout-worker/src/main/resources/db/migration/V1__payout_tables.sql(신규)payout_attempts(remittance_id UNIQUE 멱등성)payout_outboxpayout-worker/src/main/kotlin/com/openremit/payout/infrastructure/kafka/RemittancePaidConsumer.kt(신규)payout-worker/src/main/kotlin/com/openremit/payout/application/PayoutProcessor.kt(신규)payout_outbox에 기록payout-worker/src/main/kotlin/com/openremit/payout/infrastructure/client/PayoutClient.kt(신규)payout-worker/src/main/kotlin/com/openremit/payout/domain/PayoutAttempt.kt(신규)payout-worker/src/main/kotlin/com/openremit/payout/domain/PayoutOutboxEvent.kt(신규)payout-worker/src/main/kotlin/com/openremit/payout/infrastructure/persistence/*.kt(신규)4) 인프라/docker-compose: Debezium + mock payout + MySQL binlog 설정
docker-compose.ymlmock-payout-api추가 (9998)9092host,29092internal) 구성debezium+debezium-register서비스 추가debezium/openremit-outbox-connector.json(신규)remittance_events,payout_outbox대상 outbox event router 설정mysql-init/01-debezium-user.sql(신규)mock-payout/mappings/payout-success.json(신규)5) 테스트 추가/보강
remittance-api/src/test/kotlin/com/openremit/api/remittance/RemittanceCreateIntegrationTest.ktremittance-api/src/test/kotlin/com/openremit/api/remittance/RemittancePayoutResultConsumerIntegrationTest.kt(신규)remittance-api/src/test/kotlin/com/openremit/api/TestcontainersConfig.ktpayout-worker/src/test/kotlin/com/openremit/payout/PayoutWorkerIntegrationTest.kt(신규)remittance.paid소비 → payout 호출 → outbox 기록 검증payout-worker/src/test/kotlin/com/openremit/payout/PayoutWorkerTestcontainersConfig.kt(신규)6) 문서 업데이트
README.mdChecklist
remittance_events) 저장 추가How to Test