Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#91] Refactor: Problem 관련 예외처리 리팩토링 #92

Merged
merged 2 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class AuthController {


@PutMapping(value = "/signup", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@Operation(summary = "회원가입 [jwt O]", description = "isImageChange==1 : 사진으로 변경 / isImageChange==0 : 기본 사진으로 변경")
@Operation(summary = "회원가입 [jwt O]", description = "isImageChange==0 : 기본 사진으로 변경 / isImageChange==1 : 사진으로 변경")
public ResponseEntity<ResponseData<SignupResponseDto>> signup(
@RequestPart(value="imageFile", required = false) MultipartFile imageFile,
@RequestPart(value="signupRequestDto") SignupRequestDto signupRequestDto) throws IOException { // 여기서 Role을 USER로 교체해주지 않으면 다른 로그인 필수 API를 사용하지 못함.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import com.sajang.devracebackend.dto.room.RoomEnterRequestDto;
import com.sajang.devracebackend.dto.room.RoomWaitRequestDto;
import com.sajang.devracebackend.dto.room.RoomWaitResponseDto;
import com.sajang.devracebackend.dto.userroom.CheckIsPassDto;
import com.sajang.devracebackend.dto.userroom.UserPassRequestDto;
import com.sajang.devracebackend.dto.userroom.RoomCheckAccessResponseDto;
import com.sajang.devracebackend.dto.room.RoomCheckStateResponseDto;
import com.sajang.devracebackend.dto.userroom.SolvingPageResponseDto;
Expand Down Expand Up @@ -61,33 +61,34 @@ public ResponseEntity<ResponseData<SolvingPageResponseDto>> loadSolvingPage(@Pat

@GetMapping("/rooms/{roomId}/access-check")
@Operation(summary = "문제풀이 페이지 접근허용 검사 [jwt O]", description = "isLeave == 0 or 1 or null")
public ResponseEntity<ResponseData<RoomCheckAccessResponseDto>> checkAccess(@PathVariable(value = "roomId") Long roomId) { // value=""를 작성해주어야만, Swagger에서 api테스트할때 이름값이 뜸.
public ResponseEntity<ResponseData<RoomCheckAccessResponseDto>> checkAccess(@PathVariable(value = "roomId") Long roomId) {
RoomCheckAccessResponseDto roomCheckAccessResponseDto = userRoomService.checkAccess(roomId);
return ResponseData.toResponseEntity(ResponseCode.READ_USERROOM, roomCheckAccessResponseDto);
}

@GetMapping("/rooms/{roomId}/state-check")
@Operation(summary = "방 상태 검사 [jwt O]")
public ResponseEntity<ResponseData<RoomCheckStateResponseDto>> checkState(@PathVariable(value = "roomId") Long roomId) { // value=""를 작성해주어야만, Swagger에서 api테스트할때 이름값이 뜸.
public ResponseEntity<ResponseData<RoomCheckStateResponseDto>> checkState(@PathVariable(value = "roomId") Long roomId) {
RoomCheckStateResponseDto roomCheckStateResponseDto = roomService.checkState(roomId);
return ResponseData.toResponseEntity(ResponseCode.READ_USERROOM, roomCheckStateResponseDto);
}

@PutMapping("/room/{roomId}")
@Operation(summary = "문제풀이 실패 및 성공 [jwt O]", description = "isRetry==0 : 첫풀이 경우 / isRetry==1 : 재풀이 경우")
public ResponseEntity<ResponseData> passSolvingProblem(
@PathVariable(value = "roomId") Long roomId,
@RequestBody UserPassRequestDto userPassRequestDto) {
userRoomService.passSolvingProblem(roomId, userPassRequestDto);
return ResponseData.toResponseEntity(ResponseCode.UPDATE_USERROOM);
}

@MessageMapping("wait.enter") // 웹소켓 메시지 처리 (백엔드로 '/pub/wait.enter'를 호출시 이 브로커에서 처리)
public void userWaitRoom(@Payload RoomWaitRequestDto roomWaitRequestDto) {
// '/exchange/wait.exchange/waitingroom.{roomId}' 구독되어있는 프론트엔드에게 메세지 전달.
RoomWaitResponseDto roomWaitResponseDto = roomService.userWaitRoom(roomWaitRequestDto);
rabbitTemplate.convertAndSend(RabbitConfig.WAIT_EXCHANGE_NAME, "waitingroom." + roomWaitResponseDto.getRoomId(), roomWaitResponseDto);
}

@PutMapping("/room/{roomId}")
public ResponseEntity<ResponseData> success(
@RequestBody CheckIsPassDto checkIsPassDto,
@PathVariable(name ="roomId") Long roomId){
userRoomService.checkIsPass(checkIsPassDto,roomId);
return ResponseData.toResponseEntity(ResponseCode.UPDATE_USERROOM);
}


// ========== STOMP Test 임시 용도 ========== //
// @RabbitListener(queues = RabbitConfig.WAIT_QUEUE_NAME) // 프로듀서(백엔드)->컨슈머(프론트엔드) 과정에서 큐에 도착할 때, 메소드 자동 호출됨.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.sajang.devracebackend.dto.userroom;


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -10,7 +9,9 @@
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CheckIsPassDto {
public class UserPassRequestDto {

private Integer isRetry; // 문제 재풀이 여부

private String code;
private Integer isPass;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.sajang.devracebackend.domain.Room;
import com.sajang.devracebackend.domain.User;
import com.sajang.devracebackend.dto.room.RoomEnterRequestDto;
import com.sajang.devracebackend.dto.userroom.CheckIsPassDto;
import com.sajang.devracebackend.dto.userroom.UserPassRequestDto;
import com.sajang.devracebackend.dto.userroom.RoomCheckAccessResponseDto;
import com.sajang.devracebackend.dto.userroom.SolvingPageResponseDto;

Expand All @@ -12,5 +12,5 @@ public interface UserRoomService {
void usersEnterRoom(Long roomId, RoomEnterRequestDto roomEnterRequestDto);
SolvingPageResponseDto loadSolvingPage(Long roomId);
RoomCheckAccessResponseDto checkAccess(Long roomId);
void checkIsPass(CheckIsPassDto checkIsPassDto, Long roomId);
void passSolvingProblem(Long roomId, UserPassRequestDto userPassRequestDto);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import com.sajang.devracebackend.domain.Problem;
import com.sajang.devracebackend.repository.ProblemRepository;
import com.sajang.devracebackend.response.exception.exception404.NoSuchProblemException;
import com.sajang.devracebackend.service.ProblemService;
import lombok.RequiredArgsConstructor;
import org.json.simple.JSONObject;
import org.jsoup.nodes.Element;
import org.springframework.stereotype.Service;
import org.jsoup.Jsoup;
Expand All @@ -28,7 +28,12 @@ public class ProblemServiceImpl implements ProblemService {
@Override
public Problem crawlAndSaveProblem(Integer problemNumber) throws IOException { // Service 클래스 내에서만 호출되며 방 생성에 이용될 것이기에 Dto가 아닌, Entity를 반환받음.
String url = "https://www.acmicpc.net/problem/" + problemNumber;
Document doc = Jsoup.connect(url).get();
Document doc = null;
try {
doc = Jsoup.connect(url).get();
} catch (Exception e) {
throw new NoSuchProblemException("problemNumber = " + problemNumber);
}

Elements contents = doc.select("#problem-body"); // #problem-body에 접근
Elements contentHead = doc.select(".page-header h1"); // 문제 title 추출을 위한 page-header에 접근
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.sajang.devracebackend.domain.enums.RoomState;
import com.sajang.devracebackend.domain.mapping.UserRoom;
import com.sajang.devracebackend.dto.room.RoomEnterRequestDto;
import com.sajang.devracebackend.dto.userroom.CheckIsPassDto;
import com.sajang.devracebackend.dto.userroom.UserPassRequestDto;
import com.sajang.devracebackend.dto.userroom.RoomCheckAccessResponseDto;
import com.sajang.devracebackend.dto.userroom.SolvingPageResponseDto;
import com.sajang.devracebackend.repository.ChatRepository;
Expand Down Expand Up @@ -123,27 +123,28 @@ public RoomCheckAccessResponseDto checkAccess(Long roomId) {

@Transactional
@Override
public void checkIsPass(CheckIsPassDto checkIsPassDto, Long roomId) {
User user = userService.findLoginUser(); // 현재 유저 데이터 가져오기
Room room = roomService.findRoom(roomId); // 현재 입장된 방 데이터 가져오기
UserRoom userRoom = userRoomRepository.findByUserAndRoom(user,room).orElseThrow( // api를 호출한 유저와 유저의 room 요소 가져오기
() -> new NoSuchUserRoomException(String.format("userId = %d & roomId = %d", user.getId(), room.getId()))
);

userRoom.updateCode(checkIsPassDto.getCode());
userRoom.updateIsPass(checkIsPassDto.getIsPass());
userRoom.updateIsLeave(1);
public void passSolvingProblem(Long roomId, UserPassRequestDto userPassRequestDto) {
User user = userService.findLoginUser();
Room room = roomService.findRoom(roomId);
UserRoom userRoom = userRoomRepository.findByUserAndRoom(user, room).orElseThrow(
()->new NoSuchUserRoomException(String.format("userId = %d & roomId = %d", user.getId(), room.getId())));

userRoom.updateCode(userPassRequestDto.getCode());
userRoom.updateIsLeave(1);
userRoom.updateLeaveTime(LocalDateTime.now());

if(checkIsPassDto.getIsPass() == 1){
room.updateRanking(userRoom.getUser().getNickname()); // 성공시에만 닉네임 랭킹 등록.
if(userPassRequestDto.getIsRetry() == 0 || (userPassRequestDto.getIsRetry() == 1 && userPassRequestDto.getIsPass() == 1)) {
// 재풀이인 경우, 성공인 경우에만 성공여부를 업데이트함. (재풀이의 퇴장인 경우에는 성공여부를 업데이트 하지않음)
userRoom.updateIsPass(userPassRequestDto.getIsPass());
}

boolean isUsersLeave = userRoomRepository.findAllByRoom(room).stream()
.allMatch(users -> users.getIsLeave() == 1); //모든 유저의 isLeave를 찾아 1인지 확인
if(isUsersLeave) {
room.updateRoomState(RoomState.FINISH);
}
}
// 밑의 랭킹 업데이트 파트는 STOMP 실시간 처리를 위하여, 주석처리 해두었음.
// if(userPassRequestDto.getIsPass() == 1) {
// room.updateRanking(user.getNickname()); // 성공시에만 닉네임 랭킹 등록.
// }

boolean isLeaveAllUsers = userRoomRepository.findAllByRoom(room).stream()
.allMatch(users -> users.getIsLeave() == 1); // 모든 유저의 isLeave 값이 1인지 확인
if(isLeaveAllUsers == true) room.updateRoomState(RoomState.FINISH);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ public List<String> convertToEntityAttribute(String dbData) { // DB의 String
if (dbData == null || dbData.equals("__null__")) {
return new ArrayList<>();
}
return new ArrayList<>(Arrays.asList(dbData.split(SPLIT_CHAR))); // else 경우
return new ArrayList<>(Arrays.asList(dbData.split(SPLIT_CHAR))); // else 경우
}
}
Loading