diff --git a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/domain/status/application/service/CreateStatusService.kt b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/domain/status/application/service/CreateStatusService.kt index ae320c4..16fd291 100644 --- a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/domain/status/application/service/CreateStatusService.kt +++ b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/domain/status/application/service/CreateStatusService.kt @@ -5,8 +5,11 @@ import hs.kr.entrydsm.status.domain.status.application.port.out.QueryStatusPort import hs.kr.entrydsm.status.domain.status.application.port.out.SaveStatusPort import hs.kr.entrydsm.status.domain.status.model.ApplicationStatus import hs.kr.entrydsm.status.domain.status.model.Status +import hs.kr.entrydsm.status.infrastructure.kafka.producer.StatusEventProducer import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import org.springframework.transaction.support.TransactionSynchronization +import org.springframework.transaction.support.TransactionSynchronizationManager /** * 상태 생성 서비스 클래스입니다. @@ -19,6 +22,7 @@ import org.springframework.transaction.annotation.Transactional class CreateStatusService( private val queryStatusPort: QueryStatusPort, private val saveStatusPort: SaveStatusPort, + private val statusEventProducer: StatusEventProducer ) : CreateStatusUseCase { /** * 새로운 지원자의 초기 상태를 생성합니다. @@ -28,16 +32,35 @@ class CreateStatusService( */ @Transactional override fun execute(receiptCode: Long) { - queryStatusPort.findByReceiptCode(receiptCode) - ?: saveStatusPort.save( - Status( - id = null, - applicationStatus = ApplicationStatus.SUBMITTED, - examCode = null, - isFirstRoundPass = false, - isSecondRoundPass = false, - receiptCode = receiptCode, - ), - ) + try { + queryStatusPort.findByReceiptCode(receiptCode) + ?: saveStatusPort.save( + Status( + id = null, + applicationStatus = ApplicationStatus.SUBMITTED, + examCode = null, + isFirstRoundPass = false, + isSecondRoundPass = false, + receiptCode = receiptCode, + ), + ) + + registerAfterCommitCallback(receiptCode) + } catch (e: Exception) { + statusEventProducer.sendStatusCreatedFailed(receiptCode) + throw e + } + } + + private fun registerAfterCommitCallback( + receiptCode: Long, + ) { + val callback = + object : TransactionSynchronization { + override fun afterCommit() { + statusEventProducer.sendStatusCreatedCompleted(receiptCode) + } + } + TransactionSynchronizationManager.registerSynchronization(callback) } } diff --git a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/config/KafkaTopics.kt b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/config/KafkaTopics.kt index d63c6c1..1956281 100644 --- a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/config/KafkaTopics.kt +++ b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/config/KafkaTopics.kt @@ -15,4 +15,10 @@ object KafkaTopics { const val DELETE_USER = "delete-user" const val CANCEL_SUBMITTED_APPLICATION = "cancel-submitted-application" + + const val APPLICATION_STATUS_CREATE_COMPLETED = "application-status-create-completed" + + const val APPLICATION_STATUS_CREATE_FAILED = "application-status-create-failed" + + const val USER_RECEIPT_CODE_UPDATE_FAILED = "user-receipt-code-update-failed" } diff --git a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/consumer/StatusConsumer.kt b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/consumer/StatusConsumer.kt index 5939e86..a5c67bd 100644 --- a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/consumer/StatusConsumer.kt +++ b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/consumer/StatusConsumer.kt @@ -32,13 +32,8 @@ class StatusConsumer( createStatusUseCase.execute(createApplicationEvent.receiptCode) } - /** - * 탈퇴한 유저의 원서 상태를 삭제합니다. - * - * @param message 탈퇴한 유저의 접수 번호 - */ @KafkaListener( - topics = [KafkaTopics.DELETE_USER, KafkaTopics.CANCEL_SUBMITTED_APPLICATION], + topics = [KafkaTopics.DELETE_USER, KafkaTopics.CANCEL_SUBMITTED_APPLICATION, KafkaTopics.USER_RECEIPT_CODE_UPDATE_FAILED], groupId = "delete-status", containerFactory = "kafkaListenerContainerFactory", ) diff --git a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducer.kt b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducer.kt new file mode 100644 index 0000000..9ed959f --- /dev/null +++ b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducer.kt @@ -0,0 +1,6 @@ +package hs.kr.entrydsm.status.infrastructure.kafka.producer + +interface StatusEventProducer { + fun sendStatusCreatedCompleted(receiptCode: Long) + fun sendStatusCreatedFailed(receiptCode: Long) +} \ No newline at end of file diff --git a/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducerImpl.kt b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducerImpl.kt new file mode 100644 index 0000000..8724e79 --- /dev/null +++ b/casper-status/src/main/kotlin/hs/kr/entrydsm/status/infrastructure/kafka/producer/StatusEventProducerImpl.kt @@ -0,0 +1,26 @@ +package hs.kr.entrydsm.status.infrastructure.kafka.producer + +import hs.kr.entrydsm.status.infrastructure.kafka.config.KafkaTopics +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.stereotype.Component + +@Component +class StatusEventProducerImpl( + private val sendStatusCreatedCompletedTemplate: KafkaTemplate, + private val sendStatusCreatedFailedTemplate: KafkaTemplate +) : StatusEventProducer { + + override fun sendStatusCreatedCompleted(receiptCode: Long) { + sendStatusCreatedCompletedTemplate.send( + KafkaTopics.APPLICATION_STATUS_CREATE_COMPLETED, + receiptCode + ) + } + + override fun sendStatusCreatedFailed(receiptCode: Long) { + sendStatusCreatedFailedTemplate.send( + KafkaTopics.APPLICATION_STATUS_CREATE_FAILED, + receiptCode + ) + } +} \ No newline at end of file