From 193ffb6be533500b775669ca6470540adc80da31 Mon Sep 17 00:00:00 2001 From: yoon6yo Date: Sat, 18 Jul 2026 18:37:34 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=8B=A0=EC=B2=AD/=EB=B3=80=EA=B2=BD=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EA=B1=B0=EC=A0=88=20=EC=8B=9C=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EC=9D=B4=EB=A9=94=EC=9D=BC=20=EB=B0=9C=EC=86=A1=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#376)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 관리자 신청/변경 요청 거절 시 사용자 이메일 발송 추가 - 신청 거절(rejectRequest): 서버명·거절 사유 포함 이메일 발송 - 변경 요청 거절(rejectModification): 변경 유형·거절 사유 포함 이메일 발송 - AlarmService에 sendRequestRejectedEmail, sendModificationRejectedEmail 추가 - messages.properties에 거절 안내 메일 템플릿 추가 (항목 9, 10) * test: 거절 이메일 발송 테스트 추가 AlarmServiceTest - sendRequestRejectedEmail: 이메일 수신자·제목 검증, noti 채널 로그 적재 검증, 메일 실패 시 에러 Slack 발송 검증 - sendModificationRejectedEmail: 동일 패턴 + 변경 유형 제목 포함 여부 검증 AdminRequestCommandServiceTest - rejectRequest: 성공 시 sendRequestRejectedEmail 호출 검증, 사유 전달 검증, 실패 시 미발송 검증 - rejectModification: 성공 시 sendModificationRejectedEmail 호출 검증, 사유 전달 검증, 실패 시 미발송 검증 --- .../domain/alarm/service/AlarmService.java | 29 ++++ .../service/AdminRequestCommandService.java | 2 + src/main/resources/messages.properties | 25 ++++ .../alarm/service/AlarmServiceTest.java | 141 ++++++++++++++++++ .../AdminRequestCommandServiceTest.java | 76 ++++++++++ 5 files changed, 273 insertions(+) diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java index 8c7f38c8..0fccf8fe 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java @@ -7,6 +7,7 @@ import java.util.stream.Collectors; import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; +import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeRequest; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; import DGU_AI_LAB.admin_be.domain.users.entity.User; import DGU_AI_LAB.admin_be.global.util.MessageUtils; @@ -220,6 +221,34 @@ private String formatPortSummary(List ports) { .collect(Collectors.joining(", ")); } + public void sendRequestRejectedEmail(Request request, String adminComment) { + User user = request.getUser(); + String serverName = request.getResourceGroup().getServerName(); + + String subject = messageUtils.get("email.request.rejected.subject", serverName); + String body = messageUtils.get("email.request.rejected.body", + user.getName(), // {0} + serverName, // {1} + adminComment); // {2} + + sendMailAlert(user.getEmail(), subject, body); + sendMonitoringLog(user.getName(), user.getEmail(), subject); + } + + public void sendModificationRejectedEmail(ChangeRequest changeRequest, String adminComment) { + User user = changeRequest.getRequestedBy(); + String changeType = changeRequest.getChangeType().name(); + + String subject = messageUtils.get("email.modification.rejected.subject", changeType); + String body = messageUtils.get("email.modification.rejected.body", + user.getName(), // {0} + changeType, // {1} + adminComment); // {2} + + sendMailAlert(user.getEmail(), subject, body); + sendMonitoringLog(user.getName(), user.getEmail(), subject); + } + public void sendAdminSlackNotification(String serverName, String message) { sendSlackAlert(message, getAdminWebhookUrl(serverName)); } diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java index a4c07f9d..140068b3 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java @@ -219,6 +219,7 @@ public SaveRequestResponseDTO rejectRequest(RejectRequestDTO dto) { throw new BusinessException(ErrorCode.INVALID_REQUEST_STATUS); } request.reject(dto.adminComment()); + alarmService.sendRequestRejectedEmail(request, dto.adminComment()); return SaveRequestResponseDTO.fromEntity(request); } @@ -236,6 +237,7 @@ public void rejectModification(Long adminId, RejectModificationDTO dto) { .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); changeRequest.deny(admin, dto.adminComment()); + alarmService.sendModificationRejectedEmail(changeRequest, dto.adminComment()); } @Transactional diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 1aa0f564..77137bda 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -123,6 +123,31 @@ email.container.created.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uA - \uC11C\uBC84 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uC624\uB294 \uAC1C\uBCC4 \uC5F0\uB77D(DM, \uCE74\uCE74\uC624\uD1A1 \uB4F1)\uC740 \uB2F5\uBCC0\uB4DC\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.\n\ \n\uB9C8\uC9C0\uB9C9\uC73C\uB85C, \uC0AC\uC6A9\uC790\uBD84\uC758 \uB370\uC774\uD130\uB294 \uC2DC\uC2A4\uD15C\uC5D0\uC11C \uBC31\uC5C5\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uAC1C\uC778\uC801\uC778 \uB370\uC774\uD130\uB294 \uBAA8\uB450 \uBC31\uC5C5\uD558\uC2DC\uAE30 \uBC14\uB78D\uB2C8\uB2E4. \uAC10\uC0AC\uD569\uB2C8\uB2E4! +# ============================================================================== +# 9. \uC2E0\uCCAD \uAC70\uC808 \uC548\uB0B4 \uBA54\uC77C \u2014 email.request.rejected +# ============================================================================== +# subject: {0}: \uC11C\uBC84\uBA85 +email.request.rejected.subject=[DGU AILab] \uC11C\uBC84 \uC2E0\uCCAD \uAC70\uC808 \uC548\uB0B4 ({0}) + +# {0}: \uC774\uB984, {1}: \uC11C\uBC84\uBA85, {2}: \uAC70\uC808 \uC0AC\uC720 +email.request.rejected.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uAD6D\uB300\uD559\uAD50 \uC11C\uBC84\uAD00\uB9AC\uD300\uC785\uB2C8\uB2E4.\n\ + \n\uC2E0\uCCAD\uD558\uC2E0 GPU \uC11C\uBC84 \uC0AC\uC6A9 \uC694\uCCAD\uC774 \uAC70\uC808\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\ + \n- \uC11C\uBC84: {1}\n\ + - \uAC70\uC808 \uC0AC\uC720: {2}\n\ + \n\uBB38\uC758\uAC00 \uC788\uC73C\uC2DC\uBA74 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD574 \uC8FC\uC138\uC694. + +# ============================================================================== +# 10. \uBCC0\uACBD \uC694\uCCAD \uAC70\uC808 \uC548\uB0B4 \uBA54\uC77C \u2014 email.modification.rejected +# ============================================================================== +# subject: {0}: \uBCC0\uACBD \uC720\uD615 +email.modification.rejected.subject=[DGU AILab] \uC11C\uBC84 \uBCC0\uACBD \uC694\uCCAD \uAC70\uC808 \uC548\uB0B4 ({0}) + +# {0}: \uC774\uB984, {1}: \uBCC0\uACBD \uC720\uD615, {2}: \uAC70\uC808 \uC0AC\uC720 +email.modification.rejected.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uAD6D\uB300\uD559\uAD50 \uC11C\uBC84\uAD00\uB9AC\uD300\uC785\uB2C8\uB2E4.\n\ + \n\uC694\uCCAD\uD558\uC2E0 \uC11C\uBC84 \uBCC0\uACBD ({1}) \uC694\uCCAD\uC774 \uAC70\uC808\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\ + \n- \uAC70\uC808 \uC0AC\uC720: {2}\n\ + \n\uBB38\uC758\uAC00 \uC788\uC73C\uC2DC\uBA74 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD574 \uC8FC\uC138\uC694. + # ============================================================================== # 7. \uAD00\uB9AC\uC790 \uC218\uB3D9 \uC0AD\uC81C \uC548\uB0B4 \uBA54\uC77C \u2014 email.container.deleted # ============================================================================== diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java index 2acb33a9..239f1777 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java @@ -1,10 +1,13 @@ package DGU_AI_LAB.admin_be.domain.alarm.service; import DGU_AI_LAB.admin_be.domain.alarm.dto.SlackMessageDto; +import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeRequest; +import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeType; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; import DGU_AI_LAB.admin_be.domain.resourceGroups.entity.ResourceGroup; import DGU_AI_LAB.admin_be.domain.users.entity.User; import DGU_AI_LAB.admin_be.global.util.MessageUtils; +import org.springframework.mail.SimpleMailMessage; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -246,6 +249,122 @@ void sendAllAlerts_continuesWithDM_whenMailFails() { } } + @Nested + @DisplayName("sendRequestRejectedEmail") + class SendRequestRejectedEmail { + + @Test + @DisplayName("사용자에게 거절 이메일이 발송된다") + void sendRequestRejectedEmail_sendsMailToUser() { + Request request = mockRequest("홍길동", "hong@dgu.ac.kr", "FARM"); + when(messageUtils.get(anyString(), any())).thenReturn("[DGU AILab] 서버 신청 거절 안내 (FARM)"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("거절 안내 본문"); + + alarmService.sendRequestRejectedEmail(request, "신청서 양식 미흡"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SimpleMailMessage.class); + verify(mailSender).send(captor.capture()); + assertThat(captor.getValue().getTo()).containsExactly("hong@dgu.ac.kr"); + assertThat(captor.getValue().getSubject()).isEqualTo("[DGU AILab] 서버 신청 거절 안내 (FARM)"); + } + + @Test + @DisplayName("거절 이메일 발송 후 noti 채널에 모니터링 로그가 적재된다") + void sendRequestRejectedEmail_pushesMonitoringLogToNotiChannel() { + Request request = mockRequest("홍길동", "hong@dgu.ac.kr", "FARM"); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + + alarmService.sendRequestRejectedEmail(request, "신청서 양식 미흡"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getValue().getWebhookUrl()).isEqualTo(NOTI_WEBHOOK); + assertThat(captor.getValue().getType()).isEqualTo(SlackMessageDto.MessageType.WEBHOOK); + } + + @Test + @DisplayName("메일 전송 실패 시 에러 Slack 알림이 발송된다") + void sendRequestRejectedEmail_sendsSlackError_whenMailFails() { + Request request = mockRequest("홍길동", "hong@dgu.ac.kr", "FARM"); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + doThrow(new RuntimeException("SMTP 오류")).when(mailSender).send(any(SimpleMailMessage.class)); + + alarmService.sendRequestRejectedEmail(request, "신청서 양식 미흡"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations, atLeastOnce()).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getAllValues()).anyMatch(dto -> + dto.getWebhookUrl().equals(ERROR_WEBHOOK)); + } + } + + @Nested + @DisplayName("sendModificationRejectedEmail") + class SendModificationRejectedEmail { + + @Test + @DisplayName("사용자에게 변경 요청 거절 이메일이 발송된다") + void sendModificationRejectedEmail_sendsMailToUser() { + ChangeRequest changeRequest = mockChangeRequest("이순신", "lee@dgu.ac.kr", ChangeType.EXPIRES_AT); + when(messageUtils.get(anyString(), any())).thenReturn("[DGU AILab] 서버 변경 요청 거절 안내 (EXPIRES_AT)"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("변경 거절 안내 본문"); + + alarmService.sendModificationRejectedEmail(changeRequest, "변경 사유 불충분"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SimpleMailMessage.class); + verify(mailSender).send(captor.capture()); + assertThat(captor.getValue().getTo()).containsExactly("lee@dgu.ac.kr"); + assertThat(captor.getValue().getSubject()).isEqualTo("[DGU AILab] 서버 변경 요청 거절 안내 (EXPIRES_AT)"); + } + + @Test + @DisplayName("변경 요청 거절 이메일 발송 후 noti 채널에 모니터링 로그가 적재된다") + void sendModificationRejectedEmail_pushesMonitoringLogToNotiChannel() { + ChangeRequest changeRequest = mockChangeRequest("이순신", "lee@dgu.ac.kr", ChangeType.EXPIRES_AT); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + + alarmService.sendModificationRejectedEmail(changeRequest, "변경 사유 불충분"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getValue().getWebhookUrl()).isEqualTo(NOTI_WEBHOOK); + } + + @Test + @DisplayName("변경 유형이 이메일 제목에 포함된다") + void sendModificationRejectedEmail_includesChangeTypeInSubject() { + ChangeRequest changeRequest = mockChangeRequest("김철수", "kim@dgu.ac.kr", ChangeType.VOLUME_SIZE); + when(messageUtils.get(eq("email.modification.rejected.subject"), eq("VOLUME_SIZE"))) + .thenReturn("[DGU AILab] 서버 변경 요청 거절 안내 (VOLUME_SIZE)"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendModificationRejectedEmail(changeRequest, "볼륨 변경 불가"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SimpleMailMessage.class); + verify(mailSender).send(captor.capture()); + assertThat(captor.getValue().getSubject()).contains("VOLUME_SIZE"); + } + + @Test + @DisplayName("메일 전송 실패 시 에러 Slack 알림이 발송된다") + void sendModificationRejectedEmail_sendsSlackError_whenMailFails() { + ChangeRequest changeRequest = mockChangeRequest("이순신", "lee@dgu.ac.kr", ChangeType.EXPIRES_AT); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + doThrow(new RuntimeException("SMTP 오류")).when(mailSender).send(any(SimpleMailMessage.class)); + + alarmService.sendModificationRejectedEmail(changeRequest, "변경 사유 불충분"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations, atLeastOnce()).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getAllValues()).anyMatch(dto -> + dto.getWebhookUrl().equals(ERROR_WEBHOOK)); + } + } + private Request mockRequest(String userName, String serverName) { User user = mock(User.class); when(user.getName()).thenReturn(userName); @@ -256,4 +375,26 @@ private Request mockRequest(String userName, String serverName) { when(request.getResourceGroup()).thenReturn(rg); return request; } + + private Request mockRequest(String userName, String email, String serverName) { + User user = mock(User.class); + when(user.getName()).thenReturn(userName); + when(user.getEmail()).thenReturn(email); + ResourceGroup rg = mock(ResourceGroup.class); + when(rg.getServerName()).thenReturn(serverName); + Request request = mock(Request.class); + when(request.getUser()).thenReturn(user); + when(request.getResourceGroup()).thenReturn(rg); + return request; + } + + private ChangeRequest mockChangeRequest(String userName, String email, ChangeType changeType) { + User user = mock(User.class); + when(user.getName()).thenReturn(userName); + when(user.getEmail()).thenReturn(email); + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getRequestedBy()).thenReturn(user); + when(changeRequest.getChangeType()).thenReturn(changeType); + return changeRequest; + } } diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java index 633d0243..03a06ee0 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java @@ -428,6 +428,41 @@ void rejectRequest_throwsException_whenStatusIsDeleted() { assertThatThrownBy(() -> service.rejectRequest(dto)) .isInstanceOf(BusinessException.class); } + + @Test + @DisplayName("거절 성공 시 alarmService.sendRequestRejectedEmail이 호출된다") + void rejectRequest_sendsRejectionEmail_onSuccess() { + Request request = buildMockedRequestWithStatus(35L, Status.PENDING); + RejectRequestDTO dto = new RejectRequestDTO(35L, "신청서 양식 미흡"); + + service.rejectRequest(dto); + + verify(alarmService).sendRequestRejectedEmail(request, "신청서 양식 미흡"); + } + + @Test + @DisplayName("거절 사유가 이메일 발송 메서드에 그대로 전달된다") + void rejectRequest_passesAdminCommentToEmail() { + Request request = buildMockedRequestWithStatus(36L, Status.PENDING); + String comment = "서버 정원 초과로 인한 거절"; + RejectRequestDTO dto = new RejectRequestDTO(36L, comment); + + service.rejectRequest(dto); + + verify(alarmService).sendRequestRejectedEmail(request, comment); + } + + @Test + @DisplayName("유효하지 않은 상태로 거절 시 이메일이 발송되지 않는다") + void rejectRequest_doesNotSendEmail_whenStatusIsInvalid() { + buildMockedRequestWithStatus(37L, Status.DENIED); + RejectRequestDTO dto = new RejectRequestDTO(37L, "사유"); + + assertThatThrownBy(() -> service.rejectRequest(dto)) + .isInstanceOf(BusinessException.class); + + verify(alarmService, never()).sendRequestRejectedEmail(any(), anyString()); + } } // ────────────────────────────────────────────────────────────────────── @@ -490,6 +525,47 @@ void rejectModification_throwsException_whenAdminNotFound() { assertThatThrownBy(() -> service.rejectModification(999L, dto)) .isInstanceOf(BusinessException.class); } + + @Test + @DisplayName("변경 요청 거절 성공 시 alarmService.sendModificationRejectedEmail이 호출된다") + void rejectModification_sendsRejectionEmail_onSuccess() { + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequestRepository.findById(10L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + + RejectModificationDTO dto = new RejectModificationDTO(10L, "변경 사유 불충분"); + service.rejectModification(100L, dto); + + verify(alarmService).sendModificationRejectedEmail(changeRequest, "변경 사유 불충분"); + } + + @Test + @DisplayName("거절 사유가 이메일 발송 메서드에 그대로 전달된다") + void rejectModification_passesAdminCommentToEmail() { + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequestRepository.findById(11L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + String comment = "리소스 여유 없음"; + + service.rejectModification(100L, new RejectModificationDTO(11L, comment)); + + verify(alarmService).sendModificationRejectedEmail(changeRequest, comment); + } + + @Test + @DisplayName("PENDING이 아닌 상태에서 거절 시 이메일이 발송되지 않는다") + void rejectModification_doesNotSendEmail_whenStatusIsNotPending() { + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getStatus()).thenReturn(Status.FULFILLED); + when(changeRequestRepository.findById(12L)).thenReturn(Optional.of(changeRequest)); + + assertThatThrownBy(() -> service.rejectModification(100L, new RejectModificationDTO(12L, "사유"))) + .isInstanceOf(BusinessException.class); + + verify(alarmService, never()).sendModificationRejectedEmail(any(), anyString()); + } } // ────────────────────────────────────────────────────────────────────── From 4ac99a8134bd2d8225c092316ffa9405b66bb184 Mon Sep 17 00:00:00 2001 From: yoon6yo Date: Sat, 18 Jul 2026 18:49:00 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=BB=A8=ED=85=8C=EC=9D=B4?= =?UTF-8?q?=EB=84=88=20=EB=B0=B0=EC=A0=95=20=EC=9D=B4=EB=A9=94=EC=9D=BC?= =?UTF-8?q?=EC=97=90=20=EC=B6=94=EA=B0=80=20=ED=8F=AC=ED=8A=B8=20=EB=B0=8F?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EB=A7=A4=EB=89=B4=EC=96=BC=20?= =?UTF-8?q?=EC=84=B9=EC=85=98=20=EC=B6=94=EA=B0=80=20(#377)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [서버 정보] 섹션에 SSH·Jupyter 외 추가 포트 항목({7}) 표시 (없을 시 '없음') - [초기 설정] 이후 [사용자 매뉴얼] 섹션 삽입 (Google Slides 링크) - AlarmService.sendContainerCreatedEmail(): PodExternalPort 조회 후 ssh/jupyter를 제외한 추가 포트를 계산하여 메일 본문에 포함 - AlarmServiceTest: SendContainerCreatedEmail 테스트 5건 추가 --- .../domain/alarm/service/AlarmService.java | 10 +- src/main/resources/messages.properties | 5 +- .../alarm/service/AlarmServiceTest.java | 127 ++++++++++++++++++ 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java index 0fccf8fe..bdbc4beb 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java @@ -147,6 +147,13 @@ public void sendContainerCreatedEmail(Request request, String sshPort, String ju var image = request.getContainerImage(); String serverName = request.getResourceGroup().getServerName(); + List allPorts = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); + String extraPorts = allPorts.stream() + .filter(p -> !"ssh".equalsIgnoreCase(p.getUsagePurpose()) && !"jupyter".equalsIgnoreCase(p.getUsagePurpose())) + .map(p -> p.getUsagePurpose() + "(" + p.getExternalPort() + ")") + .collect(Collectors.joining(", ")); + if (extraPorts.isEmpty()) extraPorts = "없음"; + String subject = messageUtils.get("email.container.created.subject", serverName); String body = messageUtils.get("email.container.created.body", user.getName(), // {0} @@ -155,7 +162,8 @@ public void sendContainerCreatedEmail(Request request, String sshPort, String ju sshPort, // {3} jupyterPort, // {4} resolveHostIp(serverName), // {5} - request.getUbuntuPassword()); // {6} + request.getUbuntuPassword(), // {6} + extraPorts); // {7} sendMailAlert(user.getEmail(), subject, body); sendMonitoringLog(user.getName(), user.getEmail(), subject); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 77137bda..2799914b 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -91,7 +91,7 @@ notification.user.soft-delete.body=\uC548\uB155\uD558\uC138\uC694, {0}\uB2D8.\n\ # subject {0}: \uC11C\uBC84\uBA85(FARM/LAB) email.container.created.subject=[DGU AILab] \uC11C\uBC84 \uBC30\uC815 \uC548\uB0B4 ({0}) -# {0}: \uC774\uB984, {1}: \uC774\uBBF8\uC9C0:\uBC84\uC804, {2}: username, {3}: SSH \uD3EC\uD2B8, {4}: Jupyter \uD3EC\uD2B8, {5}: \uC811\uC18D IP, {6}: \uCD08\uAE30 \uBE44\uBC00\uBC88\uD638 +# {0}: \uC774\uB984, {1}: \uC774\uBBF8\uC9C0:\uBC84\uC804, {2}: username, {3}: SSH \uD3EC\uD2B8, {4}: Jupyter \uD3EC\uD2B8, {5}: \uC811\uC18D IP, {6}: \uCD08\uAE30 \uBE44\uBC00\uBC88\uD638, {7}: \uCD94\uAC00 \uD3EC\uD2B8 # \uD3EC\uD2B8\uB294 \uBB38\uC790\uC5F4\uB85C \uC804\uB2EC(\uC22B\uC790\uD615\uC774\uBA74 MessageFormat\uAC00 30,888\uCC98\uB7FC \uCF64\uB9C8\uB97C \uB123\uC74C) email.container.created.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uAD6D\uB300\uD559\uAD50 \uC11C\uBC84\uAD00\uB9AC\uD300\uC785\uB2C8\uB2E4.\n\ \n\uC11C\uBC84 \uBC30\uC815\uC774 \uC644\uB8CC\uB418\uC5C8\uC73C\uBA70, \uBC30\uC815\uB41C \uC11C\uBC84\uC758 \uC815\uBCF4\uB294 \uB2E4\uC74C\uACFC \uAC19\uC2B5\uB2C8\uB2E4.\n\ @@ -100,6 +100,7 @@ email.container.created.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uA - \uC811\uC18D \uC544\uC774\uB514(username): {2}\n\ - SSH \uD3EC\uD2B8\uBC88\uD638: {3}\n\ - JUPYTER \uD3EC\uD2B8\uBC88\uD638: {4}\n\ + - \uCD94\uAC00 \uD3EC\uD2B8: {7}\n\ \n[\uC811\uC18D \uC815\uBCF4]\n\ - SSH \uC811\uC18D \uBA85\uB839\uC5B4: ssh -p {3} {2}@{5}\n\ - SSH/Ubuntu \uCD08\uAE30 \uBE44\uBC00\uBC88\uD638: {6}\n\ @@ -110,6 +111,8 @@ email.container.created.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uA - 24\uC2DC\uAC04 \uB0B4\uC5D0 \uBCC0\uACBD\uD558\uC9C0 \uC54A\uC744 \uACBD\uC6B0 \uCEE8\uD14C\uC774\uB108\uAC00 \uACBD\uACE0\uC5C6\uC774 \uC0AD\uC81C\uB420 \uC218 \uC788\uC2B5\uB2C8\uB2E4.\n\ - SSH/Ubuntu \uBE44\uBC00\uBC88\uD638 \uBCC0\uACBD \uBC29\uBC95: sudo passwd {2}\n\ - JupyterLab Password\uB3C4 \uC81C\uACF5\uB41C token \uAC12\uC744 \uC0AC\uC6A9\uD558\uC5EC \uBCC0\uACBD\uD574\uC8FC\uC138\uC694.\n\ + \n[\uC0AC\uC6A9\uC790 \uB9E4\uB274\uC5BC]\n\ + - https://docs.google.com/presentation/d/1tu9vUQRd0HBaVrwPLDzo0QJ5vEg4FnjI/edit?usp=sharing&ouid=104298167984129919697&rtpof=true&sd=true\n\ \n[\uBB38\uC758 \uBC0F \uC624\uB958 \uC2E0\uACE0]\n\ - \uC624\uB958 \uC2E0\uACE0, \uCEE8\uD14C\uC774\uB108 \uC0AC\uC6A9 \uAE30\uD55C \uC5F0\uC7A5, \uAE30\uD0C0 \uC9C8\uBB38\uC740 \uC544\uB798 \uAD6C\uAE00 \uD3FC\uC73C\uB85C \uC2E0\uCCAD\uD574\uC8FC\uC138\uC694.\n\ - \uAD6C\uAE00 \uD3FC: https://forms.gle/nACaxj2UeJF56V2i7\n\ diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java index 239f1777..4ae1fba8 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java @@ -1,6 +1,9 @@ package DGU_AI_LAB.admin_be.domain.alarm.service; import DGU_AI_LAB.admin_be.domain.alarm.dto.SlackMessageDto; +import DGU_AI_LAB.admin_be.domain.containerImage.entity.ContainerImage; +import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; +import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeRequest; import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeType; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; @@ -51,6 +54,9 @@ class AlarmServiceTest { @Mock private MessageUtils messageUtils; + @Mock + private PodExternalPortRepository podExternalPortRepository; + @Mock private ListOperations listOperations; @@ -249,6 +255,101 @@ void sendAllAlerts_continuesWithDM_whenMailFails() { } } + @Nested + @DisplayName("sendContainerCreatedEmail") + class SendContainerCreatedEmail { + + @Test + @DisplayName("추가 포트가 없을 때 '없음'으로 메일이 발송된다") + void sendContainerCreatedEmail_sendsMailWithNoExtraPorts() { + Request request = mockRequestForCreated("홍길동", "hong@dgu.ac.kr", "LAB", 1L); + when(podExternalPortRepository.findByRequestRequestId(1L)).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("[DGU AILab] 서버 배정 안내 (LAB)"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn("배정 안내 본문 (추가 포트: 없음)"); + + alarmService.sendContainerCreatedEmail(request, "9100", "9104"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SimpleMailMessage.class); + verify(mailSender).send(captor.capture()); + assertThat(captor.getValue().getTo()).containsExactly("hong@dgu.ac.kr"); + } + + @Test + @DisplayName("추가 포트가 있을 때 포트 목록이 포함되어 발송된다") + void sendContainerCreatedEmail_sendsMailWithExtraPorts() { + Request request = mockRequestForCreated("이순신", "lee@dgu.ac.kr", "FARM", 2L); + PodExternalPort sshPort = mockPodPort("ssh", 9100); + PodExternalPort jupyterPort = mockPodPort("jupyter", 9104); + PodExternalPort tensorPort = mockPodPort("tensorboard", 9200); + when(podExternalPortRepository.findByRequestRequestId(2L)) + .thenReturn(List.of(sshPort, jupyterPort, tensorPort)); + when(messageUtils.get(anyString(), any())).thenReturn("[DGU AILab] 서버 배정 안내 (FARM)"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn("배정 안내 본문 (추가 포트: tensorboard(9200))"); + + alarmService.sendContainerCreatedEmail(request, "9100", "9104"); + + // ssh, jupyter 필터링 후 tensorboard만 {7}로 전달되는지 검증 + verify(messageUtils).get(eq("email.container.created.body"), + any(), any(), any(), eq("9100"), eq("9104"), any(), any(), eq("tensorboard(9200)")); + } + + @Test + @DisplayName("ssh와 jupyter는 추가 포트에서 제외된다") + void sendContainerCreatedEmail_excludesSshAndJupyterFromExtraPorts() { + Request request = mockRequestForCreated("김철수", "kim@dgu.ac.kr", "LAB", 3L); + PodExternalPort sshPort = mockPodPort("ssh", 9100); + PodExternalPort jupyterPort = mockPodPort("jupyter", 9104); + when(podExternalPortRepository.findByRequestRequestId(3L)) + .thenReturn(List.of(sshPort, jupyterPort)); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn("본문"); + + alarmService.sendContainerCreatedEmail(request, "9100", "9104"); + + verify(messageUtils).get(eq("email.container.created.body"), + any(), any(), any(), any(), any(), any(), any(), eq("없음")); + } + + @Test + @DisplayName("메일 발송 후 noti 채널에 모니터링 로그가 적재된다") + void sendContainerCreatedEmail_pushesMonitoringLogToNotiChannel() { + Request request = mockRequestForCreated("홍길동", "hong@dgu.ac.kr", "LAB", 4L); + when(podExternalPortRepository.findByRequestRequestId(4L)).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn("본문"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + + alarmService.sendContainerCreatedEmail(request, "9100", "9104"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getValue().getWebhookUrl()).isEqualTo(NOTI_WEBHOOK); + } + + @Test + @DisplayName("메일 전송 실패 시 에러 Slack 알림이 발송된다") + void sendContainerCreatedEmail_sendsSlackError_whenMailFails() { + Request request = mockRequestForCreated("홍길동", "hong@dgu.ac.kr", "LAB", 5L); + when(podExternalPortRepository.findByRequestRequestId(5L)).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any(), any())) + .thenReturn("본문"); + when(messageUtils.get(anyString(), any(), any(), any())).thenReturn("로그"); + doThrow(new RuntimeException("SMTP 오류")).when(mailSender).send(any(SimpleMailMessage.class)); + + alarmService.sendContainerCreatedEmail(request, "9100", "9104"); + + ArgumentCaptor captor = ArgumentCaptor.forClass(SlackMessageDto.class); + verify(listOperations, atLeastOnce()).rightPush(eq(QUEUE_KEY), captor.capture()); + assertThat(captor.getAllValues()).anyMatch(dto -> + dto.getWebhookUrl().equals(ERROR_WEBHOOK)); + } + } + @Nested @DisplayName("sendRequestRejectedEmail") class SendRequestRejectedEmail { @@ -397,4 +498,30 @@ private ChangeRequest mockChangeRequest(String userName, String email, ChangeTyp when(changeRequest.getChangeType()).thenReturn(changeType); return changeRequest; } + + private Request mockRequestForCreated(String userName, String email, String serverName, Long requestId) { + User user = mock(User.class); + when(user.getName()).thenReturn(userName); + when(user.getEmail()).thenReturn(email); + ResourceGroup rg = mock(ResourceGroup.class); + when(rg.getServerName()).thenReturn(serverName); + ContainerImage image = mock(ContainerImage.class); + when(image.getImageName()).thenReturn("ubuntu"); + when(image.getImageVersion()).thenReturn("22.04"); + Request request = mock(Request.class); + when(request.getUser()).thenReturn(user); + when(request.getResourceGroup()).thenReturn(rg); + when(request.getContainerImage()).thenReturn(image); + when(request.getUbuntuUsername()).thenReturn("testuser"); + when(request.getUbuntuPassword()).thenReturn("InitPass1!"); + when(request.getRequestId()).thenReturn(requestId); + return request; + } + + private PodExternalPort mockPodPort(String purpose, int externalPort) { + PodExternalPort port = mock(PodExternalPort.class); + when(port.getUsagePurpose()).thenReturn(purpose); + when(port.getExternalPort()).thenReturn(externalPort); + return port; + } } From 666b00b034da82e6f152446eb1af05f307bafba4 Mon Sep 17 00:00:00 2001 From: yoon6yo Date: Tue, 4 Aug 2026 18:24:53 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EA=B3=84=EC=A0=95=20Hard=20Delete=20=EC=A0=9C=EA=B1=B0,=20Soft?= =?UTF-8?q?=20Delete=20=EC=83=81=ED=83=9C=EB=A1=9C=20=EC=98=81=EA=B5=AC=20?= =?UTF-8?q?=EB=B3=B4=EC=A1=B4=20(#380)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이력 보존을 위해 Soft Delete 1년 경과 후 DB row를 완전히 삭제하던 로직을 제거한다. 경고 이메일 발송과 Soft Delete 처리는 그대로 유지되며, 비활성화된 계정은 삭제되지 않고 영구히 보존된다. --- .../UserLifecycleTransactionalService.java | 12 ------- .../scheduler/UserSchedulerService.java | 16 ---------- .../users/repository/UserRepository.java | 7 ----- .../scheduler/UserSchedulerServiceTest.java | 30 +----------------- .../users/repository/UserRepositoryTest.java | 31 ------------------- 5 files changed, 1 insertion(+), 95 deletions(-) diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java index 75721140..72fd3e06 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java @@ -60,18 +60,6 @@ public void processInactiveUser(Long userId, LocalDateTime now) { } } - /** - * 특정 유저를 DB에서 완전 삭제(Hard Delete)합니다. - * 독립 트랜잭션으로 실행되어, 실패 시 다른 유저의 처리에 영향을 주지 않습니다. - */ - @Transactional - public void hardDeleteUser(Long userId, String email) { - userRepository.findById(userId).ifPresent(user -> { - userRepository.delete(user); - log.info("계정 영구 삭제(Hard Delete) 완료: ID={}, Email={}", userId, email); - }); - } - private void sendWarningAlert(User user, long daysLeft, LocalDateTime deleteDate) { String dateStr = deleteDate.toLocalDate().toString(); String subject = messageUtils.get("notification.user.delete-warning.subject", String.valueOf(daysLeft)); diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerService.java index a8e10f3b..fcb4fdbd 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerService.java @@ -20,7 +20,6 @@ public class UserSchedulerService { private final UserLifecycleTransactionalService userLifecycleService; private static final int INACTIVE_MONTHS = 3; - private static final int HARD_DELETE_YEARS = 1; // D-7 경고까지 포함하려면 (strict <) 기준일을 7+1=8일 앞당겨야 한다 private static final int NOTIFICATION_LEAD_DAYS = 8; @@ -31,7 +30,6 @@ public void runUserLifecycleScheduler() { LocalDateTime now = LocalDateTime.now(ZoneId.of("Asia/Seoul")); processInactiveUsers(now); - processHardDeleteUsers(now); log.info("👤 [스케줄러 종료]"); } @@ -49,18 +47,4 @@ private void processInactiveUsers(LocalDateTime now) { } } } - - private void processHardDeleteUsers(LocalDateTime now) { - LocalDateTime hardDeleteThreshold = now.minusYears(HARD_DELETE_YEARS); - List hardDeleteTargets = userRepository.findUsersForHardDelete(hardDeleteThreshold); - - for (User user : hardDeleteTargets) { - try { - // 유저별 독립 트랜잭션으로 처리 — processInactiveUsers 결과에 영향 없음 - userLifecycleService.hardDeleteUser(user.getUserId(), user.getEmail()); - } catch (Exception e) { - log.error("Hard Delete 실패: {}", user.getEmail(), e); - } - } - } } diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepository.java b/src/main/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepository.java index 12922488..039e33c3 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepository.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepository.java @@ -32,11 +32,4 @@ public interface UserRepository extends JpaRepository { " AND " + " (MAX(r.expiresAt) IS NULL OR MAX(r.expiresAt) < :thresholdDate)") List findInactiveUsers(@Param("thresholdDate") LocalDateTime thresholdDate); - - /** - * [Hard Delete 대상 조회] - * 조건: Soft Delete 된 지 1년 지난 유저 - */ - @Query("SELECT u FROM User u WHERE u.isActive = false AND u.deletedAt < :hardDeleteThreshold") - List findUsersForHardDelete(@Param("hardDeleteThreshold") LocalDateTime hardDeleteThreshold); } diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerServiceTest.java index d46396e9..c470b5e4 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserSchedulerServiceTest.java @@ -49,7 +49,7 @@ class UserSchedulerServiceTest { @Test - @DisplayName("유저 수명주기 통합 테스트: 알림(D-7, D-1), Soft Delete, Hard Delete, 활동 유저 보호") + @DisplayName("유저 수명주기 통합 테스트: 알림(D-7, D-1), Soft Delete, 활동 유저 보호") void userLifecycleScheduler_IntegrationTest() { // --- Given --- LocalDateTime now = LocalDateTime.now(); @@ -97,17 +97,6 @@ void userLifecycleScheduler_IntegrationTest() { String softBody = messageUtils.get("notification.user.soft-delete.body", "SoftTarget"); - // 6. [Hard Delete 대상] - User hardTarget = createUser("hard@test.com", "HardTarget"); - hardTarget.withdraw(); - updateDeletedAt(hardTarget, now.minusYears(1).minusDays(1)); - - // 7. [Hard Delete 미대상] - User hardSafe = createUser("hardsafe@test.com", "HardSafe"); - hardSafe.withdraw(); - updateDeletedAt(hardSafe, now.minusMonths(11)); - - // --- When --- userSchedulerService.runUserLifecycleScheduler(); @@ -147,12 +136,6 @@ void userLifecycleScheduler_IntegrationTest() { eq(softSubject), eq(softBody) ); - - // 6. [Hard Delete] 삭제 확인 - assertThat(userRepository.findById(hardTarget.getUserId())).isEmpty(); - - // 7. [Hard Delete 미대상] 생존 확인 - assertThat(userRepository.findById(hardSafe.getUserId())).isPresent(); } @@ -180,17 +163,6 @@ private void updateLastLogin(User user, LocalDateTime time) { } } - private void updateDeletedAt(User user, LocalDateTime time) { - try { - var field = User.class.getDeclaredField("deletedAt"); - field.setAccessible(true); - field.set(user, time); - userRepository.saveAndFlush(user); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - private void createRequestForUser(User user, LocalDateTime expiresAt) { ResourceGroup rg = resourceGroupRepository.findAll().stream().findFirst() .orElseGet(() -> resourceGroupRepository.save(ResourceGroup.builder().serverName("TestServer").resourceGroupName("G").build())); diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepositoryTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepositoryTest.java index 51917da3..fc659355 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepositoryTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/users/repository/UserRepositoryTest.java @@ -86,35 +86,4 @@ void findInactiveUsers_returnsUsersInactiveBeforeThreshold() { assertThat(result).extracting(User::getEmail).contains("active@dgu.ac.kr"); } } - - @Nested - @DisplayName("findUsersForHardDelete") - class FindUsersForHardDelete { - - @Test - @DisplayName("Soft delete 후 1년이 지나지 않은 유저는 Hard delete 대상이 아니다") - void findUsersForHardDelete_returnsEmpty_whenDeletedWithinOneYear() { - user1.withdraw(); - userRepository.save(user1); - userRepository.flush(); - - List result = userRepository.findUsersForHardDelete(LocalDateTime.now().minusYears(1)); - - assertThat(result).isEmpty(); - } - - @Test - @DisplayName("Soft delete된 지 1년이 지난 유저를 Hard delete 대상으로 조회한다") - void findUsersForHardDelete_returnsUser_whenDeletedBeforeOneYearThreshold() { - user1.withdraw(); - ReflectionTestUtils.setField(user1, "deletedAt", LocalDateTime.now().minusYears(2)); - userRepository.save(user1); - userRepository.flush(); - - List result = userRepository.findUsersForHardDelete(LocalDateTime.now().minusYears(1)); - - assertThat(result).hasSize(1); - assertThat(result.get(0).getEmail()).isEqualTo("active@dgu.ac.kr"); - } - } } From 7be56da2ed076153a466e8d08a4e8a12d62c1a2e Mon Sep 17 00:00:00 2001 From: yoon6yo Date: Thu, 20 Aug 2026 01:20:31 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=20=EC=9A=94=EC=B2=AD=20=EC=8A=B9?= =?UTF-8?q?=EC=9D=B8=20=EB=8F=99=EC=8B=9C=EC=84=B1=20=EB=B0=8F=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=EC=9A=94=EC=B2=AD=20=EC=B2=98=EB=A6=AC=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8,=20=EC=95=88=EB=82=B4=20=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 포트 요약 포맷 로직을 PodPortUtils로 공통화, 삭제 메일 N+1 쿼리 개선 - AdminUserService.deleteUser()가 withdraw()를 호출하지 않아 관리자 삭제 시 deletedAt이 기록되지 않던 버그 수정 - 유저 비활성 경고 메일에 Redis 기반 당일 중복 발송 방지 추가 - ChangeType.PORT 변경 요청 승인 시 항상 UNSUPPORTED_CHANGE_TYPE 예외가 나던 버그 수정 - approveRequest/approveModification에 행 잠금을 추가해 동시 승인 시 중복 provisioning 되는 race condition 제거 - 변경 요청 승인(EXPIRES_AT 외 전체 타입) 및 관리자 계정 삭제 시 누락됐던 안내 메일 추가 - GROUP 타입 변경 요청 승인이 항상 ClassCastException으로 실패하던 기존 버그 발견 및 수정 Closes #381 --- .gitignore | 3 + docs/component.png | Bin 0 -> 196760 bytes docs/sequence.png | Bin 0 -> 189877 bytes .../domain/alarm/service/AlarmService.java | 52 +++--- .../admin_be/domain/pod/PodPortUtils.java | 29 ++++ .../repository/ChangeRequestRepository.java | 13 ++ .../repository/RequestRepository.java | 11 ++ .../service/AdminRequestCommandService.java | 46 +++++- .../service/RequestExpiryService.java | 7 +- .../UserLifecycleTransactionalService.java | 27 +++- .../users/service/AdminUserService.java | 33 +++- src/main/resources/messages.properties | 19 +++ .../alarm/service/AlarmServiceTest.java | 138 ++++++++++++++++ .../RequestRepositoryLockingTest.java | 144 +++++++++++++++++ .../AdminRequestCommandServiceTest.java | 145 +++++++++++++++-- .../scheduler/RequestEventListenerTest.java | 19 ++- ...UserLifecycleTransactionalServiceTest.java | 148 ++++++++++++++++++ .../users/service/AdminUserServiceTest.java | 56 ++++++- 18 files changed, 839 insertions(+), 51 deletions(-) create mode 100644 docs/component.png create mode 100644 docs/sequence.png create mode 100644 src/main/java/DGU_AI_LAB/admin_be/domain/pod/PodPortUtils.java create mode 100644 src/test/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepositoryLockingTest.java create mode 100644 src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalServiceTest.java diff --git a/.gitignore b/.gitignore index 36a91d2b..7ea800e5 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ out/ application.yml /.gradle .DS_Store + +### Local notes ### +status.md diff --git a/docs/component.png b/docs/component.png new file mode 100644 index 0000000000000000000000000000000000000000..82e2dae44f866cba78f49f6a663cc126d508a0cc GIT binary patch literal 196760 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 literal 0 HcmV?d00001 diff --git a/docs/sequence.png b/docs/sequence.png new file mode 100644 index 0000000000000000000000000000000000000000..67601c8f7d72d95ef25e424ae5ed62884c8d1edd GIT binary patch literal 189877 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

uKkJ>FMonTOdld9z}g$Et5 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 z allPorts = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); - String extraPorts = allPorts.stream() - .filter(p -> !"ssh".equalsIgnoreCase(p.getUsagePurpose()) && !"jupyter".equalsIgnoreCase(p.getUsagePurpose())) - .map(p -> p.getUsagePurpose() + "(" + p.getExternalPort() + ")") - .collect(Collectors.joining(", ")); - if (extraPorts.isEmpty()) extraPorts = "없음"; + String extraPorts = PodPortUtils.formatExtraPortSummary(allPorts); String subject = messageUtils.get("email.container.created.subject", serverName); String body = messageUtils.get("email.container.created.body", @@ -183,17 +179,22 @@ private String resolveHostIp(String serverName) { * [관리자 수동 삭제 안내 메일] 관리자가 계정 삭제 시 사용자에게 발송. */ public void sendContainerDeletedEmail(Request request) { + List ports = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); + sendContainerDeletedEmail(request, ports); + } + + public void sendContainerDeletedEmail(Request request, List ports) { User user = request.getUser(); String serverName = request.getResourceGroup().getServerName(); - List ports = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); + String podName = request.getPodName() != null ? request.getPodName() : "미배정"; String subject = messageUtils.get("email.container.deleted.subject", serverName); String body = messageUtils.get("email.container.deleted.body", user.getName(), // {0} serverName, // {1} request.getUbuntuUsername(), // {2} - request.getPodName(), // {3} - formatPortSummary(ports), // {4} + podName, // {3} + PodPortUtils.formatPortSummary(ports), // {4} LocalDate.now().toString()); // {5} sendMailAlert(user.getEmail(), subject, body); @@ -207,6 +208,8 @@ public void sendContainerExtendedEmail(Request request, LocalDateTime oldExpires User user = request.getUser(); String serverName = request.getResourceGroup().getServerName(); List ports = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); + String oldDate = oldExpiresAt != null ? oldExpiresAt.toLocalDate().toString() : "이전 기록 없음"; + String podName = request.getPodName() != null ? request.getPodName() : "미배정"; String subject = messageUtils.get("email.container.extended.subject", serverName); String body = messageUtils.get("email.container.extended.body", @@ -214,21 +217,14 @@ public void sendContainerExtendedEmail(Request request, LocalDateTime oldExpires serverName, // {1} request.getUbuntuUsername(), // {2} newExpiresAt.toLocalDate().toString(), // {3} - oldExpiresAt.toLocalDate().toString(), // {4} - request.getPodName(), // {5} - formatPortSummary(ports)); // {6} + oldDate, // {4} + podName, // {5} + PodPortUtils.formatPortSummary(ports)); // {6} sendMailAlert(user.getEmail(), subject, body); sendMonitoringLog(user.getName(), user.getEmail(), subject); } - private String formatPortSummary(List ports) { - if (ports == null || ports.isEmpty()) return "없음"; - return ports.stream() - .map(p -> p.getUsagePurpose() + "(" + p.getExternalPort() + ")") - .collect(Collectors.joining(", ")); - } - public void sendRequestRejectedEmail(Request request, String adminComment) { User user = request.getUser(); String serverName = request.getResourceGroup().getServerName(); @@ -257,6 +253,24 @@ public void sendModificationRejectedEmail(ChangeRequest changeRequest, String ad sendMonitoringLog(user.getName(), user.getEmail(), subject); } + /** + * [변경 요청 승인 안내 메일] EXPIRES_AT 외 타입(VOLUME_SIZE/GROUP/RESOURCE_GROUP/CONTAINER_IMAGE/PORT) 공통. + * EXPIRES_AT은 sendContainerExtendedEmail로 별도의 상세 메일을 보낸다. + */ + public void sendModificationApprovedEmail(ChangeRequest changeRequest, String adminComment) { + User user = changeRequest.getRequestedBy(); + String changeType = changeRequest.getChangeType().name(); + + String subject = messageUtils.get("email.modification.approved.subject", changeType); + String body = messageUtils.get("email.modification.approved.body", + user.getName(), // {0} + changeType, // {1} + adminComment); // {2} + + sendMailAlert(user.getEmail(), subject, body); + sendMonitoringLog(user.getName(), user.getEmail(), subject); + } + public void sendAdminSlackNotification(String serverName, String message) { sendSlackAlert(message, getAdminWebhookUrl(serverName)); } diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/pod/PodPortUtils.java b/src/main/java/DGU_AI_LAB/admin_be/domain/pod/PodPortUtils.java new file mode 100644 index 00000000..05537228 --- /dev/null +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/pod/PodPortUtils.java @@ -0,0 +1,29 @@ +package DGU_AI_LAB.admin_be.domain.pod; + +import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; + +import java.util.List; +import java.util.stream.Collectors; + +public class PodPortUtils { + + private PodPortUtils() {} + + /** 전체 포트 목록을 "용도(포트번호), ..." 형식으로 반환. 없으면 "없음". */ + public static String formatPortSummary(List ports) { + if (ports == null || ports.isEmpty()) return "없음"; + return ports.stream() + .map(p -> p.getUsagePurpose() + "(" + p.getExternalPort() + ")") + .collect(Collectors.joining(", ")); + } + + /** ssh/jupyter를 제외한 추가 포트만 포맷. 없으면 "없음". */ + public static String formatExtraPortSummary(List ports) { + if (ports == null) return "없음"; + List extraPorts = ports.stream() + .filter(p -> !"ssh".equalsIgnoreCase(p.getUsagePurpose()) + && !"jupyter".equalsIgnoreCase(p.getUsagePurpose())) + .collect(Collectors.toList()); + return formatPortSummary(extraPorts); + } +} diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/ChangeRequestRepository.java b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/ChangeRequestRepository.java index d58762c3..4f66c9c3 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/ChangeRequestRepository.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/ChangeRequestRepository.java @@ -2,12 +2,25 @@ import DGU_AI_LAB.admin_be.domain.requests.entity.ChangeRequest; import DGU_AI_LAB.admin_be.domain.requests.entity.Status; +import jakarta.persistence.LockModeType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; +import java.util.Optional; public interface ChangeRequestRepository extends JpaRepository { List findAllByStatus(Status status); List findAllByRequestedBy_UserIdAndStatus(Long userId, Status status); List findAllByRequestedBy_UserId(Long userId); + + /** + * 변경 요청 승인 시 상태 확인 → 반영 사이의 race condition을 막기 위한 행 잠금 조회. + * RequestRepository.findByIdForUpdate와 동일한 목적. + */ + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("SELECT c FROM ChangeRequest c WHERE c.changeRequestId = :changeRequestId") + Optional findByIdForUpdate(@Param("changeRequestId") Long changeRequestId); } \ No newline at end of file diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepository.java b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepository.java index 326080fe..971daf01 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepository.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepository.java @@ -3,7 +3,9 @@ import DGU_AI_LAB.admin_be.domain.requests.entity.Request; import DGU_AI_LAB.admin_be.domain.requests.entity.Status; import DGU_AI_LAB.admin_be.domain.users.entity.User; +import jakarta.persistence.LockModeType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Lock; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @@ -29,6 +31,15 @@ public interface RequestRepository extends JpaRepository { @Query("SELECT r.ubuntuUsername FROM Request r WHERE r.status = :status") List findUbuntuUsernamesByStatus(@Param("status") Status status); + /** + * 승인 처리 중 상태 확인 → 변경 사이의 race condition을 막기 위한 행 잠금 조회. + * 동시에 같은 Request를 승인하려는 두 번째 트랜잭션은 첫 트랜잭션 커밋(짧은 상태-확인 트랜잭션) 때까지 대기한 뒤 + * PROCESSING 상태를 보고 INVALID_REQUEST_STATUS로 실패한다. + */ + @Lock(LockModeType.PESSIMISTIC_WRITE) + @Query("SELECT r FROM Request r WHERE r.requestId = :requestId") + Optional findByIdForUpdate(@Param("requestId") Long requestId); + @Query("SELECT DISTINCT r FROM Request r " + "JOIN FETCH r.user " + "LEFT JOIN FETCH r.resourceGroup " + diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java index 140068b3..b8dd53c2 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandService.java @@ -7,8 +7,10 @@ import DGU_AI_LAB.admin_be.domain.groups.repository.GroupRepository; import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; +import DGU_AI_LAB.admin_be.domain.portRequests.service.PortRequestService; import DGU_AI_LAB.admin_be.domain.requests.dto.request.ApproveModificationDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.ApproveRequestDTO; +import DGU_AI_LAB.admin_be.domain.requests.dto.request.PortRequestDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.RejectModificationDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.RejectRequestDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.UserCreationRequestDTO; @@ -43,6 +45,7 @@ import reactor.core.publisher.Mono; import java.time.LocalDateTime; +import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -63,6 +66,7 @@ public class AdminRequestCommandService { private final PodExternalPortRepository podExternalPortRepository; private final PodService podService; private final UbuntuAccountService ubuntuAccountService; + private final PortRequestService portRequestService; private final ObjectMapper objectMapper; private final @Qualifier("configWebClient") WebClient userCreationWebClient; @@ -76,7 +80,9 @@ public SaveRequestResponseDTO approveRequest(ApproveRequestDTO dto) { final UserCreationRequestDTO[] creationDtoRef = {null}; final String[] usernameRef = {null}; tx.execute(status -> { - Request req = requestRepository.findById(dto.requestId()) + // 행 잠금 조회: 동시에 같은 요청을 승인 시도하는 두 번째 트랜잭션은 여기서 대기하다가 + // 첫 트랜잭션 커밋 후 PROCESSING 상태를 보고 아래에서 실패한다 (중복 승인/중복 provisioning 방지) + Request req = requestRepository.findByIdForUpdate(dto.requestId()) .orElseThrow(() -> new BusinessException(ErrorCode.RESOURCE_NOT_FOUND)); if (req.getStatus() != Status.PENDING) { throw new BusinessException(ErrorCode.INVALID_REQUEST_STATUS); @@ -219,7 +225,11 @@ public SaveRequestResponseDTO rejectRequest(RejectRequestDTO dto) { throw new BusinessException(ErrorCode.INVALID_REQUEST_STATUS); } request.reject(dto.adminComment()); - alarmService.sendRequestRejectedEmail(request, dto.adminComment()); + try { + alarmService.sendRequestRejectedEmail(request, dto.adminComment()); + } catch (Exception e) { + log.warn("거절 안내 메일 발송 실패: requestId={}", dto.requestId(), e); + } return SaveRequestResponseDTO.fromEntity(request); } @@ -237,12 +247,18 @@ public void rejectModification(Long adminId, RejectModificationDTO dto) { .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)); changeRequest.deny(admin, dto.adminComment()); - alarmService.sendModificationRejectedEmail(changeRequest, dto.adminComment()); + try { + alarmService.sendModificationRejectedEmail(changeRequest, dto.adminComment()); + } catch (Exception e) { + log.warn("변경 요청 거절 메일 발송 실패: changeRequestId={}", dto.changeRequestId(), e); + } } @Transactional public void approveModification(Long adminId, ApproveModificationDTO dto) { - ChangeRequest changeRequest = changeRequestRepository.findById(dto.changeRequestId()) + // 행 잠금 조회: 동시에 같은 변경 요청을 승인 시도하는 두 번째 트랜잭션은 첫 트랜잭션 커밋까지 대기하다가 + // FULFILLED 상태를 보고 실패한다 (PORT 등 부수 효과의 중복 실행 방지) + ChangeRequest changeRequest = changeRequestRepository.findByIdForUpdate(dto.changeRequestId()) .orElseThrow(() -> new BusinessException(ErrorCode.RESOURCE_NOT_FOUND)); if (changeRequest.getStatus() != Status.PENDING) { @@ -274,7 +290,8 @@ public void approveModification(Long adminId, ApproveModificationDTO dto) { case GROUP: // 그룹 변경은 복잡하기 때문에, 엔티티가 아닌 서비스 레이어에서 처리합니다. originalRequest.getRequestGroups().clear(); - Set newGroupIds = objectMapper.readValue(changeRequest.getNewValue(), Set.class); + Set newGroupIds = objectMapper.readValue(changeRequest.getNewValue(), + objectMapper.getTypeFactory().constructCollectionType(Set.class, Long.class)); Set newGroups = newGroupIds.stream() .map(gid -> groupRepository.findByUbuntuGid(gid) .orElseThrow(() -> new BusinessException(ErrorCode.RESOURCE_NOT_FOUND))) @@ -296,6 +313,18 @@ public void approveModification(Long adminId, ApproveModificationDTO dto) { .orElseThrow(() -> new BusinessException(ErrorCode.RESOURCE_NOT_FOUND)); originalRequest.updateContainerImage(newContainerImage); break; + case PORT: + List newPorts = objectMapper.readValue(changeRequest.getNewValue(), + objectMapper.getTypeFactory().constructCollectionType(List.class, PortRequestDTO.class)); + for (PortRequestDTO portRequestDTO : newPorts) { + portRequestService.createPortRequest( + originalRequest, + originalRequest.getResourceGroup(), + portRequestDTO.internalPort(), + portRequestDTO.usagePurpose() + ); + } + break; default: throw new BusinessException(ErrorCode.UNSUPPORTED_CHANGE_TYPE); } @@ -313,6 +342,13 @@ public void approveModification(Long adminId, ApproveModificationDTO dto) { } catch (Exception e) { log.warn("기간 연장 안내 메일 발송 실패: changeRequestId={}", dto.changeRequestId(), e); } + } else { + try { + alarmService.sendModificationApprovedEmail(changeRequest, dto.adminComment()); + log.info("사용자 '{}'에게 변경 요청 승인 안내 메일을 발송했습니다.", originalRequest.getUser().getName()); + } catch (Exception e) { + log.warn("변경 요청 승인 안내 메일 발송 실패: changeRequestId={}", dto.changeRequestId(), e); + } } } diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/RequestExpiryService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/RequestExpiryService.java index 0f1c2a42..6b35bca8 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/RequestExpiryService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/requests/service/RequestExpiryService.java @@ -1,5 +1,6 @@ package DGU_AI_LAB.admin_be.domain.requests.service; +import DGU_AI_LAB.admin_be.domain.pod.PodPortUtils; import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; @@ -15,7 +16,6 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; -import java.util.stream.Collectors; @Slf4j @Service @@ -43,10 +43,7 @@ public void deleteExpiredRequest(Long requestId) { String expiresAt = request.getExpiresAt() != null ? request.getExpiresAt().toLocalDate().toString() : ""; List ports = podExternalPortRepository.findByRequestRequestId(requestId); - String portSummary = ports.isEmpty() ? "없음" - : ports.stream() - .map(p -> p.getUsagePurpose() + "(" + p.getExternalPort() + ")") - .collect(Collectors.joining(", ")); + String portSummary = PodPortUtils.formatPortSummary(ports); try { podService.deletePod(request.getPodName()); diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java index 72fd3e06..a7c34d98 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalService.java @@ -6,9 +6,11 @@ import DGU_AI_LAB.admin_be.global.util.MessageUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.time.Duration; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; @@ -25,6 +27,7 @@ public class UserLifecycleTransactionalService { private final UserRepository userRepository; private final AlarmService alarmService; private final MessageUtils messageUtils; + private final RedisTemplate redisTemplate; private static final int INACTIVE_MONTHS = 3; @@ -54,13 +57,18 @@ public void processInactiveUser(Long userId, LocalDateTime now) { long daysLeft = ChronoUnit.DAYS.between(now.toLocalDate(), deleteDate.toLocalDate()); if (daysLeft == 7 || daysLeft == 3 || daysLeft == 1) { - sendWarningAlert(user, daysLeft, deleteDate); + sendWarningAlert(user, daysLeft, deleteDate, now.toLocalDate().toString()); } else if (daysLeft <= 0) { softDeleteUser(user); } } - private void sendWarningAlert(User user, long daysLeft, LocalDateTime deleteDate) { + private void sendWarningAlert(User user, long daysLeft, LocalDateTime deleteDate, String today) { + if (isDuplicateWarning(user.getUserId(), daysLeft, today)) { + log.debug("계정 삭제 경고 중복 발송 방지: userId={}, daysLeft={}, date={}", user.getUserId(), daysLeft, today); + return; + } + String dateStr = deleteDate.toLocalDate().toString(); String subject = messageUtils.get("notification.user.delete-warning.subject", String.valueOf(daysLeft)); String body = messageUtils.get("notification.user.delete-warning.body", @@ -70,6 +78,21 @@ private void sendWarningAlert(User user, long daysLeft, LocalDateTime deleteDate log.info("경고 알림 발송: {} ({}일 전)", user.getEmail(), daysLeft); } + /** + * Redis SETNX로 당일 중복 발송을 방지한다 (RequestNotificationService.isDuplicate와 동일 패턴). + * Redis 장애 시 false를 반환해 이메일 발송을 허용한다(fail-open). + */ + private boolean isDuplicateWarning(Long userId, long daysLeft, String date) { + try { + String key = "email:user-inactive-warning:" + userId + ":" + daysLeft + ":" + date; + Boolean set = redisTemplate.opsForValue().setIfAbsent(key, "sent", Duration.ofHours(25)); + return Boolean.FALSE.equals(set); + } catch (Exception e) { + log.warn("Redis 중복 체크 실패, 발송 진행: {}", e.getMessage()); + return false; + } + } + private void softDeleteUser(User user) { user.withdraw(); diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserService.java index 1e6a373d..21ab9541 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserService.java @@ -1,6 +1,8 @@ package DGU_AI_LAB.admin_be.domain.users.service; import DGU_AI_LAB.admin_be.domain.alarm.service.AlarmService; +import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; +import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; import DGU_AI_LAB.admin_be.domain.requests.entity.Status; import DGU_AI_LAB.admin_be.domain.requests.repository.RequestRepository; @@ -13,12 +15,15 @@ import DGU_AI_LAB.admin_be.error.ErrorCode; import DGU_AI_LAB.admin_be.error.exception.ConflictException; import DGU_AI_LAB.admin_be.error.exception.EntityNotFoundException; +import DGU_AI_LAB.admin_be.global.util.MessageUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Slf4j @Service @@ -30,6 +35,8 @@ public class AdminUserService { private final RequestRepository requestRepository; private final UbuntuAccountService ubuntuAccountService; private final AlarmService alarmService; + private final PodExternalPortRepository podExternalPortRepository; + private final MessageUtils messageUtils; /** * 전체 유저 조회 @@ -57,13 +64,25 @@ public void deleteUser(Long userId) { List userRequests = requestRepository.findAllByUser(user); + List fulfilledIds = userRequests.stream() + .filter(r -> r.getStatus() == Status.FULFILLED) + .map(Request::getRequestId) + .collect(Collectors.toList()); + Map> portsMap = fulfilledIds.isEmpty() + ? Map.of() + : podExternalPortRepository + .findByRequestRequestIdIn(fulfilledIds) + .stream() + .collect(Collectors.groupingBy(p -> p.getRequest().getRequestId())); + for (Request request : userRequests) { - if (request.getStatus() == Status.FULFILLED) { + if (fulfilledIds.contains(request.getRequestId())) { ubuntuAccountService.deleteUbuntuAccount(request.getUbuntuUsername()); request.deleteAfterCleanup(); requestRepository.save(request); try { - alarmService.sendContainerDeletedEmail(request); + List ports = portsMap.getOrDefault(request.getRequestId(), List.of()); + alarmService.sendContainerDeletedEmail(request, ports); } catch (Exception e) { log.warn("[deleteUser] 삭제 안내 메일 발송 실패: ubuntuUsername={}", request.getUbuntuUsername(), e); } @@ -73,8 +92,16 @@ public void deleteUser(Long userId) { } log.info("[deleteUser] userId={}와 연결된 Request 정리 완료", userId); - user.updateUserInfo(null, false); + user.withdraw(); log.info("[deleteUser] userId={} 논리적 삭제 완료 (isActive=false)", userId); + + try { + String subject = messageUtils.get("notification.user.admin-delete.subject"); + String body = messageUtils.get("notification.user.admin-delete.body", user.getName()); + alarmService.sendAllAlerts(user.getName(), user.getEmail(), subject, body); + } catch (Exception e) { + log.warn("[deleteUser] 계정 비활성화 안내 메일 발송 실패: userId={}", userId, e); + } } /** diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 2799914b..d49a3a32 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -84,6 +84,13 @@ notification.user.soft-delete.body=\uC548\uB155\uD558\uC138\uC694, {0}\uB2D8.\n\ \n\uC9C0\uAE08\uBD80\uD130 \uB85C\uADF8\uC778\uC774 \uBD88\uAC00\uB2A5\uD558\uBA70, 1\uB144 \uB4A4 \uAC1C\uC778\uC815\uBCF4\uAC00 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0\uC11C \uC601\uAD6C \uC0AD\uC81C\uB429\uB2C8\uB2E4.\n\ \uACC4\uC815 \uBCF5\uAD6C\uAC00 \uD544\uC694\uD558\uC2E0 \uACBD\uC6B0 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758 \uBC14\uB78D\uB2C8\uB2E4. +# [\uAD00\uB9AC\uC790 \uC218\uB3D9 \uC0AD\uC81C] (\uBE44\uD65C\uC131\uD654) +# {0}: \uC0AC\uC6A9\uC790 \uC774\uB984 +notification.user.admin-delete.subject=[DGU AI LAB] \uACC4\uC815 \uBE44\uD65C\uC131\uD654 \uC548\uB0B4 +notification.user.admin-delete.body=\uC548\uB155\uD558\uC138\uC694, {0}\uB2D8.\n\ + \n\uAD00\uB9AC\uC790\uC5D0 \uC758\uD574 \uACC4\uC815\uC774 \uBE44\uD65C\uC131\uD654 \uCC98\uB9AC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\ + \n\uC9C0\uAE08\uBD80\uD130 \uB85C\uADF8\uC778\uC774 \uBD88\uAC00\uB2A5\uD569\uB2C8\uB2E4. \uACC4\uC815 \uAD00\uB828 \uBB38\uC758\uC0AC\uD56D\uC740 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758 \uBC14\uB78D\uB2C8\uB2E4. + # ============================================================================== # 6. \uCEE8\uD14C\uC774\uB108 \uBC30\uC815 \uC548\uB0B4 \uBA54\uC77C (\uC2E0\uCCAD \uC2B9\uC778 \uC2DC \uC0AC\uC6A9\uC790\uC5D0\uAC8C \uBC1C\uC1A1) \u2014 email.container.created # DB(message_templates) \uC624\uBC84\uB77C\uC774\uB4DC \uAC00\uB2A5. reset \uC2DC \uC544\uB798 \uAE30\uBCF8\uAC12\uC73C\uB85C \uBCF5\uADC0. @@ -151,6 +158,18 @@ email.modification.rejected.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D \n- \uAC70\uC808 \uC0AC\uC720: {2}\n\ \n\uBB38\uC758\uAC00 \uC788\uC73C\uC2DC\uBA74 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD574 \uC8FC\uC138\uC694. +# ============================================================================== +# 10-1. \uBCC0\uACBD \uC694\uCCAD \uC2B9\uC778 \uC548\uB0B4 \uBA54\uC77C (EXPIRES_AT \uC678 \uD0C0\uC785 \uACF5\uD1B5) \u2014 email.modification.approved +# ============================================================================== +# subject: {0}: \uBCC0\uACBD \uC720\uD615 +email.modification.approved.subject=[DGU AILab] \uC11C\uBC84 \uBCC0\uACBD \uC694\uCCAD \uC2B9\uC778 \uC548\uB0B4 ({0}) + +# {0}: \uC774\uB984, {1}: \uBCC0\uACBD \uC720\uD615, {2}: \uC2B9\uC778 \uCF54\uBA58\uD2B8 +email.modification.approved.body=\uC548\uB155\uD558\uC138\uC694 {0}\uB2D8, \uB3D9\uAD6D\uB300\uD559\uAD50 \uC11C\uBC84\uAD00\uB9AC\uD300\uC785\uB2C8\uB2E4.\n\ + \n\uC694\uCCAD\uD558\uC2E0 \uC11C\uBC84 \uBCC0\uACBD ({1}) \uC694\uCCAD\uC774 \uC2B9\uC778\uB418\uC5C8\uC2B5\uB2C8\uB2E4.\n\ + \n- \uC2B9\uC778 \uCF54\uBA58\uD2B8: {2}\n\ + \n\uBB38\uC758\uAC00 \uC788\uC73C\uC2DC\uBA74 \uAD00\uB9AC\uC790\uC5D0\uAC8C \uBB38\uC758\uD574 \uC8FC\uC138\uC694. + # ============================================================================== # 7. \uAD00\uB9AC\uC790 \uC218\uB3D9 \uC0AD\uC81C \uC548\uB0B4 \uBA54\uC77C \u2014 email.container.deleted # ============================================================================== diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java index 4ae1fba8..efccbdc5 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmServiceTest.java @@ -466,6 +466,144 @@ void sendModificationRejectedEmail_sendsSlackError_whenMailFails() { } } + @Nested + @DisplayName("sendContainerDeletedEmail") + class SendContainerDeletedEmail { + + @Test + @DisplayName("podName이 null이면 이메일 본문에 '미배정'으로 전달된다") + void sendContainerDeletedEmail_nullPodName_renders_placeholder() { + Request request = mockRequestForDeleted("홍길동", "hong@dgu.ac.kr", "LAB", null); + when(podExternalPortRepository.findByRequestRequestId(any())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerDeletedEmail(request); + + verify(messageUtils).get(eq("email.container.deleted.body"), + any(), any(), any(), eq("미배정"), any(), any()); + } + + @Test + @DisplayName("podName이 있으면 실제 값이 이메일 본문에 전달된다") + void sendContainerDeletedEmail_withPodName_passesRealValue() { + Request request = mockRequestForDeleted("홍길동", "hong@dgu.ac.kr", "LAB", "pod-user1-abc"); + when(podExternalPortRepository.findByRequestRequestId(any())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerDeletedEmail(request); + + verify(messageUtils).get(eq("email.container.deleted.body"), + any(), any(), any(), eq("pod-user1-abc"), any(), any()); + } + + @Test + @DisplayName("ports를 직접 전달하는 오버로드는 DB를 조회하지 않는다") + void sendContainerDeletedEmail_overload_doesNotQueryRepository() { + Request request = mockRequestForDeleted("홍길동", "hong@dgu.ac.kr", "LAB", "pod-abc"); + PodExternalPort port = mockPodPort("ssh", 30022); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerDeletedEmail(request, List.of(port)); + + verify(podExternalPortRepository, never()).findByRequestRequestId(any()); + verify(mailSender).send(any(SimpleMailMessage.class)); + } + + @Test + @DisplayName("ports를 직접 전달하면 포트 요약이 본문에 포함된다") + void sendContainerDeletedEmail_overload_includesPortSummary() { + Request request = mockRequestForDeleted("이순신", "lee@dgu.ac.kr", "FARM", "pod-xyz"); + PodExternalPort port = mockPodPort("jupyter", 30888); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerDeletedEmail(request, List.of(port)); + + verify(messageUtils).get(eq("email.container.deleted.body"), + any(), any(), any(), any(), eq("jupyter(30888)"), any()); + } + } + + @Nested + @DisplayName("sendContainerExtendedEmail") + class SendContainerExtendedEmail { + + @Test + @DisplayName("oldExpiresAt이 null이면 NPE 없이 '이전 기록 없음'이 본문에 전달된다") + void sendContainerExtendedEmail_nullOldExpiresAt_rendersPlaceholder() { + Request request = mockRequestForExtended("홍길동", "hong@dgu.ac.kr", "LAB", "pod-abc"); + when(podExternalPortRepository.findByRequestRequestId(any())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerExtendedEmail(request, null, + java.time.LocalDateTime.of(2027, 12, 31, 23, 59, 59)); + + verify(messageUtils).get(eq("email.container.extended.body"), + any(), any(), any(), any(), eq("이전 기록 없음"), any(), any()); + } + + @Test + @DisplayName("oldExpiresAt이 있으면 날짜 문자열이 본문에 전달된다") + void sendContainerExtendedEmail_withOldExpiresAt_passesDate() { + Request request = mockRequestForExtended("홍길동", "hong@dgu.ac.kr", "LAB", "pod-abc"); + when(podExternalPortRepository.findByRequestRequestId(any())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerExtendedEmail(request, + java.time.LocalDateTime.of(2026, 6, 30, 0, 0), + java.time.LocalDateTime.of(2027, 12, 31, 23, 59, 59)); + + verify(messageUtils).get(eq("email.container.extended.body"), + any(), any(), any(), any(), eq("2026-06-30"), any(), any()); + } + + @Test + @DisplayName("podName이 null이면 '미배정'이 본문에 전달된다") + void sendContainerExtendedEmail_nullPodName_rendersPlaceholder() { + Request request = mockRequestForExtended("홍길동", "hong@dgu.ac.kr", "LAB", null); + when(podExternalPortRepository.findByRequestRequestId(any())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any())).thenReturn("제목"); + when(messageUtils.get(anyString(), any(), any(), any(), any(), any(), any(), any())).thenReturn("본문"); + + alarmService.sendContainerExtendedEmail(request, + java.time.LocalDateTime.of(2026, 6, 30, 0, 0), + java.time.LocalDateTime.of(2027, 12, 31, 23, 59, 59)); + + verify(messageUtils).get(eq("email.container.extended.body"), + any(), any(), any(), any(), any(), eq("미배정"), any()); + } + } + + private Request mockRequestForDeleted(String userName, String email, String serverName, String podName) { + return mockRequestWithOptionalId(userName, email, serverName, podName, null); + } + + private Request mockRequestForExtended(String userName, String email, String serverName, String podName) { + return mockRequestWithOptionalId(userName, email, serverName, podName, 99L); + } + + private Request mockRequestWithOptionalId(String userName, String email, String serverName, String podName, Long requestId) { + User user = mock(User.class); + when(user.getName()).thenReturn(userName); + when(user.getEmail()).thenReturn(email); + ResourceGroup rg = mock(ResourceGroup.class); + when(rg.getServerName()).thenReturn(serverName); + Request request = mock(Request.class); + when(request.getUser()).thenReturn(user); + when(request.getResourceGroup()).thenReturn(rg); + when(request.getPodName()).thenReturn(podName); + when(request.getUbuntuUsername()).thenReturn("testuser"); + if (requestId != null) { + when(request.getRequestId()).thenReturn(requestId); + } + return request; + } + private Request mockRequest(String userName, String serverName) { User user = mock(User.class); when(user.getName()).thenReturn(userName); diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepositoryLockingTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepositoryLockingTest.java new file mode 100644 index 00000000..b45fca63 --- /dev/null +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/repository/RequestRepositoryLockingTest.java @@ -0,0 +1,144 @@ +package DGU_AI_LAB.admin_be.domain.requests.repository; + +import DGU_AI_LAB.admin_be.domain.containerImage.entity.ContainerImage; +import DGU_AI_LAB.admin_be.domain.containerImage.repository.ContainerImageRepository; +import DGU_AI_LAB.admin_be.domain.requests.entity.Request; +import DGU_AI_LAB.admin_be.domain.requests.entity.Status; +import DGU_AI_LAB.admin_be.domain.resourceGroups.entity.ResourceGroup; +import DGU_AI_LAB.admin_be.domain.resourceGroups.repository.ResourceGroupRepository; +import DGU_AI_LAB.admin_be.domain.users.entity.User; +import DGU_AI_LAB.admin_be.domain.users.repository.UserRepository; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.support.TransactionTemplate; + +import java.time.LocalDateTime; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * findByIdForUpdate()의 행 잠금이 실제로 동시 접근을 직렬화하는지 검증한다. + * 테스트 메서드 자체는 트랜잭션으로 감싸지 않아(NOT_SUPPORTED) 스레드별 TransactionTemplate이 + * 각자 독립적으로 커밋되도록 한다 — @DataJpaTest 기본 롤백 트랜잭션 안에서는 두 스레드가 + * 서로의 커밋을 볼 수 없어 이 테스트의 목적(실제 잠금 검증)을 달성할 수 없다. + */ +@DataJpaTest +@ActiveProfiles("test") +@Transactional(propagation = Propagation.NOT_SUPPORTED) +class RequestRepositoryLockingTest { + + @Autowired + private RequestRepository requestRepository; + + @Autowired + private UserRepository userRepository; + + @Autowired + private ResourceGroupRepository resourceGroupRepository; + + @Autowired + private ContainerImageRepository containerImageRepository; + + @Autowired + private PlatformTransactionManager transactionManager; + + private Long requestId; + + @BeforeEach + void setUp() { + User user = userRepository.save(User.builder() + .email("lockingtest@dgu.ac.kr") + .password("encoded") + .name("잠금테스트") + .studentId("2021009999") + .phone("010-9999-0000") + .department("컴퓨터공학과") + .build()); + + ResourceGroup resourceGroup = resourceGroupRepository.save(ResourceGroup.builder() + .resourceGroupName("Locking Test Server") + .description("잠금 테스트용") + .serverName("server-lock") + .build()); + + ContainerImage containerImage = containerImageRepository.save(ContainerImage.builder() + .imageName("pytorch") + .imageVersion("2.1.0") + .cudaVersion("11.8") + .description("잠금 테스트용 이미지") + .build()); + + Request request = requestRepository.save(Request.builder() + .ubuntuUsername("lockingtestuser") + .ubuntuPassword("hashedPw") + .ubuntuPasswordBase64("base64Pw") + .volumeSizeGiB(50L) + .expiresAt(LocalDateTime.now().plusDays(30)) + .usagePurpose("동시성 테스트") + .formAnswers("{}") + .user(user) + .resourceGroup(resourceGroup) + .containerImage(containerImage) + .build()); + + requestId = request.getRequestId(); + } + + @Test + @DisplayName("두 트랜잭션이 동시에 findByIdForUpdate를 호출하면, 두 번째는 첫 번째가 커밋할 때까지 대기했다가 변경된 상태를 본다") + void findByIdForUpdate_blocksConcurrentAccess_untilFirstTransactionCommits() throws Exception { + TransactionTemplate tx = new TransactionTemplate(transactionManager); + CountDownLatch lockAcquired = new CountDownLatch(1); + long holdMillis = 500; + + ExecutorService executor = Executors.newFixedThreadPool(2); + try { + // 첫 번째 관리자의 승인 시도: 행 잠금을 잡고 holdMillis만큼 "외부 API 호출하는 척" 대기 후 PROCESSING으로 전환 + Future first = executor.submit(() -> tx.executeWithoutResult(status -> { + Request req = requestRepository.findByIdForUpdate(requestId).orElseThrow(); + lockAcquired.countDown(); + try { + Thread.sleep(holdMillis); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + req.markAsProcessing(); + })); + + assertThat(lockAcquired.await(5, TimeUnit.SECONDS)).isTrue(); + + // 두 번째 관리자의 동시 승인 시도: 첫 번째가 락을 쥔 직후 바로 같은 행을 조회 시도 + long start = System.nanoTime(); + AtomicReference secondSeenStatus = new AtomicReference<>(); + Future second = executor.submit(() -> tx.executeWithoutResult(status -> { + Request req = requestRepository.findByIdForUpdate(requestId).orElseThrow(); + secondSeenStatus.set(req.getStatus()); + })); + + first.get(5, TimeUnit.SECONDS); + second.get(5, TimeUnit.SECONDS); + long elapsedMillis = (System.nanoTime() - start) / 1_000_000; + + // 잠금이 실제로 걸렸다면: (1) 두 번째는 첫 번째 커밋 이후 상태(PROCESSING)를 봐야 한다. + // 이게 핵심 증거다 — 잠금이 없었다면 두 번째는 커밋 전 상태인 PENDING을 읽었을 것이다. + // (2) 지연 시간도 블로킹의 보조 증거로 함께 확인하되, 스레드 스케줄링 변동을 감안해 느슨하게 검증한다. + assertThat(secondSeenStatus.get()).isEqualTo(Status.PROCESSING); + assertThat(elapsedMillis).isGreaterThanOrEqualTo(holdMillis / 2); + } finally { + executor.shutdown(); + } + } +} diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java index 03a06ee0..fe65a950 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/requests/service/AdminRequestCommandServiceTest.java @@ -7,6 +7,7 @@ import DGU_AI_LAB.admin_be.domain.groups.repository.GroupRepository; import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; +import DGU_AI_LAB.admin_be.domain.portRequests.service.PortRequestService; import DGU_AI_LAB.admin_be.domain.requests.dto.request.ApproveModificationDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.ApproveRequestDTO; import DGU_AI_LAB.admin_be.domain.requests.dto.request.RejectModificationDTO; @@ -66,6 +67,7 @@ class AdminRequestCommandServiceTest { @Mock private PodExternalPortRepository podExternalPortRepository; @Mock private PodService podService; @Mock private UbuntuAccountService ubuntuAccountService; + @Mock private PortRequestService portRequestService; @Mock private WebClient mockWebClient; @Mock private PlatformTransactionManager transactionManager; @Mock private TransactionStatus transactionStatus; @@ -91,7 +93,7 @@ void setUp() { service = new AdminRequestCommandService( alarmService, requestRepository, userRepository, containerImageRepository, resourceGroupRepository, changeRequestRepository, - groupRepository, podExternalPortRepository, podService, ubuntuAccountService, new ObjectMapper(), + groupRepository, podExternalPortRepository, podService, ubuntuAccountService, portRequestService, new ObjectMapper(), mockWebClient, transactionManager ); // 공유 엔티티 기본 설정 @@ -128,6 +130,7 @@ private Request buildMockedRequest(Long requestId) { when(request.getResourceGroup()).thenReturn(mockRg); when(request.getContainerImage()).thenReturn(mockImage); when(requestRepository.findById(requestId)).thenReturn(Optional.of(request)); + when(requestRepository.findByIdForUpdate(requestId)).thenReturn(Optional.of(request)); return request; } @@ -258,8 +261,9 @@ void approveRequest_podThrowsBusinessException_compensatesWithAccountDeletion() .isEqualTo(ErrorCode.POD_CREATION_FAILED); verify(ubuntuAccountService).deleteUbuntuAccount("testuser"); - // requestRepository.findById 재조회 후 revertToPending 호출 검증 - verify(requestRepository, atLeast(2)).findById(requestId); + // 1단계는 findByIdForUpdate(행 잠금)로 상태 확인, 보상 트랜잭션은 findById로 재조회 후 revertToPending 호출 + verify(requestRepository).findByIdForUpdate(requestId); + verify(requestRepository).findById(requestId); } @Test @@ -329,7 +333,7 @@ void approveRequest_nonPendingStatus_throwsBusinessException() { Long requestId = 14L; Request request = mock(Request.class); when(request.getStatus()).thenReturn(Status.FULFILLED); - when(requestRepository.findById(requestId)).thenReturn(Optional.of(request)); + when(requestRepository.findByIdForUpdate(requestId)).thenReturn(Optional.of(request)); ApproveRequestDTO dto = new ApproveRequestDTO(requestId, 1L, 1, 10L, "승인"); @@ -344,7 +348,7 @@ void approveRequest_nonPendingStatus_throwsBusinessException() { @Test @DisplayName("존재하지 않는 requestId 승인 시 BusinessException 발생") void approveRequest_requestNotFound_throwsBusinessException() { - when(requestRepository.findById(999L)).thenReturn(Optional.empty()); + when(requestRepository.findByIdForUpdate(999L)).thenReturn(Optional.empty()); ApproveRequestDTO dto = new ApproveRequestDTO(999L, 1L, 1, 10L, "승인"); @@ -463,6 +467,34 @@ void rejectRequest_doesNotSendEmail_whenStatusIsInvalid() { verify(alarmService, never()).sendRequestRejectedEmail(any(), anyString()); } + + @Test + @DisplayName("이메일 발송 실패 시 예외가 전파되지 않고 reject()는 이미 호출된 상태다") + void rejectRequest_emailFailure_doesNotPropagateException() { + Request request = buildMockedRequestWithStatus(38L, Status.PENDING); + doThrow(new RuntimeException("SMTP 연결 실패")) + .when(alarmService).sendRequestRejectedEmail(any(), anyString()); + + RejectRequestDTO dto = new RejectRequestDTO(38L, "신청서 양식 미흡"); + + // 이메일 실패해도 예외 미전파 (DB 롤백 없음) + service.rejectRequest(dto); + + verify(request).reject("신청서 양식 미흡"); + } + + @Test + @DisplayName("이메일 발송 실패 시에도 정상 응답 DTO가 반환된다") + void rejectRequest_emailFailure_stillReturnsResponseDTO() { + buildMockedRequestWithStatus(39L, Status.PENDING); + doThrow(new RuntimeException("MessageUtils 키 없음")) + .when(alarmService).sendRequestRejectedEmail(any(), anyString()); + + RejectRequestDTO dto = new RejectRequestDTO(39L, "사유"); + + // 예외 없이 DTO 반환 + assertThat(service.rejectRequest(dto)).isNotNull(); + } } // ────────────────────────────────────────────────────────────────────── @@ -566,6 +598,37 @@ void rejectModification_doesNotSendEmail_whenStatusIsNotPending() { verify(alarmService, never()).sendModificationRejectedEmail(any(), anyString()); } + + @Test + @DisplayName("이메일 발송 실패 시 예외가 전파되지 않고 deny()는 이미 호출된 상태다") + void rejectModification_emailFailure_doesNotPropagateException() { + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequestRepository.findById(13L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + doThrow(new RuntimeException("SMTP 연결 실패")) + .when(alarmService).sendModificationRejectedEmail(any(), anyString()); + + // 이메일 실패해도 예외 미전파 (DB 롤백 없음) + service.rejectModification(100L, new RejectModificationDTO(13L, "변경 사유 불충분")); + + verify(changeRequest).deny(mockUser, "변경 사유 불충분"); + } + + @Test + @DisplayName("이메일 발송 시 RuntimeException 발생해도 deny()는 호출되고 정상 종료된다") + void rejectModification_emailThrowsRuntimeException_denyStillCalled() { + ChangeRequest changeRequest = mock(ChangeRequest.class); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequestRepository.findById(14L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + doThrow(new IllegalStateException("MessageUtils 키 없음")) + .when(alarmService).sendModificationRejectedEmail(any(), anyString()); + + service.rejectModification(100L, new RejectModificationDTO(14L, "사유")); + + verify(changeRequest).deny(eq(mockUser), eq("사유")); + } } // ────────────────────────────────────────────────────────────────────── @@ -585,7 +648,7 @@ void approveModification_volumeSize_success() throws Exception { when(changeRequest.getChangeType()).thenReturn(ChangeType.VOLUME_SIZE); when(changeRequest.getNewValue()).thenReturn("200"); when(changeRequest.getRequest()).thenReturn(originalRequest); - when(changeRequestRepository.findById(1L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(1L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); ApproveModificationDTO dto = new ApproveModificationDTO(1L, "승인합니다"); @@ -593,6 +656,7 @@ void approveModification_volumeSize_success() throws Exception { verify(originalRequest).updateVolumeSize(200L); verify(changeRequest).approve(mockUser, "승인합니다"); + verify(alarmService).sendModificationApprovedEmail(changeRequest, "승인합니다"); } @Test @@ -608,7 +672,7 @@ void approveModification_expiresAt_success() throws Exception { when(changeRequest.getChangeType()).thenReturn(ChangeType.EXPIRES_AT); when(changeRequest.getNewValue()).thenReturn("\"2027-12-31T23:59:59\""); when(changeRequest.getRequest()).thenReturn(originalRequest); - when(changeRequestRepository.findById(2L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(2L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); ApproveModificationDTO dto = new ApproveModificationDTO(2L, "기간 연장 승인"); @@ -619,6 +683,8 @@ void approveModification_expiresAt_success() throws Exception { assertThat(captor.getValue()).isEqualTo(newExpiry); verify(changeRequest).approve(mockUser, "기간 연장 승인"); verify(alarmService).sendContainerExtendedEmail(eq(originalRequest), eq(oldExpiry), eq(newExpiry)); + // EXPIRES_AT은 전용 메일(sendContainerExtendedEmail)만 보내고, 공용 승인 메일은 중복 발송하지 않는다 + verify(alarmService, never()).sendModificationApprovedEmail(any(), any()); } @Test @@ -631,7 +697,7 @@ void approveModification_resourceGroup_success() throws Exception { when(changeRequest.getChangeType()).thenReturn(ChangeType.RESOURCE_GROUP); when(changeRequest.getNewValue()).thenReturn("2"); when(changeRequest.getRequest()).thenReturn(originalRequest); - when(changeRequestRepository.findById(3L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(3L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); when(resourceGroupRepository.findById(2)).thenReturn(Optional.of(newRg)); @@ -640,6 +706,7 @@ void approveModification_resourceGroup_success() throws Exception { verify(originalRequest).updateResourceGroup(newRg); verify(changeRequest).approve(mockUser, "리소스 그룹 변경 승인"); + verify(alarmService).sendModificationApprovedEmail(changeRequest, "리소스 그룹 변경 승인"); } @Test @@ -652,7 +719,7 @@ void approveModification_containerImage_success() throws Exception { when(changeRequest.getChangeType()).thenReturn(ChangeType.CONTAINER_IMAGE); when(changeRequest.getNewValue()).thenReturn("5"); when(changeRequest.getRequest()).thenReturn(originalRequest); - when(changeRequestRepository.findById(4L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(4L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); when(containerImageRepository.findById(5L)).thenReturn(Optional.of(newImage)); @@ -661,12 +728,64 @@ void approveModification_containerImage_success() throws Exception { verify(originalRequest).updateContainerImage(newImage); verify(changeRequest).approve(mockUser, "이미지 변경 승인"); + verify(alarmService).sendModificationApprovedEmail(changeRequest, "이미지 변경 승인"); + } + + @Test + @DisplayName("GROUP 변경 요청 승인 시 originalRequest.addGroup()이 호출된다") + void approveModification_group_success() throws Exception { + ChangeRequest changeRequest = mock(ChangeRequest.class); + Request originalRequest = buildMockedRequestWithStatus(25L, Status.FULFILLED); + Group newGroup = mock(Group.class); + when(newGroup.getUbuntuGid()).thenReturn(42L); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequest.getChangeType()).thenReturn(ChangeType.GROUP); + when(changeRequest.getNewValue()).thenReturn("[42]"); + when(changeRequest.getRequest()).thenReturn(originalRequest); + when(changeRequestRepository.findByIdForUpdate(9L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + when(groupRepository.findByUbuntuGid(42L)).thenReturn(Optional.of(newGroup)); + + ApproveModificationDTO dto = new ApproveModificationDTO(9L, "그룹 변경 승인"); + service.approveModification(100L, dto); + + verify(originalRequest).addGroup(newGroup); + verify(changeRequest).approve(mockUser, "그룹 변경 승인"); + verify(alarmService).sendModificationApprovedEmail(changeRequest, "그룹 변경 승인"); + } + + @Test + @DisplayName("PORT 변경 요청 승인 시 요청된 각 포트에 대해 portRequestService.createPortRequest()가 호출된다") + void approveModification_port_success() throws Exception { + ChangeRequest changeRequest = mock(ChangeRequest.class); + Request originalRequest = buildMockedRequestWithStatus(24L, Status.FULFILLED); + when(originalRequest.getResourceGroup()).thenReturn(mockRg); + when(changeRequest.getStatus()).thenReturn(Status.PENDING); + when(changeRequest.getChangeType()).thenReturn(ChangeType.PORT); + when(changeRequest.getNewValue()).thenReturn( + "[{\"internalPort\":3000,\"usagePurpose\":\"웹 서버\"},{\"internalPort\":6006,\"usagePurpose\":\"텐서보드\"}]"); + when(changeRequest.getRequest()).thenReturn(originalRequest); + when(changeRequestRepository.findByIdForUpdate(8L)).thenReturn(Optional.of(changeRequest)); + when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); + + ApproveModificationDTO dto = new ApproveModificationDTO(8L, "포트 추가 승인"); + service.approveModification(100L, dto); + + ArgumentCaptor portCaptor = ArgumentCaptor.forClass(Integer.class); + ArgumentCaptor purposeCaptor = ArgumentCaptor.forClass(String.class); + verify(portRequestService, times(2)).createPortRequest( + eq(originalRequest), eq(mockRg), portCaptor.capture(), purposeCaptor.capture()); + + assertThat(portCaptor.getAllValues()).containsExactly(3000, 6006); + assertThat(purposeCaptor.getAllValues()).containsExactly("웹 서버", "텐서보드"); + verify(changeRequest).approve(mockUser, "포트 추가 승인"); + verify(alarmService).sendModificationApprovedEmail(changeRequest, "포트 추가 승인"); } @Test @DisplayName("존재하지 않는 변경 요청 ID로 승인하면 BusinessException을 던진다") void approveModification_throwsException_whenChangeRequestNotFound() { - when(changeRequestRepository.findById(999L)).thenReturn(Optional.empty()); + when(changeRequestRepository.findByIdForUpdate(999L)).thenReturn(Optional.empty()); ApproveModificationDTO dto = new ApproveModificationDTO(999L, "승인"); @@ -679,7 +798,7 @@ void approveModification_throwsException_whenChangeRequestNotFound() { void approveModification_throwsException_whenNotPendingStatus() { ChangeRequest changeRequest = mock(ChangeRequest.class); when(changeRequest.getStatus()).thenReturn(Status.FULFILLED); - when(changeRequestRepository.findById(5L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(5L)).thenReturn(Optional.of(changeRequest)); ApproveModificationDTO dto = new ApproveModificationDTO(5L, "승인"); @@ -692,7 +811,7 @@ void approveModification_throwsException_whenNotPendingStatus() { void approveModification_throwsException_whenAdminNotFound() { ChangeRequest changeRequest = mock(ChangeRequest.class); when(changeRequest.getStatus()).thenReturn(Status.PENDING); - when(changeRequestRepository.findById(6L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(6L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(999L)).thenReturn(Optional.empty()); ApproveModificationDTO dto = new ApproveModificationDTO(6L, "승인"); @@ -707,7 +826,7 @@ void approveModification_throwsException_whenOriginalRequestIsNull() { ChangeRequest changeRequest = mock(ChangeRequest.class); when(changeRequest.getStatus()).thenReturn(Status.PENDING); when(changeRequest.getRequest()).thenReturn(null); - when(changeRequestRepository.findById(7L)).thenReturn(Optional.of(changeRequest)); + when(changeRequestRepository.findByIdForUpdate(7L)).thenReturn(Optional.of(changeRequest)); when(userRepository.findById(100L)).thenReturn(Optional.of(mockUser)); ApproveModificationDTO dto = new ApproveModificationDTO(7L, "승인"); diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/RequestEventListenerTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/RequestEventListenerTest.java index 02462efa..838da667 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/RequestEventListenerTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/RequestEventListenerTest.java @@ -12,6 +12,8 @@ import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; +import org.junit.jupiter.api.BeforeEach; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -29,16 +31,29 @@ class RequestEventListenerTest { @Mock private MessageUtils messageUtils; + private static final String SUBJECT = "[DGU AI LAB] 서버 계정 삭제 완료 안내"; + private static final String BODY = "안녕하세요, 홍길동님. 서버 계정이 삭제되었습니다."; + private static final String ADMIN_MSG = "🗑️ [LAB] 리소스 삭제 완료: user1 (server-lab)"; + private static final RequestExpiredEvent EVENT = new RequestExpiredEvent( "홍길동", "hong@test.com", "user1", "server-lab", "pod-xxx", "ssh(30022)", "2025-12-31"); + @BeforeEach + void setUp() { + when(messageUtils.get("notification.expired.detail.subject")).thenReturn(SUBJECT); + when(messageUtils.get(eq("notification.expired.detail.body"), any(), any(), any(), any(), any(), any())) + .thenReturn(BODY); + when(messageUtils.get(eq("notification.admin.delete.success"), any(), any(), any())) + .thenReturn(ADMIN_MSG); + } + @Test @DisplayName("이벤트에 포함된 userName/userEmail로 사용자 알림을 전송한다") void handleExpiredEvent_sendsUserNotificationWithStringFields() { requestEventListener.handleExpiredEvent(EVENT); - verify(alarmService).sendAllAlerts(eq("홍길동"), eq("hong@test.com"), any(), any()); + verify(alarmService).sendAllAlerts(eq("홍길동"), eq("hong@test.com"), eq(SUBJECT), eq(BODY)); } @Test @@ -46,7 +61,7 @@ void handleExpiredEvent_sendsUserNotificationWithStringFields() { void handleExpiredEvent_sendsAdminNotificationWithServerName() { requestEventListener.handleExpiredEvent(EVENT); - verify(alarmService).sendAdminSlackNotification(eq("server-lab"), any()); + verify(alarmService).sendAdminSlackNotification(eq("server-lab"), eq(ADMIN_MSG)); } @Test diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalServiceTest.java new file mode 100644 index 00000000..fea22fc5 --- /dev/null +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/scheduler/UserLifecycleTransactionalServiceTest.java @@ -0,0 +1,148 @@ +package DGU_AI_LAB.admin_be.domain.scheduler; + +import DGU_AI_LAB.admin_be.domain.alarm.service.AlarmService; +import DGU_AI_LAB.admin_be.domain.users.entity.User; +import DGU_AI_LAB.admin_be.domain.users.repository.UserRepository; +import DGU_AI_LAB.admin_be.global.util.MessageUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ValueOperations; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +@MockitoSettings(strictness = Strictness.LENIENT) +@DisplayName("UserLifecycleTransactionalService") +class UserLifecycleTransactionalServiceTest { + + @InjectMocks + private UserLifecycleTransactionalService lifecycleService; + + @Mock + private UserRepository userRepository; + + @Mock + private AlarmService alarmService; + + @Mock + private MessageUtils messageUtils; + + @Mock + private RedisTemplate redisTemplate; + + @Mock + @SuppressWarnings("rawtypes") + private ValueOperations valueOps; + + @BeforeEach + @SuppressWarnings("unchecked") + void setUp() { + when(redisTemplate.opsForValue()).thenReturn(valueOps); + when(valueOps.setIfAbsent(anyString(), any(), any(Duration.class))).thenReturn(true); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); + } + + private User buildUserWithLastLogin(LocalDateTime lastLoginAt) { + User user = User.builder() + .email("test@dgu.ac.kr") + .password("pw") + .name("홍길동") + .studentId("2021001234") + .phone("010-1234-5678") + .department("컴퓨터공학과") + .build(); + try { + var field = User.class.getDeclaredField("lastLoginAt"); + field.setAccessible(true); + field.set(user, lastLoginAt); + var idField = User.class.getDeclaredField("userId"); + idField.setAccessible(true); + idField.set(user, 1L); + } catch (Exception e) { + throw new RuntimeException(e); + } + return user; + } + + @Nested + @DisplayName("processInactiveUser - 경고 알림 중복 방지") + class WarningDeduplication { + + @Test + @DisplayName("D-7 경고 대상이면 알림을 발송한다") + void sendsWarning_whenSevenDaysLeft() { + LocalDateTime now = LocalDateTime.of(2026, 1, 10, 9, 0); + LocalDateTime lastLoginAt = now.plusDays(7).minusMonths(3); + User user = buildUserWithLastLogin(lastLoginAt); + when(userRepository.findById(1L)).thenReturn(Optional.of(user)); + + lifecycleService.processInactiveUser(1L, now); + + verify(alarmService, times(1)).sendAllAlerts(any(), any(), any(), any()); + } + + @Test + @DisplayName("같은 날 동일 유저에게 같은 daysLeft 경고를 두 번 트리거해도 한 번만 발송한다") + void doesNotResendWarning_onSameDayDuplicateTrigger() { + LocalDateTime now = LocalDateTime.of(2026, 1, 10, 9, 0); + LocalDateTime lastLoginAt = now.plusDays(7).minusMonths(3); + User user = buildUserWithLastLogin(lastLoginAt); + when(userRepository.findById(1L)).thenReturn(Optional.of(user)); + + // 첫 호출: SETNX 성공(신규) → 발송 + when(valueOps.setIfAbsent(anyString(), any(), any(Duration.class))).thenReturn(true); + lifecycleService.processInactiveUser(1L, now); + + // 재실행(재배포/수동 트리거 등): SETNX 실패(이미 존재) → 스킵 + when(valueOps.setIfAbsent(anyString(), any(), any(Duration.class))).thenReturn(false); + lifecycleService.processInactiveUser(1L, now); + + verify(alarmService, times(1)).sendAllAlerts(any(), any(), any(), any()); + } + + @Test + @DisplayName("Redis 장애 시에도 경고 발송은 계속 진행한다 (fail-open)") + void sendsWarning_whenRedisFails() { + LocalDateTime now = LocalDateTime.of(2026, 1, 10, 9, 0); + LocalDateTime lastLoginAt = now.plusDays(1).minusMonths(3); + User user = buildUserWithLastLogin(lastLoginAt); + when(userRepository.findById(1L)).thenReturn(Optional.of(user)); + when(valueOps.setIfAbsent(anyString(), any(), any(Duration.class))) + .thenThrow(new RuntimeException("Redis down")); + + lifecycleService.processInactiveUser(1L, now); + + verify(alarmService, times(1)).sendAllAlerts(any(), any(), any(), any()); + } + + @Test + @DisplayName("삭제 예정일이 지난 유저는 중복 방지와 무관하게 Soft Delete된다") + void softDeletesUser_regardlessOfDedup() { + LocalDateTime now = LocalDateTime.of(2026, 1, 10, 9, 0); + LocalDateTime lastLoginAt = now.minusMonths(3).minusDays(1); + User user = buildUserWithLastLogin(lastLoginAt); + when(userRepository.findById(1L)).thenReturn(Optional.of(user)); + + lifecycleService.processInactiveUser(1L, now); + + assertThat(user.getIsActive()).isFalse(); + assertThat(user.getDeletedAt()).isNotNull(); + verify(alarmService, times(1)).sendAllAlerts(any(), any(), any(), any()); + } + } +} diff --git a/src/test/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserServiceTest.java b/src/test/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserServiceTest.java index c8aad4dc..5d413482 100644 --- a/src/test/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserServiceTest.java +++ b/src/test/java/DGU_AI_LAB/admin_be/domain/users/service/AdminUserServiceTest.java @@ -2,6 +2,8 @@ import DGU_AI_LAB.admin_be.domain.alarm.service.AlarmService; import DGU_AI_LAB.admin_be.domain.containerImage.entity.ContainerImage; +import DGU_AI_LAB.admin_be.domain.pod.entity.PodExternalPort; +import DGU_AI_LAB.admin_be.domain.pod.repository.PodExternalPortRepository; import DGU_AI_LAB.admin_be.domain.requests.entity.Request; import DGU_AI_LAB.admin_be.domain.requests.entity.Status; import DGU_AI_LAB.admin_be.domain.requests.repository.RequestRepository; @@ -15,6 +17,7 @@ import DGU_AI_LAB.admin_be.error.ErrorCode; import DGU_AI_LAB.admin_be.error.exception.ConflictException; import DGU_AI_LAB.admin_be.error.exception.EntityNotFoundException; +import DGU_AI_LAB.admin_be.global.util.MessageUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -30,6 +33,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @ExtendWith(MockitoExtension.class) @@ -50,6 +54,12 @@ class AdminUserServiceTest { @Mock private AlarmService alarmService; + @Mock + private PodExternalPortRepository podExternalPortRepository; + + @Mock + private MessageUtils messageUtils; + private User mockUser; @BeforeEach @@ -134,11 +144,14 @@ class DeleteUser { void deleteUser_withNoRequests_softDeletes() { when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of()); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); adminUserService.deleteUser(1L); assertThat(mockUser.getIsActive()).isFalse(); + assertThat(mockUser.getDeletedAt()).isNotNull(); verifyNoInteractions(ubuntuAccountService); + verify(alarmService).sendAllAlerts(eq("홍길동"), eq("test@dgu.ac.kr"), anyString(), anyString()); } @Test @@ -156,15 +169,18 @@ void deleteUser_withFulfilledRequest_callsUbuntuDelete() { Request fulfilledRequest = mock(Request.class); when(fulfilledRequest.getStatus()).thenReturn(Status.FULFILLED); when(fulfilledRequest.getUbuntuUsername()).thenReturn("testuser"); + when(fulfilledRequest.getRequestId()).thenReturn(1L); + when(podExternalPortRepository.findByRequestRequestIdIn(anyList())).thenReturn(List.of()); when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of(fulfilledRequest)); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); adminUserService.deleteUser(1L); verify(ubuntuAccountService).deleteUbuntuAccount("testuser"); verify(fulfilledRequest).deleteAfterCleanup(); - verify(alarmService).sendContainerDeletedEmail(fulfilledRequest); + verify(alarmService).sendContainerDeletedEmail(eq(fulfilledRequest), anyList()); assertThat(mockUser.getIsActive()).isFalse(); } @@ -176,6 +192,7 @@ void deleteUser_withPendingRequest_callsDelete() { when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of(pendingRequest)); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); adminUserService.deleteUser(1L); @@ -191,6 +208,7 @@ void deleteUser_withDeletedRequest_skips() { when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of(deletedRequest)); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); adminUserService.deleteUser(1L); @@ -205,6 +223,8 @@ void deleteUser_withMixedRequests_handlesEachCorrectly() { Request fulfilled = mock(Request.class); when(fulfilled.getStatus()).thenReturn(Status.FULFILLED); when(fulfilled.getUbuntuUsername()).thenReturn("fuser"); + when(fulfilled.getRequestId()).thenReturn(10L); + when(podExternalPortRepository.findByRequestRequestIdIn(anyList())).thenReturn(List.of()); Request pending = mock(Request.class); when(pending.getStatus()).thenReturn(Status.PENDING); @@ -214,16 +234,48 @@ void deleteUser_withMixedRequests_handlesEachCorrectly() { when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of(fulfilled, pending, deleted)); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); adminUserService.deleteUser(1L); verify(ubuntuAccountService).deleteUbuntuAccount("fuser"); verify(fulfilled).deleteAfterCleanup(); - verify(alarmService).sendContainerDeletedEmail(fulfilled); + verify(alarmService).sendContainerDeletedEmail(eq(fulfilled), anyList()); verify(pending).delete(); verify(deleted, never()).delete(); verify(deleted, never()).deleteAfterCleanup(); } + + @Test + @DisplayName("FULFILLED 요청이 여러 개여도 포트 배치 쿼리는 1회만 실행된다") + void deleteUser_multipleFullfilledRequests_batchQueriesPorts() { + Request req1 = mock(Request.class); + when(req1.getStatus()).thenReturn(Status.FULFILLED); + when(req1.getUbuntuUsername()).thenReturn("user1"); + when(req1.getRequestId()).thenReturn(1L); + + Request req2 = mock(Request.class); + when(req2.getStatus()).thenReturn(Status.FULFILLED); + when(req2.getUbuntuUsername()).thenReturn("user2"); + when(req2.getRequestId()).thenReturn(2L); + + Request req3 = mock(Request.class); + when(req3.getStatus()).thenReturn(Status.FULFILLED); + when(req3.getUbuntuUsername()).thenReturn("user3"); + when(req3.getRequestId()).thenReturn(3L); + + when(userRepository.findById(1L)).thenReturn(Optional.of(mockUser)); + when(requestRepository.findAllByUser(mockUser)).thenReturn(List.of(req1, req2, req3)); + when(podExternalPortRepository.findByRequestRequestIdIn(anyList())).thenReturn(List.of()); + when(messageUtils.get(anyString(), any(Object[].class))).thenReturn("mock"); + + adminUserService.deleteUser(1L); + + // 개별 쿼리(findByRequestRequestId) 미호출, 배치 쿼리 1회만 호출 + verify(podExternalPortRepository, never()).findByRequestRequestId(any()); + verify(podExternalPortRepository, times(1)).findByRequestRequestIdIn(anyList()); + verify(alarmService, times(3)).sendContainerDeletedEmail(any(Request.class), anyList()); + } } @Nested From 1a5206e9d1e58d7b3d6b6cf9dd5bc861e8251822 Mon Sep 17 00:00:00 2001 From: yoon6yo Date: Thu, 20 Aug 2026 02:07:54 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20FARM=20=EA=B3=B5=EC=9D=B8=20?= =?UTF-8?q?=ED=8F=AC=ED=8A=B8=20=EC=95=88=EB=82=B4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?develop=EC=97=90=20=EB=B0=98=EC=98=81=20(main=EA=B3=BC=20?= =?UTF-8?q?=EB=8F=99=EA=B8=B0=ED=99=94)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit main(#374)에서만 존재하던 FARM pfSense 공인 포트 오프셋 변환 로직을 develop에 반영해 두 브랜치를 동기화. develop→main PR(#383)의 충돌 해소 목적. --- .../domain/alarm/service/AlarmService.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java index 43a8227e..7074a456 100644 --- a/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java +++ b/src/main/java/DGU_AI_LAB/admin_be/domain/alarm/service/AlarmService.java @@ -147,6 +147,13 @@ public void sendContainerCreatedEmail(Request request, String sshPort, String ju var image = request.getContainerImage(); String serverName = request.getResourceGroup().getServerName(); + // FARM은 pfSense가 210.94.179.19:9300-9397 → farm6:30000-30097로 오프셋 포워딩하므로 + // 사용자에겐 NodePort가 아니라 공인 포트를 안내해야 한다 (26-07-15 외부 실측 검증). + if ("FARM".equalsIgnoreCase(serverName)) { + sshPort = toFarmPublicPort(sshPort); + jupyterPort = toFarmPublicPort(jupyterPort); + } + List allPorts = podExternalPortRepository.findByRequestRequestId(request.getRequestId()); String extraPorts = PodPortUtils.formatExtraPortSummary(allPorts); @@ -165,6 +172,23 @@ public void sendContainerCreatedEmail(Request request, String sshPort, String ju sendMonitoringLog(user.getName(), user.getEmail(), subject); } + // ponytail: pfSense FARM 오프셋 매핑 하드코딩(admin_fe publicEndpoint.js와 동일 공식). 대역이 늘면 설정으로. + private static final int NODEPORT_BASE = 30000; + private static final int FARM_PUBLIC_PORT_BASE = 9300; + private static final int FARM_PUBLIC_BAND_SIZE = 98; // 외부 9300-9397 + + private String toFarmPublicPort(String nodePort) { + try { + int offset = Integer.parseInt(nodePort) - NODEPORT_BASE; + if (offset >= 0 && offset < FARM_PUBLIC_BAND_SIZE) { + return String.valueOf(FARM_PUBLIC_PORT_BASE + offset); + } + } catch (NumberFormatException ignored) { + // 빈 문자열 등 — 원본 그대로 반환 + } + return nodePort; // 매핑 대역 밖이면 원본 유지(외부 미개방 포트임이 그대로 드러나는 편이 낫다) + } + // ponytail: LAB/FARM 2-호스트 하드코딩. 호스트가 늘면 노드/설정 레지스트리로. private String resolveHostIp(String serverName) { if (serverName == null) return "";