Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package hs.kr.entrydsm.status.infrastructure.grpc.server

import com.google.protobuf.Empty
import hs.kr.entrydsm.casper.status.proto.StatusServiceGrpcKt
import hs.kr.entrydsm.casper.status.proto.StatusServiceProto
import hs.kr.entrydsm.status.infrastructure.grpc.server.dto.response.InternalStatusResponse
import hs.kr.entrydsm.status.domain.status.application.port.`in`.GetAllStatusUseCase
import hs.kr.entrydsm.status.domain.status.application.port.`in`.GetStatusByReceiptCodeUseCase
import hs.kr.entrydsm.status.domain.status.application.port.`in`.UpdateExamCodeUseCase
import hs.kr.entrydsm.status.infrastructure.grpc.server.mapper.StatusGrpcMapper
import net.devh.boot.grpc.server.service.GrpcService

/**
* 상태 관련 gRPC 서비스 구현 클래스입니다.
* 다른 마이크로서비스와의 gRPC 통신을 통해 상태 정보를 제공합니다.
*
* @property getStatusByReceiptCodeUseCase 접수번호로 상태 조회 유스케이스
* @property getAllStatusUseCase 모든 상태 조회 유스케이스
* @property updateExamCodeUseCase 수험번호 업데이트 유스케이스
* @property statusGrpcMapper gRPC 메시지 변환 매퍼
*/
@GrpcService
class StatusGrpcService(
private val getStatusByReceiptCodeUseCase: GetStatusByReceiptCodeUseCase,
private val getAllStatusUseCase: GetAllStatusUseCase,
private val updateExamCodeUseCase: UpdateExamCodeUseCase,
private val statusGrpcMapper: StatusGrpcMapper
): StatusServiceGrpcKt.StatusServiceCoroutineImplBase() {

/**
* 모든 상태 리스트를 조회합니다.
*
* @param request Empty 요청
* @return 모든 상태 정보를 포함한 gRPC 응답
*/
override suspend fun getStatusList(request: Empty): StatusServiceProto.GetStatusListResponse {
val statusList = getAllStatusUseCase.execute()

val internalStatusResponseList = statusList.map {
InternalStatusResponse(
id = it.id,
applicationStatus = it.applicationStatus,
examCode = it.examCode,
isFirstRoundPass = it.isFirstRoundPass,
isSecondRoundPass = it.isSecondRoundPass,
receiptCode = it.receiptCode
)
}
return statusGrpcMapper.toGetStatusListResponse(internalStatusResponseList)
}

/**
* 접수번호로 특정 상태를 조회합니다.
*
* @param request 접수번호가 포함된 gRPC 요청
* @return 해당 접수번호의 상태 정보 gRPC 응답
*/
override suspend fun getStatusByReceiptCode(request: StatusServiceProto.GetStatusByReceiptCodeRequest): StatusServiceProto.GetStatusByReceiptCodeResponse {

val status = getStatusByReceiptCodeUseCase.execute(request.receiptCode)

val internalStatusResponse = InternalStatusResponse(
id = status.id,
applicationStatus = status.applicationStatus,
examCode = status.examCode,
isFirstRoundPass = status.isFirstRoundPass,
isSecondRoundPass = status.isSecondRoundPass,
receiptCode = status.receiptCode
)
return statusGrpcMapper.toGetStatusByReceiptCodeResponse(internalStatusResponse)
}

/**
* 수험번호를 업데이트합니다.
*
* @param request 접수번호와 새로운 수험번호가 포함된 gRPC 요청
* @return Empty 응답
*/
override suspend fun updateExamCode(request: StatusServiceProto.GetExamCodeRequest): Empty {

updateExamCodeUseCase.execute(request.receiptCode, request.examCode)
return Empty.getDefaultInstance()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package hs.kr.entrydsm.status.infrastructure.grpc.server.dto.response

import hs.kr.entrydsm.status.domain.status.model.ApplicationStatus

/**
* 내부 gRPC 통신용 상태 응답 DTO 클래스입니다.
* 다른 마이크로서비스와의 통신에서 상태 정보를 전달하는 데 사용됩니다.
*
* @property id 상태 식별자
* @property applicationStatus 현재 지원 상태
* @property examCode 수험번호
* @property isFirstRoundPass 1차 전형 합격 여부
* @property isSecondRoundPass 2차 전형 합격 여부
* @property receiptCode 접수번호
*/
data class InternalStatusResponse(
val id: Long,
val applicationStatus: ApplicationStatus,
var examCode: String? = null,
var isFirstRoundPass: Boolean = false,
var isSecondRoundPass: Boolean = false,
val receiptCode: Long
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package hs.kr.entrydsm.status.infrastructure.grpc.server.mapper

import hs.kr.entrydsm.casper.status.proto.StatusServiceProto
import hs.kr.entrydsm.status.domain.status.model.ApplicationStatus
import hs.kr.entrydsm.status.infrastructure.grpc.server.dto.response.InternalStatusResponse
import org.springframework.stereotype.Component

/**
* 상태 정보를 gRPC 프로토콜 버퍼와 매핑하는 매퍼 클래스입니다.
* 내부 DTO와 gRPC 메시지 간의 변환을 담당합니다.
*/
@Component
class StatusGrpcMapper {

/**
* 상태 리스트를 gRPC 응답으로 변환합니다.
*
* @param statusList 변환할 상태 응답 리스트
* @return gRPC 상태 리스트 응답
*/
fun toGetStatusListResponse(statusList: List<InternalStatusResponse>): StatusServiceProto.GetStatusListResponse {
return StatusServiceProto.GetStatusListResponse.newBuilder()
.addAllStatusList(statusList.map { toStatusInfoElement(it) })
.build()
}

/**
* 단일 상태를 gRPC 응답으로 변환합니다.
*
* @param response 변환할 상태 응답
* @return gRPC 상태 조회 응답
*/
fun toGetStatusByReceiptCodeResponse(response: InternalStatusResponse): StatusServiceProto.GetStatusByReceiptCodeResponse {
return StatusServiceProto.GetStatusByReceiptCodeResponse.newBuilder()
.setStatus(toStatusInfoElement(response))
.build()
}

/**
* 상태 응답을 gRPC 상태 정보 요소로 변환합니다.
*
* @param response 변환할 상태 응답
* @return gRPC 상태 정보 요소
*/
private fun toStatusInfoElement(response: InternalStatusResponse): StatusServiceProto.StatusInfoElement {
return StatusServiceProto.StatusInfoElement.newBuilder()
.setId(response.id)
.setApplicationStatus(toProtoApplicationStatus(response.applicationStatus))
.setExamCode(response.examCode)
.setIsFirstRoundPass(response.isFirstRoundPass)
.setIsSecondRoundPass(response.isSecondRoundPass)
.setReceiptCode(response.receiptCode)
.build()
}

/**
* 도메인 지원 상태를 gRPC 프로토콜 지원 상태로 변환합니다.
*
* @param applicationStatus 변환할 도메인 지원 상태
* @return gRPC 프로토콜 지원 상태
*/
private fun toProtoApplicationStatus(applicationStatus: ApplicationStatus): StatusServiceProto.ApplicationStatus {
return when (applicationStatus){
ApplicationStatus.NOT_APPLIED -> StatusServiceProto.ApplicationStatus.NOT_APPLIED
ApplicationStatus.SUBMITTED -> StatusServiceProto.ApplicationStatus.SUBMITTED
ApplicationStatus.WRITING -> StatusServiceProto.ApplicationStatus.WRITING
ApplicationStatus.WAITING_DOCUMENTS -> StatusServiceProto.ApplicationStatus.WAITING_DOCUMENTS
ApplicationStatus.DOCUMENTS_RECEIVED -> StatusServiceProto.ApplicationStatus.DOCUMENTS_RECEIVED
ApplicationStatus.SCREENING_IN_PROGRESS -> StatusServiceProto.ApplicationStatus.SCREENING_IN_PROGRESS
ApplicationStatus.RESULT_ANNOUNCED -> StatusServiceProto.ApplicationStatus.RESULT_ANNOUNCED
}
}
}
52 changes: 52 additions & 0 deletions casper-status/src/main/proto/status.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
syntax ="proto3";

import "google/protobuf/empty.proto";

package status.proto;

option java_package = "hs.kr.entrydsm.casper.status.proto";
option java_outer_classname = "StatusServiceProto";

service StatusService{
rpc getStatusList(google.protobuf.Empty) returns (GetStatusListResponse);
rpc getStatusByReceiptCode(GetStatusByReceiptCodeRequest) returns (GetStatusByReceiptCodeResponse);
rpc updateExamCode(GetExamCodeRequest) returns (google.protobuf.Empty);
}


message GetStatusListResponse {
repeated StatusInfoElement status_list = 1;
}

message GetStatusByReceiptCodeRequest{
int64 receipt_code = 1;
}

message GetStatusByReceiptCodeResponse{
StatusInfoElement status = 1;
}

message GetExamCodeRequest{
int64 receipt_code = 1;
string examCode = 2;
}

message StatusInfoElement{
int64 id = 1;
ApplicationStatus applicationStatus = 2;
string examCode = 3;
bool isFirstRoundPass = 4;
bool isSecondRoundPass = 5;
int64 receiptCode = 6;
}

enum ApplicationStatus {
UNSPECIFIED = 0;
NOT_APPLIED = 1;
WRITING = 2;
SUBMITTED = 3;
WAITING_DOCUMENTS = 4;
DOCUMENTS_RECEIVED = 5;
SCREENING_IN_PROGRESS = 6;
RESULT_ANNOUNCED = 7;
}
Loading