From 40fa71884cc5afc00ba7d0cbabd1945cacce4886 Mon Sep 17 00:00:00 2001 From: kelly6bf Date: Mon, 18 Nov 2024 14:20:49 +0900 Subject: [PATCH 1/8] =?UTF-8?q?chore:=20#961=20build.gradle=20Web=20Socket?= =?UTF-8?q?=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/build.gradle b/backend/build.gradle index 987827899..0c8e32a20 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -59,6 +59,9 @@ dependencies { implementation 'io.jsonwebtoken:jjwt:0.12.6' implementation 'io.jsonwebtoken:jjwt-impl:0.12.6' + // Web Socket + implementation 'org.springframework.boot:spring-boot-starter-websocket' + // Test testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' From bd30648a42c7b4f67a2434f2f7cf5a2e9cc596c0 Mon Sep 17 00:00:00 2001 From: kelly6bf Date: Mon, 18 Nov 2024 17:20:18 +0900 Subject: [PATCH 2/8] =?UTF-8?q?chore:=20#961=20SchedulerService=20WS=20?= =?UTF-8?q?=EC=82=BD=EC=9E=85=20=EA=B5=AC=EA=B0=84=20=EB=A7=88=ED=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/site/coduo/sync/service/SchedulerService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java index 8cc4795f9..cba6a6378 100644 --- a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java +++ b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java @@ -32,6 +32,7 @@ public void start(final String key) { if (schedulerRegistry.isActive(key)) { return; } + // TODO : WS로 전환 sseService.broadcast(key, "timer", "start"); if (isInitial(key)) { final Timer timer = timerRepository.fetchTimerByAccessCode(key) @@ -59,11 +60,13 @@ private void runTimer(final String key, final Timer timer) { stop(key, timer); return; } + // TODO : WS로 전환 if (sseService.hasNoConnections(key) && schedulerRegistry.has(key)) { pause(key); return; } timer.decreaseRemainingTime(DELAY_SECOND.toMillis()); + // TODO : WS로 전환 sseService.broadcast(key, "remaining-time", String.valueOf(timer.getRemainingTime())); } @@ -75,6 +78,7 @@ public void pause(final String key) { } private void stop(final String key, final Timer timer) { + // TODO : WS로 전환 sseService.broadcast(key, "timer", "stop"); schedulerRegistry.release(key); final Timer initalTimer = new Timer(timer.getAccessCode(), timer.getDuration(), timer.getDuration()); From 6afcc39ef3b219f324a8df67e4d5f261fa68d187 Mon Sep 17 00:00:00 2001 From: kelly6bf Date: Tue, 19 Nov 2024 14:40:22 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20#961=20Web=20Socket=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NotFoundPairRoomSessionException.java | 8 +++ .../websocket/PairRoomWebSocketService.java | 25 ++++++++ .../PairRoomWebSocketSessionStore.java | 54 ++++++++++++++++ .../site/coduo/websocket/WebSocketConfig.java | 22 +++++++ .../coduo/websocket/WebSocketHandler.java | 63 +++++++++++++++++++ .../coduo/websocket/WebSocketMessage.java | 4 ++ .../site/coduo/websocket/WebSocketSender.java | 34 ++++++++++ .../message/EventAndDataMessage.java | 6 ++ 8 files changed, 216 insertions(+) create mode 100644 backend/src/main/java/site/coduo/pairroom/exception/NotFoundPairRoomSessionException.java create mode 100644 backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java create mode 100644 backend/src/main/java/site/coduo/websocket/PairRoomWebSocketSessionStore.java create mode 100644 backend/src/main/java/site/coduo/websocket/WebSocketConfig.java create mode 100644 backend/src/main/java/site/coduo/websocket/WebSocketHandler.java create mode 100644 backend/src/main/java/site/coduo/websocket/WebSocketMessage.java create mode 100644 backend/src/main/java/site/coduo/websocket/WebSocketSender.java create mode 100644 backend/src/main/java/site/coduo/websocket/message/EventAndDataMessage.java diff --git a/backend/src/main/java/site/coduo/pairroom/exception/NotFoundPairRoomSessionException.java b/backend/src/main/java/site/coduo/pairroom/exception/NotFoundPairRoomSessionException.java new file mode 100644 index 000000000..30895d563 --- /dev/null +++ b/backend/src/main/java/site/coduo/pairroom/exception/NotFoundPairRoomSessionException.java @@ -0,0 +1,8 @@ +package site.coduo.pairroom.exception; + +public class NotFoundPairRoomSessionException extends PairRoomException { + + public NotFoundPairRoomSessionException(final String message) { + super(message); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java new file mode 100644 index 000000000..3c0c9cd16 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java @@ -0,0 +1,25 @@ +package site.coduo.websocket; + +import java.util.Set; + +import org.springframework.stereotype.Service; +import org.springframework.web.socket.WebSocketSession; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@Service +public class PairRoomWebSocketService { + + private final PairRoomWebSocketSessionStore pairRoomWebSocketSessionStore; + private final WebSocketSender webSocketSender; + + public void sendAllPairRoomSessions(final String pairRoomAccessCode, final WebSocketMessage message) { + final Set sessions = pairRoomWebSocketSessionStore.getSessions(pairRoomAccessCode); + webSocketSender.sendMessage(sessions, message); + } + + public boolean hasNoConnections(final String pairRoomAccessCode) { + return !pairRoomWebSocketSessionStore.hasPairRoomSessions(pairRoomAccessCode); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketSessionStore.java b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketSessionStore.java new file mode 100644 index 000000000..0e293acd6 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketSessionStore.java @@ -0,0 +1,54 @@ +package site.coduo.websocket; + +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.WebSocketSession; + +import lombok.RequiredArgsConstructor; +import site.coduo.pairroom.exception.InvalidAccessCodeException; +import site.coduo.pairroom.exception.NotFoundPairRoomSessionException; +import site.coduo.pairroom.exception.PairRoomNotFoundException; +import site.coduo.pairroom.repository.PairRoomRepository; + +@RequiredArgsConstructor +@Component +public class PairRoomWebSocketSessionStore { + + private final PairRoomRepository pairRoomRepository; + private final Map> sessions = new ConcurrentHashMap<>(); + + public void addSession(final String pairRoomAccessCode, final WebSocketSession session) { + validatePairRoomAccessCode(pairRoomAccessCode); + if (!sessions.containsKey(pairRoomAccessCode)) { + sessions.put(pairRoomAccessCode, new HashSet<>()); + } + sessions.get(pairRoomAccessCode).add(session); + } + + private void validatePairRoomAccessCode(final String pairRoomAccessCode) { + if (pairRoomAccessCode == null || pairRoomAccessCode.isBlank()) { + throw new InvalidAccessCodeException("페어룸 접근 코드로 null이 입력될 수 없습니다."); + } + + if (!pairRoomRepository.existsByAccessCode(pairRoomAccessCode)) { + throw new PairRoomNotFoundException("존재하지 않는 페어룸 코드입니다. - " + pairRoomAccessCode); + } + } + + public Set getSessions(final String pairRoomAccessCode) { + validatePairRoomAccessCode(pairRoomAccessCode); + if (!sessions.containsKey(pairRoomAccessCode)) { + throw new NotFoundPairRoomSessionException("해당 페어룸의 세션이 존재하지 않습니다. - " + pairRoomAccessCode); + } + return sessions.get(pairRoomAccessCode); + } + + public boolean hasPairRoomSessions(final String pairRoomAccessCode) { + validatePairRoomAccessCode(pairRoomAccessCode); + return sessions.containsKey(pairRoomAccessCode); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketConfig.java b/backend/src/main/java/site/coduo/websocket/WebSocketConfig.java new file mode 100644 index 000000000..971aa509c --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/WebSocketConfig.java @@ -0,0 +1,22 @@ +package site.coduo.websocket; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +@EnableWebSocket +@Configuration +public class WebSocketConfig implements WebSocketConfigurer { + + private final WebSocketHandler webSocketHandler; + + @Override + public void registerWebSocketHandlers(final WebSocketHandlerRegistry registry) { + registry.addHandler(webSocketHandler, "/ws-connect") + .setAllowedOrigins("*"); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java new file mode 100644 index 000000000..1f728121a --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java @@ -0,0 +1,63 @@ +package site.coduo.websocket; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.CloseStatus; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +@Component +public class WebSocketHandler extends TextWebSocketHandler { + + private final PairRoomWebSocketSessionStore pairRoomWebSocketSessionStore; + + @Override + public void afterConnectionEstablished(final WebSocketSession session) { + final String query = session.getUri().getQuery(); + final String pairRoomAccessCode = parsePairRoomAccessCode(query); + pairRoomWebSocketSessionStore.addSession(pairRoomAccessCode, session); + log.info("연결 성공 : {}", session.getId()); + } + + // TODO : 솔직히 이건 좀 아니지 얂냐... 개선하자 우테코 나왔으면 켈리야.. + private String parsePairRoomAccessCode(final String query) { + if (query == null || query.isEmpty()) { + throw new IllegalArgumentException("Web Socket 연결 uri에 페어룸 Access Code가 존재하지 않습니다."); + } + + if (query != null) { + String[] pairs = query.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8) : pair; + if ("accesscode".equals(key)) { + return URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8); + } + } + } + return null; // 또는 기본값 설정 + } + + @Override + protected void handleTextMessage(final WebSocketSession session, final TextMessage message) { + // TODO : 클라이언트의 메시지를 파싱하는 메서드. 타이머 잔여 시간 조회에 필요가 없어 우선 보류 + } + + @Override + public void handleTransportError(final WebSocketSession session, final Throwable exception) { + log.error("Web Socket 전송 중 에러 발생 : {}", exception.getMessage()); + } + + @Override + public void afterConnectionClosed(final WebSocketSession session, final CloseStatus status) { + log.info("연결 종료 : {}, 상태 : {}", session.getId(), status); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketMessage.java b/backend/src/main/java/site/coduo/websocket/WebSocketMessage.java new file mode 100644 index 000000000..0951b62d5 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/WebSocketMessage.java @@ -0,0 +1,4 @@ +package site.coduo.websocket; + +public interface WebSocketMessage { +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketSender.java b/backend/src/main/java/site/coduo/websocket/WebSocketSender.java new file mode 100644 index 000000000..2d3ec734f --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/WebSocketSender.java @@ -0,0 +1,34 @@ +package site.coduo.websocket; + +import java.io.IOException; +import java.util.Set; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +@Component +public class WebSocketSender { + + private final ObjectMapper objectMapper; + + public void sendMessage(final Set sessions, final WebSocketMessage message) { + sessions.parallelStream().forEach(session -> sendMessage(session, message)); + } + + private void sendMessage(final WebSocketSession session, final WebSocketMessage message) { + try { + final TextMessage webSocketMessage = new TextMessage(objectMapper.writeValueAsString(message)); + session.sendMessage(webSocketMessage); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/backend/src/main/java/site/coduo/websocket/message/EventAndDataMessage.java b/backend/src/main/java/site/coduo/websocket/message/EventAndDataMessage.java new file mode 100644 index 000000000..b06d18388 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/message/EventAndDataMessage.java @@ -0,0 +1,6 @@ +package site.coduo.websocket.message; + +import site.coduo.websocket.WebSocketMessage; + +public record EventAndDataMessage(String event, String data) implements WebSocketMessage { +} From 17a898f6b11fc23130f3873befe1c7a879c7b345 Mon Sep 17 00:00:00 2001 From: yechop Date: Tue, 19 Nov 2024 16:59:30 +0900 Subject: [PATCH 4/8] =?UTF-8?q?refactor:=20=EC=BF=BC=EB=A6=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=95=A1=EC=84=B8=EC=8A=A4=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=ED=95=98=EB=8A=94=20=EC=97=AD=ED=95=A0=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/QueryAccessCodeParser.java | 38 ++++++++++++++ .../coduo/websocket/WebSocketHandler.java | 24 +-------- .../exception/EmptyQueryException.java | 8 +++ .../NotFoundAccessCodeInQueryException.java | 8 +++ .../exception/WebSocketException.java | 8 +++ .../websocket/QueryAccessCodeParserTest.java | 52 +++++++++++++++++++ 6 files changed, 115 insertions(+), 23 deletions(-) create mode 100644 backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java create mode 100644 backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java diff --git a/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java b/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java new file mode 100644 index 000000000..4761e6846 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java @@ -0,0 +1,38 @@ +package site.coduo.websocket; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import site.coduo.websocket.exception.EmptyQueryException; +import site.coduo.websocket.exception.NotFoundAccessCodeInQueryException; + +public class QueryAccessCodeParser { + + private static final String QUERY_DELIMITER = "&"; + private static final String KEY_VALUE_DELIMITER = "="; + private static final int ACCESS_CODE_QUERY_SIZE = 2; + private static final int KEY_INDEX = 0; + private static final String ACCESS_CODE_KEY_NAME = "accesscode"; + private static final int VALUE_INDEX = 1; + + public static String parse(final String query) { + validateQuery(query); + return Arrays.stream(query.split(QUERY_DELIMITER)) + .map(keyValuePair -> keyValuePair.split(KEY_VALUE_DELIMITER)) + .filter(QueryAccessCodeParser::isAccessCodeKeyValuePair) + .findFirst() + .map(accessCodeKeyValue -> URLDecoder.decode(accessCodeKeyValue[VALUE_INDEX], StandardCharsets.UTF_8)) + .orElseThrow(() -> new NotFoundAccessCodeInQueryException("쿼리에 액세스코드가 존재하지 않습니다.")); + } + + private static void validateQuery(final String query) { + if (query == null || query.isEmpty()) { + throw new EmptyQueryException("쿼리가 존재하지 않습니다."); + } + } + + private static boolean isAccessCodeKeyValuePair(final String[] keyValuePair) { + return keyValuePair.length == ACCESS_CODE_QUERY_SIZE && keyValuePair[KEY_INDEX].equals(ACCESS_CODE_KEY_NAME); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java index 1f728121a..1133d1a00 100644 --- a/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java +++ b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java @@ -1,8 +1,5 @@ package site.coduo.websocket; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; - import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; @@ -22,30 +19,11 @@ public class WebSocketHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(final WebSocketSession session) { final String query = session.getUri().getQuery(); - final String pairRoomAccessCode = parsePairRoomAccessCode(query); + final String pairRoomAccessCode = QueryAccessCodeParser.parse(query); pairRoomWebSocketSessionStore.addSession(pairRoomAccessCode, session); log.info("연결 성공 : {}", session.getId()); } - // TODO : 솔직히 이건 좀 아니지 얂냐... 개선하자 우테코 나왔으면 켈리야.. - private String parsePairRoomAccessCode(final String query) { - if (query == null || query.isEmpty()) { - throw new IllegalArgumentException("Web Socket 연결 uri에 페어룸 Access Code가 존재하지 않습니다."); - } - - if (query != null) { - String[] pairs = query.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8) : pair; - if ("accesscode".equals(key)) { - return URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8); - } - } - } - return null; // 또는 기본값 설정 - } - @Override protected void handleTextMessage(final WebSocketSession session, final TextMessage message) { // TODO : 클라이언트의 메시지를 파싱하는 메서드. 타이머 잔여 시간 조회에 필요가 없어 우선 보류 diff --git a/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java new file mode 100644 index 000000000..b9b54a737 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class EmptyQueryException extends WebSocketException { + + public EmptyQueryException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java new file mode 100644 index 000000000..c61cb293e --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class NotFoundAccessCodeInQueryException extends WebSocketException { + + public NotFoundAccessCodeInQueryException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java new file mode 100644 index 000000000..8cb1f648a --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class WebSocketException extends RuntimeException { + + public WebSocketException(String message) { + super(message); + } +} diff --git a/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java new file mode 100644 index 000000000..0886ceba5 --- /dev/null +++ b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java @@ -0,0 +1,52 @@ +package site.coduo.websocket; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URLEncoder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import site.coduo.websocket.exception.EmptyQueryException; +import site.coduo.websocket.exception.NotFoundAccessCodeInQueryException; + +class QueryAccessCodeParserTest { + + @DisplayName("query에서 accesscode를 추출한다.") + @ParameterizedTest + @CsvSource(value = {"user=ink&accesscode=abcde-&role=admin", "accesscode=abcde-",}) + void parseAccessCode(final String query) { + final String accessCode = QueryAccessCodeParser.parse(query); + assertThat(accessCode).isEqualTo("abcde-"); + } + + @DisplayName("인코딩된 query에서 accesscode를 추출한다.") + @Test + void parseEncodedAccessCode() { + final String encode = URLEncoder.encode("abcde-"); + final String accessCode = QueryAccessCodeParser.parse("user=john&accesscode=" + encode); + assertThat(accessCode).isEqualTo("abcde-"); + } + + @DisplayName("query가 비어있거나 null이면 예외가 발생한다.") + @NullAndEmptySource + @ParameterizedTest + void throwExceptionWhenQueryIsEmptyOrNull(final String query) { + assertThatThrownBy(() -> QueryAccessCodeParser.parse(query)) + .isExactlyInstanceOf(EmptyQueryException.class) + .hasMessageContaining("쿼리가 존재하지 않습니다"); + } + + @DisplayName("accesscode가 비어있으면 예외가 발생한다.") + @Test + void throwExceptionWhenAccessCodeIsEmpty() { + String query = "user=ink&accesscode="; + assertThatThrownBy(() -> QueryAccessCodeParser.parse(query)) + .isExactlyInstanceOf(NotFoundAccessCodeInQueryException.class) + .hasMessageContaining("쿼리에 액세스코드가 존재하지 않습니다."); + } +} From 2957562a608e960c78982e75a7464c364f3ef1fb Mon Sep 17 00:00:00 2001 From: yechop Date: Tue, 19 Nov 2024 16:59:30 +0900 Subject: [PATCH 5/8] =?UTF-8?q?refactor:=20=EC=BF=BC=EB=A6=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=95=A1=EC=84=B8=EC=8A=A4=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=ED=95=98=EB=8A=94=20=EC=97=AD=ED=95=A0=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/QueryAccessCodeParser.java | 38 +++++++++++++ .../coduo/websocket/WebSocketHandler.java | 24 +------- .../exception/EmptyQueryException.java | 8 +++ .../NotFoundAccessCodeInQueryException.java | 8 +++ .../exception/WebSocketException.java | 8 +++ .../websocket/QueryAccessCodeParserTest.java | 55 +++++++++++++++++++ 6 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java create mode 100644 backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java create mode 100644 backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java diff --git a/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java b/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java new file mode 100644 index 000000000..4761e6846 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/QueryAccessCodeParser.java @@ -0,0 +1,38 @@ +package site.coduo.websocket; + +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +import site.coduo.websocket.exception.EmptyQueryException; +import site.coduo.websocket.exception.NotFoundAccessCodeInQueryException; + +public class QueryAccessCodeParser { + + private static final String QUERY_DELIMITER = "&"; + private static final String KEY_VALUE_DELIMITER = "="; + private static final int ACCESS_CODE_QUERY_SIZE = 2; + private static final int KEY_INDEX = 0; + private static final String ACCESS_CODE_KEY_NAME = "accesscode"; + private static final int VALUE_INDEX = 1; + + public static String parse(final String query) { + validateQuery(query); + return Arrays.stream(query.split(QUERY_DELIMITER)) + .map(keyValuePair -> keyValuePair.split(KEY_VALUE_DELIMITER)) + .filter(QueryAccessCodeParser::isAccessCodeKeyValuePair) + .findFirst() + .map(accessCodeKeyValue -> URLDecoder.decode(accessCodeKeyValue[VALUE_INDEX], StandardCharsets.UTF_8)) + .orElseThrow(() -> new NotFoundAccessCodeInQueryException("쿼리에 액세스코드가 존재하지 않습니다.")); + } + + private static void validateQuery(final String query) { + if (query == null || query.isEmpty()) { + throw new EmptyQueryException("쿼리가 존재하지 않습니다."); + } + } + + private static boolean isAccessCodeKeyValuePair(final String[] keyValuePair) { + return keyValuePair.length == ACCESS_CODE_QUERY_SIZE && keyValuePair[KEY_INDEX].equals(ACCESS_CODE_KEY_NAME); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java index 1f728121a..1133d1a00 100644 --- a/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java +++ b/backend/src/main/java/site/coduo/websocket/WebSocketHandler.java @@ -1,8 +1,5 @@ package site.coduo.websocket; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; - import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; @@ -22,30 +19,11 @@ public class WebSocketHandler extends TextWebSocketHandler { @Override public void afterConnectionEstablished(final WebSocketSession session) { final String query = session.getUri().getQuery(); - final String pairRoomAccessCode = parsePairRoomAccessCode(query); + final String pairRoomAccessCode = QueryAccessCodeParser.parse(query); pairRoomWebSocketSessionStore.addSession(pairRoomAccessCode, session); log.info("연결 성공 : {}", session.getId()); } - // TODO : 솔직히 이건 좀 아니지 얂냐... 개선하자 우테코 나왔으면 켈리야.. - private String parsePairRoomAccessCode(final String query) { - if (query == null || query.isEmpty()) { - throw new IllegalArgumentException("Web Socket 연결 uri에 페어룸 Access Code가 존재하지 않습니다."); - } - - if (query != null) { - String[] pairs = query.split("&"); - for (String pair : pairs) { - int idx = pair.indexOf("="); - String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8) : pair; - if ("accesscode".equals(key)) { - return URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8); - } - } - } - return null; // 또는 기본값 설정 - } - @Override protected void handleTextMessage(final WebSocketSession session, final TextMessage message) { // TODO : 클라이언트의 메시지를 파싱하는 메서드. 타이머 잔여 시간 조회에 필요가 없어 우선 보류 diff --git a/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java new file mode 100644 index 000000000..b9b54a737 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class EmptyQueryException extends WebSocketException { + + public EmptyQueryException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java new file mode 100644 index 000000000..c61cb293e --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class NotFoundAccessCodeInQueryException extends WebSocketException { + + public NotFoundAccessCodeInQueryException(String message) { + super(message); + } +} diff --git a/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java new file mode 100644 index 000000000..8cb1f648a --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java @@ -0,0 +1,8 @@ +package site.coduo.websocket.exception; + +public class WebSocketException extends RuntimeException { + + public WebSocketException(String message) { + super(message); + } +} diff --git a/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java new file mode 100644 index 000000000..67fa5aec6 --- /dev/null +++ b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java @@ -0,0 +1,55 @@ +package site.coduo.websocket; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.net.URLEncoder; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; + +import site.coduo.websocket.exception.EmptyQueryException; +import site.coduo.websocket.exception.NotFoundAccessCodeInQueryException; + +class QueryAccessCodeParserTest { + + @DisplayName("query에서 accesscode를 추출한다.") + @ParameterizedTest + @CsvSource(value = {"user=ink&accesscode=abcde-&role=admin", "accesscode=abcde-",}) + void parseAccessCode(final String query) { + final String accessCode = QueryAccessCodeParser.parse(query); + assertThat(accessCode).isEqualTo("abcde-"); + } + + @DisplayName("인코딩된 query에서 accesscode를 추출한다.") + @Test + void parseEncodedAccessCode() { + // given + final String encode = URLEncoder.encode("abcde-"); + + // when & then + final String accessCode = QueryAccessCodeParser.parse("user=john&accesscode=" + encode); + assertThat(accessCode).isEqualTo("abcde-"); + } + + @DisplayName("query가 비어있거나 null이면 예외가 발생한다.") + @NullAndEmptySource + @ParameterizedTest + void throwExceptionWhenQueryIsEmptyOrNull(final String query) { + assertThatThrownBy(() -> QueryAccessCodeParser.parse(query)) + .isExactlyInstanceOf(EmptyQueryException.class) + .hasMessageContaining("쿼리가 존재하지 않습니다"); + } + + @DisplayName("accesscode가 비어있으면 예외가 발생한다.") + @Test + void throwExceptionWhenAccessCodeIsEmpty() { + String query = "user=ink&accesscode="; + assertThatThrownBy(() -> QueryAccessCodeParser.parse(query)) + .isExactlyInstanceOf(NotFoundAccessCodeInQueryException.class) + .hasMessageContaining("쿼리에 액세스코드가 존재하지 않습니다."); + } +} From cce686129790c843fd4763aaad7622e2f09c920b Mon Sep 17 00:00:00 2001 From: kelly6bf Date: Wed, 20 Nov 2024 15:28:16 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20#961=20=EA=B8=B0=EC=A1=B4=20SSE?= =?UTF-8?q?=20=EA=B8=B0=EB=B0=98=20=EC=BD=94=EB=93=9C=EB=A5=BC=20Web=20Soc?= =?UTF-8?q?ket=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../coduo/sync/service/SchedulerService.java | 17 +++++---- .../websocket/PairRoomWebSocketService.java | 4 +-- .../coduo/websocket/ProdWebSocketSender.java | 35 +++++++++++++++++++ .../site/coduo/websocket/WebSocketSender.java | 28 ++------------- 4 files changed, 47 insertions(+), 37 deletions(-) create mode 100644 backend/src/main/java/site/coduo/websocket/ProdWebSocketSender.java diff --git a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java index cba6a6378..a23f14234 100644 --- a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java +++ b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java @@ -14,6 +14,8 @@ import site.coduo.timer.domain.Timer; import site.coduo.timer.repository.TimerRepository; import site.coduo.timer.service.TimestampRegistry; +import site.coduo.websocket.PairRoomWebSocketService; +import site.coduo.websocket.message.EventAndDataMessage; @Slf4j @RequiredArgsConstructor @@ -22,6 +24,7 @@ public class SchedulerService { public static final Duration DELAY_SECOND = Duration.of(1, ChronoUnit.SECONDS); + private final PairRoomWebSocketService pairRoomWebSocketService; private final ThreadPoolTaskScheduler taskScheduler; private final SchedulerRegistry schedulerRegistry; private final TimestampRegistry timestampRegistry; @@ -32,8 +35,7 @@ public void start(final String key) { if (schedulerRegistry.isActive(key)) { return; } - // TODO : WS로 전환 - sseService.broadcast(key, "timer", "start"); + pairRoomWebSocketService.sendAllPairRoomSessions(key, new EventAndDataMessage("timer", "start")); if (isInitial(key)) { final Timer timer = timerRepository.fetchTimerByAccessCode(key) .toDomain(); @@ -60,26 +62,23 @@ private void runTimer(final String key, final Timer timer) { stop(key, timer); return; } - // TODO : WS로 전환 - if (sseService.hasNoConnections(key) && schedulerRegistry.has(key)) { + if (pairRoomWebSocketService.hasNoConnections(key) && schedulerRegistry.has(key)) { pause(key); return; } timer.decreaseRemainingTime(DELAY_SECOND.toMillis()); - // TODO : WS로 전환 - sseService.broadcast(key, "remaining-time", String.valueOf(timer.getRemainingTime())); + pairRoomWebSocketService.sendAllPairRoomSessions(key, new EventAndDataMessage("remaining-time", String.valueOf(timer.getRemainingTime()))); } public void pause(final String key) { if (schedulerRegistry.isActive(key)) { - sseService.broadcast(key, "timer", "pause"); + pairRoomWebSocketService.sendAllPairRoomSessions(key, new EventAndDataMessage("timer", "pause")); schedulerRegistry.release(key); } } private void stop(final String key, final Timer timer) { - // TODO : WS로 전환 - sseService.broadcast(key, "timer", "stop"); + pairRoomWebSocketService.sendAllPairRoomSessions(key, new EventAndDataMessage("timer", "stop")); schedulerRegistry.release(key); final Timer initalTimer = new Timer(timer.getAccessCode(), timer.getDuration(), timer.getDuration()); timestampRegistry.register(key, initalTimer); diff --git a/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java index 3c0c9cd16..af7c291f5 100644 --- a/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java +++ b/backend/src/main/java/site/coduo/websocket/PairRoomWebSocketService.java @@ -12,11 +12,11 @@ public class PairRoomWebSocketService { private final PairRoomWebSocketSessionStore pairRoomWebSocketSessionStore; - private final WebSocketSender webSocketSender; + private final WebSocketSender prodWebSocketSender; public void sendAllPairRoomSessions(final String pairRoomAccessCode, final WebSocketMessage message) { final Set sessions = pairRoomWebSocketSessionStore.getSessions(pairRoomAccessCode); - webSocketSender.sendMessage(sessions, message); + prodWebSocketSender.sendMessage(sessions, message); } public boolean hasNoConnections(final String pairRoomAccessCode) { diff --git a/backend/src/main/java/site/coduo/websocket/ProdWebSocketSender.java b/backend/src/main/java/site/coduo/websocket/ProdWebSocketSender.java new file mode 100644 index 000000000..dbe9710b1 --- /dev/null +++ b/backend/src/main/java/site/coduo/websocket/ProdWebSocketSender.java @@ -0,0 +1,35 @@ +package site.coduo.websocket; + +import java.io.IOException; +import java.util.Set; + +import org.springframework.stereotype.Component; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RequiredArgsConstructor +@Component +public class ProdWebSocketSender implements WebSocketSender { + + private final ObjectMapper objectMapper; + + @Override + public void sendMessage(final Set sessions, final WebSocketMessage message) { + sessions.parallelStream().forEach(session -> sendMessage(session, message)); + } + + private void sendMessage(final WebSocketSession session, final WebSocketMessage message) { + try { + final TextMessage webSocketMessage = new TextMessage(objectMapper.writeValueAsString(message)); + session.sendMessage(webSocketMessage); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/backend/src/main/java/site/coduo/websocket/WebSocketSender.java b/backend/src/main/java/site/coduo/websocket/WebSocketSender.java index 2d3ec734f..635314e71 100644 --- a/backend/src/main/java/site/coduo/websocket/WebSocketSender.java +++ b/backend/src/main/java/site/coduo/websocket/WebSocketSender.java @@ -1,34 +1,10 @@ package site.coduo.websocket; -import java.io.IOException; import java.util.Set; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; -import com.fasterxml.jackson.databind.ObjectMapper; +public interface WebSocketSender { -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@RequiredArgsConstructor -@Component -public class WebSocketSender { - - private final ObjectMapper objectMapper; - - public void sendMessage(final Set sessions, final WebSocketMessage message) { - sessions.parallelStream().forEach(session -> sendMessage(session, message)); - } - - private void sendMessage(final WebSocketSession session, final WebSocketMessage message) { - try { - final TextMessage webSocketMessage = new TextMessage(objectMapper.writeValueAsString(message)); - session.sendMessage(webSocketMessage); - } catch (IOException e) { - log.error(e.getMessage(), e); - } - } + void sendMessage(final Set sessions, final WebSocketMessage message); } From 32f472f00e45f41bc30676bdd6fb6037ca9c01df Mon Sep 17 00:00:00 2001 From: yechop Date: Thu, 21 Nov 2024 17:10:45 +0900 Subject: [PATCH 7/8] =?UTF-8?q?chore:=20final=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../site/coduo/websocket/exception/EmptyQueryException.java | 2 +- .../websocket/exception/NotFoundAccessCodeInQueryException.java | 2 +- .../java/site/coduo/websocket/exception/WebSocketException.java | 2 +- .../java/site/coduo/websocket/QueryAccessCodeParserTest.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java index b9b54a737..db4f7771f 100644 --- a/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java +++ b/backend/src/main/java/site/coduo/websocket/exception/EmptyQueryException.java @@ -2,7 +2,7 @@ public class EmptyQueryException extends WebSocketException { - public EmptyQueryException(String message) { + public EmptyQueryException(final String message) { super(message); } } diff --git a/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java index c61cb293e..696781f22 100644 --- a/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java +++ b/backend/src/main/java/site/coduo/websocket/exception/NotFoundAccessCodeInQueryException.java @@ -2,7 +2,7 @@ public class NotFoundAccessCodeInQueryException extends WebSocketException { - public NotFoundAccessCodeInQueryException(String message) { + public NotFoundAccessCodeInQueryException(final String message) { super(message); } } diff --git a/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java index 8cb1f648a..b41cfa669 100644 --- a/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java +++ b/backend/src/main/java/site/coduo/websocket/exception/WebSocketException.java @@ -2,7 +2,7 @@ public class WebSocketException extends RuntimeException { - public WebSocketException(String message) { + public WebSocketException(final String message) { super(message); } } diff --git a/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java index 0886ceba5..b9676ad5e 100644 --- a/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java +++ b/backend/src/test/java/site/coduo/websocket/QueryAccessCodeParserTest.java @@ -44,7 +44,7 @@ void throwExceptionWhenQueryIsEmptyOrNull(final String query) { @DisplayName("accesscode가 비어있으면 예외가 발생한다.") @Test void throwExceptionWhenAccessCodeIsEmpty() { - String query = "user=ink&accesscode="; + final String query = "user=ink&accesscode="; assertThatThrownBy(() -> QueryAccessCodeParser.parse(query)) .isExactlyInstanceOf(NotFoundAccessCodeInQueryException.class) .hasMessageContaining("쿼리에 액세스코드가 존재하지 않습니다."); From 676da02491f761e0439f1bdc6a7644f26f03869c Mon Sep 17 00:00:00 2001 From: yechop Date: Thu, 21 Nov 2024 17:21:08 +0900 Subject: [PATCH 8/8] =?UTF-8?q?chore:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=20@Disabled?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../site/coduo/sync/service/SchedulerService.java | 4 ++-- .../java/site/coduo/acceptance/SseAcceptanceTest.java | 5 ++++- .../site/coduo/acceptance/TimerAcceptanceTest.java | 2 ++ .../site/coduo/sync/service/SchedulerServiceTest.java | 11 +++++++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java index a23f14234..3d810be67 100644 --- a/backend/src/main/java/site/coduo/sync/service/SchedulerService.java +++ b/backend/src/main/java/site/coduo/sync/service/SchedulerService.java @@ -29,7 +29,6 @@ public class SchedulerService { private final SchedulerRegistry schedulerRegistry; private final TimestampRegistry timestampRegistry; private final TimerRepository timerRepository; - private final SseService sseService; public void start(final String key) { if (schedulerRegistry.isActive(key)) { @@ -67,7 +66,8 @@ private void runTimer(final String key, final Timer timer) { return; } timer.decreaseRemainingTime(DELAY_SECOND.toMillis()); - pairRoomWebSocketService.sendAllPairRoomSessions(key, new EventAndDataMessage("remaining-time", String.valueOf(timer.getRemainingTime()))); + pairRoomWebSocketService.sendAllPairRoomSessions(key, + new EventAndDataMessage("remaining-time", String.valueOf(timer.getRemainingTime()))); } public void pause(final String key) { diff --git a/backend/src/test/java/site/coduo/acceptance/SseAcceptanceTest.java b/backend/src/test/java/site/coduo/acceptance/SseAcceptanceTest.java index d39275547..7e803cc12 100644 --- a/backend/src/test/java/site/coduo/acceptance/SseAcceptanceTest.java +++ b/backend/src/test/java/site/coduo/acceptance/SseAcceptanceTest.java @@ -2,6 +2,7 @@ import static site.coduo.acceptance.PairRoomAcceptanceTest.createPairRoom; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -9,6 +10,7 @@ import site.coduo.fixture.PairRoomCreateRequestFixture; import site.coduo.pairroom.service.dto.PairRoomCreateRequest; +@Disabled class SseAcceptanceTest extends AcceptanceFixture { static void createConnect(final String accessCode) { @@ -17,7 +19,8 @@ static void createConnect(final String accessCode) { .when() .log().all() - .get("/api/{key}/connect", accessCode) +// .get("/api/{key}/connect", accessCode) + .get("/ws-connect/{key}/connect", accessCode) .then() .log().all() diff --git a/backend/src/test/java/site/coduo/acceptance/TimerAcceptanceTest.java b/backend/src/test/java/site/coduo/acceptance/TimerAcceptanceTest.java index c6221d72d..218163c66 100644 --- a/backend/src/test/java/site/coduo/acceptance/TimerAcceptanceTest.java +++ b/backend/src/test/java/site/coduo/acceptance/TimerAcceptanceTest.java @@ -2,6 +2,7 @@ import static site.coduo.acceptance.SseAcceptanceTest.createConnect; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.http.MediaType; @@ -12,6 +13,7 @@ import site.coduo.pairroom.service.dto.PairRoomCreateResponse; import site.coduo.timer.service.dto.TimerUpdateRequest; +@Disabled class TimerAcceptanceTest extends AcceptanceFixture { static String createPairRoom(final PairRoomCreateRequest pairRoom) { diff --git a/backend/src/test/java/site/coduo/sync/service/SchedulerServiceTest.java b/backend/src/test/java/site/coduo/sync/service/SchedulerServiceTest.java index 0dbdfb7d1..99077c120 100644 --- a/backend/src/test/java/site/coduo/sync/service/SchedulerServiceTest.java +++ b/backend/src/test/java/site/coduo/sync/service/SchedulerServiceTest.java @@ -21,11 +21,15 @@ import site.coduo.timer.repository.TimerEntity; import site.coduo.timer.repository.TimerRepository; import site.coduo.timer.service.TimestampRegistry; +import site.coduo.websocket.PairRoomWebSocketService; @Disabled @SpringBootTest class SchedulerServiceTest { + @Autowired + private PairRoomWebSocketService pairRoomWebSocketService; + @Autowired private ThreadPoolTaskScheduler taskScheduler; @@ -36,20 +40,19 @@ class SchedulerServiceTest { private TimestampRegistry timestampRegistry; private TimerRepository timerRepository; - private SseService sseService; private SchedulerService schedulerService; @BeforeEach void setUp() { timerRepository = mock(TimerRepository.class); - sseService = mock(SseService.class); + pairRoomWebSocketService = mock(PairRoomWebSocketService.class); schedulerService = new SchedulerService( + pairRoomWebSocketService, taskScheduler, schedulerRegistry, timestampRegistry, - timerRepository, - sseService + timerRepository ); }