diff --git a/src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java b/src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java index 42a646e4..27bfaef5 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java +++ b/src/main/java/org/ezcode/codetest/application/submission/dto/event/GitPushStatusEvent.java @@ -1,23 +1,26 @@ package org.ezcode.codetest.application.submission.dto.event; +import org.ezcode.codetest.application.submission.model.SubmissionContext; import org.ezcode.codetest.infrastructure.github.model.PushStatus; public record GitPushStatusEvent( String sessionKey, + String principalName, + PushStatus pushStatus ) { - public static GitPushStatusEvent started(String sessionKey) { - return new GitPushStatusEvent(sessionKey, PushStatus.STARTED); + public static GitPushStatusEvent started(SubmissionContext ctx) { + return new GitPushStatusEvent(ctx.getSessionKey(), ctx.getUserEmail(), PushStatus.STARTED); } - public static GitPushStatusEvent succeeded(String sessionKey) { - return new GitPushStatusEvent(sessionKey, PushStatus.SUCCESS); + public static GitPushStatusEvent succeeded(SubmissionContext ctx) { + return new GitPushStatusEvent(ctx.getSessionKey(), ctx.getUserEmail(), PushStatus.SUCCESS); } - public static GitPushStatusEvent failed(String sessionKey) { - return new GitPushStatusEvent(sessionKey, PushStatus.FAILED); + public static GitPushStatusEvent failed(SubmissionContext ctx) { + return new GitPushStatusEvent(ctx.getSessionKey(), ctx.getUserEmail(), PushStatus.FAILED); } } diff --git a/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java b/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java index 1cca6340..25754967 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java +++ b/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionErrorEvent.java @@ -14,9 +14,9 @@ public SubmissionErrorEvent(String sessionKey, Throwable t) { this(sessionKey, resolveCode(t)); } - private static SubmissionExceptionCode resolveCode(Throwable t) { + private static SubmissionExceptionCode resolveCode(Throwable t) { if (t instanceof SubmissionException se) { - return (SubmissionExceptionCode) se.getResponseCode(); + return (SubmissionExceptionCode)se.getResponseCode(); } return SubmissionExceptionCode.UNKNOWN_ERROR; } diff --git a/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionJudgingFinishedEvent.java b/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionJudgingFinishedEvent.java index 1d31bbcc..92eb01ae 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionJudgingFinishedEvent.java +++ b/src/main/java/org/ezcode/codetest/application/submission/dto/event/SubmissionJudgingFinishedEvent.java @@ -1,12 +1,22 @@ package org.ezcode.codetest.application.submission.dto.event; import org.ezcode.codetest.application.submission.dto.event.payload.SubmissionFinalResultPayload; +import org.ezcode.codetest.application.submission.model.SubmissionContext; public record SubmissionJudgingFinishedEvent( String sessionKey, + String principalName, + SubmissionFinalResultPayload payload ) { + public static SubmissionJudgingFinishedEvent from(SubmissionContext ctx) { + return new SubmissionJudgingFinishedEvent( + ctx.getSessionKey(), + ctx.getUserEmail(), + ctx.toFinalResult() + ); + } } diff --git a/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseEvaluatedEvent.java b/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseEvaluatedEvent.java index 3b8b26ca..35eb9636 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseEvaluatedEvent.java +++ b/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseEvaluatedEvent.java @@ -1,17 +1,21 @@ package org.ezcode.codetest.application.submission.dto.event; import org.ezcode.codetest.application.submission.dto.event.payload.TestcaseResultPayload; +import org.ezcode.codetest.application.submission.model.SubmissionContext; public record TestcaseEvaluatedEvent( String sessionKey, + String principalName, + TestcaseResultPayload payload ) { - public static TestcaseEvaluatedEvent of(String sessionKey, TestcaseResultPayload payload) { + public static TestcaseEvaluatedEvent of(SubmissionContext ctx, TestcaseResultPayload payload) { return new TestcaseEvaluatedEvent( - sessionKey, + ctx.getSessionKey(), + ctx.getUserEmail(), payload ); } diff --git a/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseListInitializedEvent.java b/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseListInitializedEvent.java index 5e0c58de..b781f1a2 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseListInitializedEvent.java +++ b/src/main/java/org/ezcode/codetest/application/submission/dto/event/TestcaseListInitializedEvent.java @@ -3,15 +3,18 @@ import java.util.List; import org.ezcode.codetest.application.submission.dto.event.payload.InitTestcaseListPayload; +import org.ezcode.codetest.application.submission.model.SubmissionContext; public record TestcaseListInitializedEvent( String sessionKey, + String principalName, + List payload ) { - public static TestcaseListInitializedEvent from(String sessionKey, List payload) { - return new TestcaseListInitializedEvent(sessionKey, payload); + public static TestcaseListInitializedEvent of(SubmissionContext ctx, List payload) { + return new TestcaseListInitializedEvent(ctx.getSessionKey(), ctx.getUserEmail(), payload); } } diff --git a/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java b/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java index 0555b2fe..f88ccf83 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java +++ b/src/main/java/org/ezcode/codetest/application/submission/model/SubmissionContext.java @@ -157,4 +157,8 @@ public String getLanguageName() { public String getLanguageVersion() { return language.getVersion(); } + + public String getUserEmail() { + return user.getEmail(); + } } diff --git a/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java b/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java index eb25bed3..8a281d34 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java +++ b/src/main/java/org/ezcode/codetest/application/submission/service/GitHubPushService.java @@ -28,16 +28,16 @@ public void pushSolutionToRepo(SubmissionContext ctx) { return; } - eventService.publishGitPushStatus(GitPushStatusEvent.started(ctx.getSessionKey())); + eventService.publishGitPushStatus(GitPushStatusEvent.started(ctx)); UserGithubInfo info = userGithubService.getUserGithubInfoById(ctx.getUserId()); try { String decryptedToken = aesUtil.decrypt(info.getGithubAccessToken()); gitHubClient.commitAndPushToRepo(GitHubPushRequest.of(ctx, info, decryptedToken)); - eventService.publishGitPushStatus(GitPushStatusEvent.succeeded(ctx.getSessionKey())); + eventService.publishGitPushStatus(GitPushStatusEvent.succeeded(ctx)); } catch (Exception e) { exceptionNotifier.notifyException("commitAndPush", e); - eventService.publishGitPushStatus(GitPushStatusEvent.failed(ctx.getSessionKey())); + eventService.publishGitPushStatus(GitPushStatusEvent.failed(ctx)); } } } diff --git a/src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java b/src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java index 8377f78f..befb6877 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java +++ b/src/main/java/org/ezcode/codetest/application/submission/service/JudgementService.java @@ -42,7 +42,7 @@ public class JudgementService { public void publishInitTestcases(SubmissionContext ctx) { submissionEventService.publishInitTestcases( - new TestcaseListInitializedEvent(ctx.getSessionKey(), InitTestcaseListPayload.from(ctx)) + TestcaseListInitializedEvent.of(ctx, InitTestcaseListPayload.from(ctx)) ); } @@ -90,15 +90,13 @@ private void runTestcaseAsync(int seqId, SubmissionContext ctx) { } private void publishTestcaseUpdate(int seqId, SubmissionContext ctx, boolean isPassed, JudgeResult result) { - submissionEventService.publishTestcaseUpdate(new TestcaseEvaluatedEvent( - ctx.getSessionKey(), TestcaseResultPayload.fromEvaluation(seqId, isPassed, result)) + submissionEventService.publishTestcaseUpdate(TestcaseEvaluatedEvent.of( + ctx, TestcaseResultPayload.fromEvaluation(seqId, isPassed, result)) ); } private void publishFinalResult(SubmissionContext ctx){ - submissionEventService.publishFinalResult( - new SubmissionJudgingFinishedEvent(ctx.getSessionKey(), ctx.toFinalResult()) - ); + submissionEventService.publishFinalResult(SubmissionJudgingFinishedEvent.from(ctx)); } private void publishProblemSolve(SubmissionResult submissionResult) { diff --git a/src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java b/src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java index f4d95f84..cfcacce6 100644 --- a/src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java +++ b/src/main/java/org/ezcode/codetest/application/submission/service/SubmissionService.java @@ -1,9 +1,13 @@ package org.ezcode.codetest.application.submission.service; import java.util.List; +import java.util.Map; import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; import org.ezcode.codetest.application.submission.aop.CodeReviewLock; +import org.ezcode.codetest.application.submission.dto.event.TestcaseListInitializedEvent; +import org.ezcode.codetest.application.submission.dto.event.payload.InitTestcaseListPayload; import org.ezcode.codetest.application.submission.dto.request.review.CodeReviewRequest; import org.ezcode.codetest.application.submission.dto.request.review.ReviewPayload; import org.ezcode.codetest.application.submission.dto.response.review.CodeReviewResponse; @@ -13,6 +17,7 @@ import org.ezcode.codetest.application.submission.port.ExceptionNotifier; import org.ezcode.codetest.application.submission.port.LockManager; import org.ezcode.codetest.application.submission.port.QueueProducer; +import org.ezcode.codetest.domain.problem.model.entity.Testcase; import org.ezcode.codetest.domain.submission.exception.SubmissionException; import org.ezcode.codetest.domain.submission.exception.code.SubmissionExceptionCode; import org.ezcode.codetest.infrastructure.event.dto.submission.SubmissionMessage; @@ -28,6 +33,7 @@ import org.ezcode.codetest.domain.user.model.entity.AuthUser; import org.ezcode.codetest.domain.user.model.entity.User; import org.ezcode.codetest.domain.user.service.UserDomainService; +import org.ezcode.codetest.infrastructure.event.dto.submission.response.InitTestcaseListResponse; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -86,14 +92,6 @@ public void processSubmissionAsync(SubmissionMessage msg) { } } - private SubmissionContext createSubmissionContext(SubmissionMessage msg) { - User user = userDomainService.getUserById(msg.userId()); - Language language = languageDomainService.getLanguage(msg.languageId()); - ProblemInfo problemInfo = problemDomainService.getProblemInfo(msg.problemId()); - - return SubmissionContext.initialize(user, language, problemInfo, msg); - } - @Transactional(readOnly = true) public List getSubmissions(AuthUser authUser) { @@ -116,4 +114,12 @@ public CodeReviewResponse getCodeReview(Long problemId, CodeReviewRequest reques return new CodeReviewResponse(reviewResult.reviewContent()); } + + private SubmissionContext createSubmissionContext(SubmissionMessage msg) { + User user = userDomainService.getUserById(msg.userId()); + Language language = languageDomainService.getLanguage(msg.languageId()); + ProblemInfo problemInfo = problemDomainService.getProblemInfo(msg.problemId()); + + return SubmissionContext.initialize(user, language, problemInfo, msg); + } } diff --git a/src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java b/src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java index 115ab3c0..cb5afed5 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/event/config/WebSocketConfig.java @@ -53,7 +53,7 @@ public void configureMessageBroker(MessageBrokerRegistry registry) { .setUserDestinationBroadcast("/topic/simp-user-registry") .setUserRegistryBroadcast("/topic/simp-user-registry"); - registry.setApplicationDestinationPrefixes("/chat"); + registry.setApplicationDestinationPrefixes("/chat", "/app"); registry.setUserDestinationPrefix("/user"); } diff --git a/src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java b/src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java index 80e02148..f688ac3f 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/event/listener/SubmissionEventListener.java @@ -29,19 +29,19 @@ public class SubmissionEventListener { @EventListener public void onTestcaseInit(TestcaseListInitializedEvent event) { List wsDtos = InitTestcaseListResponse.mapToList(event.payload()); - messageService.sendInitTestcases(event.sessionKey(), wsDtos); + messageService.sendInitTestcases(event.sessionKey(), event.principalName(), wsDtos); } @EventListener public void onTestcaseUpdate(TestcaseEvaluatedEvent event) { JudgeResultResponse wsDto = JudgeResultResponse.from(event.payload()); - messageService.sendTestcaseResultUpdate(event.sessionKey(), wsDto); + messageService.sendTestcaseResultUpdate(event.sessionKey(), event.principalName(), wsDto); } @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) public void onSubmissionFinished(SubmissionJudgingFinishedEvent event) { SubmissionFinalResultResponse wsDto = SubmissionFinalResultResponse.from(event.payload()); - messageService.sendFinalResult(event.sessionKey(), wsDto); + messageService.sendFinalResult(event.sessionKey(), event.principalName(), wsDto); } @EventListener @@ -53,6 +53,6 @@ public void onSubmissionError(SubmissionErrorEvent event) { @EventListener public void onGitPushStatus(GitPushStatusEvent event) { GitPushStatusResponse wsDto = new GitPushStatusResponse(event.pushStatus()); - messageService.sendGitStatus(event.sessionKey(), wsDto); + messageService.sendGitStatus(event.sessionKey(), event.principalName(), wsDto); } } diff --git a/src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java b/src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java index 853f2509..3b1f5205 100644 --- a/src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java +++ b/src/main/java/org/ezcode/codetest/infrastructure/event/publisher/StompMessageService.java @@ -9,6 +9,11 @@ import org.springframework.messaging.simp.SimpMessageType; import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Component; @@ -21,7 +26,7 @@ public class StompMessageService { private final SimpMessagingTemplate messagingTemplate; - private static final String SUBMISSION_DEST_PREFIX = "/topic/submission/%s"; + private static final String SUBMISSION_DEST_PREFIX = "/queue/submission/%s"; public void handleChatRoomListLoad(T roomData, String principalName, String sessionId) { @@ -55,41 +60,59 @@ public void handleChatRoomHistoryLoad(T chatData, String principalName, Stri ); } - public void sendInitTestcases(String sessionKey, List dataList) { - - messagingTemplate.convertAndSend( + public void sendInitTestcases( + String sessionKey, + String principalName, + List dataList + ) { + messagingTemplate.convertAndSendToUser( + principalName, SUBMISSION_DEST_PREFIX.formatted(sessionKey) + "/init", dataList ); } - public void sendTestcaseResultUpdate(String sessionKey, JudgeResultResponse data) { - - messagingTemplate.convertAndSend( + public void sendTestcaseResultUpdate( + String sessionKey, + String principalName, + JudgeResultResponse data + ) { + messagingTemplate.convertAndSendToUser( + principalName, SUBMISSION_DEST_PREFIX.formatted(sessionKey) + "/case", data ); } - public void sendFinalResult(String sessionKey, SubmissionFinalResultResponse data) { - - messagingTemplate.convertAndSend( + public void sendFinalResult( + String sessionKey, + String principalName, + SubmissionFinalResultResponse data + ) { + messagingTemplate.convertAndSendToUser( + principalName, SUBMISSION_DEST_PREFIX.formatted(sessionKey) + "/final", data ); } - public void sendError(String sessionKey, ErrorWsResponse data) { - + public void sendError( + String sessionKey, + ErrorWsResponse data + ) { messagingTemplate.convertAndSend( SUBMISSION_DEST_PREFIX.formatted(sessionKey) + "/error", data ); } - public void sendGitStatus(String sessionKey, GitPushStatusResponse data) { - - messagingTemplate.convertAndSend( + public void sendGitStatus( + String sessionKey, + String principalName, + GitPushStatusResponse data + ) { + messagingTemplate.convertAndSendToUser( + principalName, SUBMISSION_DEST_PREFIX.formatted(sessionKey) + "/git-status", data ); @@ -109,5 +132,4 @@ public void handleChatRoomParticipantCountChange(T roomData) { messagingTemplate.convertAndSend("/topic/chatrooms", roomData); } - } diff --git a/src/main/java/org/ezcode/codetest/presentation/submission/SubmissionController.java b/src/main/java/org/ezcode/codetest/presentation/submission/SubmissionController.java index af154e60..e865baf6 100644 --- a/src/main/java/org/ezcode/codetest/presentation/submission/SubmissionController.java +++ b/src/main/java/org/ezcode/codetest/presentation/submission/SubmissionController.java @@ -47,15 +47,15 @@ public class SubmissionController { 반환된 sessionKey를 사용해 다음 경로로 구독하세요. - • /topic/submission/{sessionKey}/init + • /user/queue/submission/{sessionKey}/init - • /topic/submission/{sessionKey}/case + • /user/queue/submission/{sessionKey}/case - • /topic/submission/{sessionKey}/final + • /user/queue/submission/{sessionKey}/final • /topic/submission/{sessionKey}/error - • /topic/submission/{sessionKey}/git-status + • /user/queue/submission/{sessionKey}/git-status """ ) @ApiResponses({ diff --git a/src/main/resources/templates/submit-test.html b/src/main/resources/templates/submit-test.html index 63399072..580f829e 100644 --- a/src/main/resources/templates/submit-test.html +++ b/src/main/resources/templates/submit-test.html @@ -255,7 +255,7 @@ } // (B) sessionKey별 채널 구독 - const base = `/topic/submission/${sessionKey}`; + const base = `/user/queue/submission/${sessionKey}`; stompClient.subscribe(`${base}/init`, msg => handleInit(JSON.parse(msg.body))); stompClient.subscribe(`${base}/case`, msg => handleCase(JSON.parse(msg.body))); stompClient.subscribe(`${base}/final`, msg => handleFinal(JSON.parse(msg.body)));