Skip to content

Commit

Permalink
Merge pull request #80 from sgdevcamp2023/feat/#70_1
Browse files Browse the repository at this point in the history
Feat/#70_1 채팅서버 BaseResponse, BusinessException 적용한 리팩토링
  • Loading branch information
suakang17 authored Feb 16, 2024
2 parents 25a6fc6 + 4ab3583 commit 7d90e2e
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 120 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import chattingserver.config.kafka.Producers;
import chattingserver.dto.ChatMessageDto;
import chattingserver.dto.response.ChatMessageResponseDto;
import chattingserver.dto.response.CommonAPIMessage;
import chattingserver.dto.response.ReEnterResponseDto;
import chattingserver.service.ChatMessageService;
import chattingserver.service.RoomService;
import chattingserver.util.constant.ErrorCode;
import chattingserver.util.exception.CustomAPIException;
//import chattingserver.util.constant.ErrorCode;
import com.lalala.exception.BusinessException;
import com.lalala.exception.ErrorCode;
import com.lalala.response.BaseResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
Expand All @@ -18,11 +21,14 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.web.bind.annotation.*;

import java.util.List;


@Tag(name = "chat", description = "채팅 API")
@RequiredArgsConstructor
Expand All @@ -40,8 +46,9 @@ public class ChatController {
@Operation(summary = "웹소켓 메시지 전송")
public void sendSocketMessage(@Valid @RequestBody ChatMessageDto chatMessageDto) {
if (!roomService.isExistingRoom(chatMessageDto.getRoomId())) {
log.error("메시지 전송 에러 : 존재하지 않는 방입니다. roomId={}", chatMessageDto.getRoomId());
throw new CustomAPIException(ErrorCode.ROOM_NOT_FOUND_ERROR, "채팅방 id=" + chatMessageDto.getRoomId());
// log.error("메시지 전송 에러 : 존재하지 않는 방입니다. roomId={}", chatMessageDto.getRoomId());
// throw new CustomAPIException(ErrorCode.ROOM_NOT_FOUND_ERROR, "채팅방 id=" + chatMessageDto.getRoomId());
throw new BusinessException("존재하지 않는 채팅방입니다. 채팅방 id=" + chatMessageDto.getRoomId(), ErrorCode.UNKNOWN_ERROR);
}
ChatMessageDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto);
producers.sendMessage(savedMessage);
Expand All @@ -53,8 +60,8 @@ public void sendSocketMessage(@Valid @RequestBody ChatMessageDto chatMessageDto)
@PostMapping(value = "/message", consumes = "application/json", produces = "application/json")
public void sendMessage(@Valid @RequestBody ChatMessageDto chatMessageDto) {
if (!roomService.isExistingRoom(chatMessageDto.getRoomId())) {
log.error("메시지 전송 에러 : 존재하지 않는 방입니다. roomId={}", chatMessageDto.getRoomId());
throw new CustomAPIException(ErrorCode.ROOM_NOT_FOUND_ERROR, "채팅방 id=" + chatMessageDto.getRoomId());
throw new BusinessException("메시지 전송 에러 - 존재하지 않는 채팅방입니다. 채팅방 id=" + chatMessageDto.getRoomId(), ErrorCode.UNKNOWN_ERROR);

}
ChatMessageDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto);

Expand All @@ -67,38 +74,31 @@ public void sendMessage(@Valid @RequestBody ChatMessageDto chatMessageDto) {
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "채팅방 입장, 새 메시지 조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))})
@GetMapping("/rooms/joined/{roomId}") // TODO 웹소켓 연결 ??
public ResponseEntity<CommonAPIMessage> newMessagesAtRoom(@PathVariable String roomId, @RequestParam String readMsgId) {
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
public ResponseEntity<BaseResponse<ReEnterResponseDto>> newMessagesAtRoom(@PathVariable String roomId, @RequestParam String readMsgId) {


ReEnterResponseDto responseDto = ReEnterResponseDto.builder()
.beforeMessages(chatMessageService.getMessagesBefore(roomId, readMsgId))
.newMessages(chatMessageService.getNewMessages(roomId, readMsgId))
.build();

apiMessage.setData(responseDto);

return new ResponseEntity<>(apiMessage, HttpStatus.OK);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅방 재입장 성공, 새 메시지 조회 성공", responseDto));
}

@Operation(summary = "특정 채팅방 히스토리 조회", description = "내림차순으로 특정 채팅방의 전체 메세지를 조회합니다.")
@GetMapping("/history/{roomId}")
public ResponseEntity<CommonAPIMessage> allMessagesAtRoom(@PathVariable String roomId) {
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(chatMessageService.getAllMessagesAtRoom(roomId));
return new ResponseEntity<>(apiMessage, HttpStatus.OK);
public ResponseEntity<BaseResponse<List<ChatMessageResponseDto>>> allMessagesAtRoom(@PathVariable String roomId) {
List<ChatMessageResponseDto> allMessagesAtRoom = chatMessageService.getAllMessagesAtRoom(roomId);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅방 히스토리 조회 성공", allMessagesAtRoom));
}

@Operation(summary = "채팅 메시지 Pagination", description = "내림차순으로 해당 채팅방 메시지 Pagination, 사이즈 N = 20 고정")
@GetMapping("/history")
public ResponseEntity<CommonAPIMessage> chatMessagePagination(
public ResponseEntity<BaseResponse<Page<ChatMessageResponseDto>>> chatMessagePagination(
@RequestParam String roomId,
@Parameter(description = "첫 페이지는 0부터 시작") @RequestParam int page) {
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(chatMessageService.chatMessagePagination(roomId, page));
return new ResponseEntity<>(apiMessage, HttpStatus.OK);
Page<ChatMessageResponseDto> responseDtos = chatMessageService.chatMessagePagination(roomId, page);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅메시지 페이지네이션 성공", responseDtos));
}

@MessageMapping("/join")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import chattingserver.service.ChatMessageService;
import chattingserver.service.RoomService;
import chattingserver.service.SearchService;
import com.lalala.response.BaseResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
Expand All @@ -25,6 +26,7 @@

import java.util.HashMap;
import java.util.List;
import java.util.Optional;

@Tag(name = "room", description = "채팅방 API")
@Slf4j
Expand All @@ -41,7 +43,7 @@ public class RoomController {
@Operation(summary = "채팅방 생성 API", description = "신규 채팅방 생성", responses = {
@ApiResponse(responseCode = "201", description = "생성 성공", content = @Content(schema = @Schema(implementation = RoomResponseDto.class)))})
@PostMapping("/create")
public ResponseEntity<CommonAPIMessage> groupCreation(@Valid @RequestBody RoomCreateRequestDto roomCreateRequestDto) {
public ResponseEntity<BaseResponse<RoomResponseDto>> groupCreation(@Valid @RequestBody RoomCreateRequestDto roomCreateRequestDto) {


RoomResponseDto roomResponseDto = roomService.create(roomCreateRequestDto);
Expand All @@ -53,77 +55,63 @@ public ResponseEntity<CommonAPIMessage> groupCreation(@Valid @RequestBody RoomCr
.thumbnailImage(roomResponseDto.getThumbnailImage())
.build());

CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(roomResponseDto);

searchService.sendIndexingRequestToSearchServer(roomResponseDto);

return new ResponseEntity<>(apiMessage, HttpStatus.CREATED);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.CREATED, "채팅방 생성 성공", roomResponseDto));
}

@Operation(summary = "채팅방 영구적으로 나가기", description = "그룹 채팅방에서 유저 삭제", responses = {
@ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))})
@PostMapping("/exit/{roomId}")
public ResponseEntity<CommonAPIMessage> outOfTheRoom(@PathVariable(value = "roomId") String roomId, @RequestBody UserEntranceRequestDto userDto) {
producers.sendMessage(chatMessageService.permanentLeaving(roomId, userDto));
if (roomService.exitRoom(roomId, userDto.getUid())) {
return new ResponseEntity<>(new CommonAPIMessage(CommonAPIMessage.ResultEnum.success, new HashMap<String, String>() {{
put("roomId", roomId);
}}), HttpStatus.OK);
public ResponseEntity<BaseResponse<HashMap<String, String>>> outOfTheRoom(@PathVariable(value = "roomId") String roomId, @RequestParam Long uid) {
if (roomService.exitRoom(roomId, uid)) {

HashMap<String, String> roomId1 = new HashMap<>();
roomId1.put("roomId", roomId);

return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅방 영구 퇴장 성공", roomId1));
}
return new ResponseEntity<>(new CommonAPIMessage(CommonAPIMessage.ResultEnum.failed, new HashMap<String, String>() {{
log.error("exitRoom 채팅방 나가기 실패 roomId: {}, userId: {}", roomId, userDto.getUid());
put("roomId", roomId);
}}), HttpStatus.BAD_REQUEST);
log.error("exitRoom 채팅방 나가기 실패 roomId: {}, userId: {}", roomId, uid);
return null; // TODO common err 처리
}

@Operation(summary = "채팅방 정보 조회 API", description = "특정 채팅방 정보 조회", responses = {
@ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = RoomResponseDto.class)))})
@GetMapping("/{roomId}")
public ResponseEntity<CommonAPIMessage> chatRoomInfo(@PathVariable(value = "roomId") String roomId) {
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(roomService.getRoomInfo(roomId));
return new ResponseEntity<>(apiMessage, HttpStatus.OK);
public ResponseEntity<BaseResponse<RoomResponseDto>> chatRoomInfo(@PathVariable(value = "roomId") String roomId) {
RoomResponseDto roomInfo = roomService.getRoomInfo(roomId);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅방 정보 조회 성공", roomInfo));
}

@Operation(summary = "모든 채팅방 정보 조회 API", description = "모든 채팅방 정보 조회", responses = {
@ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = RoomResponseDto.class)))})
@GetMapping("/")
public ResponseEntity<CommonAPIMessage> getAllChatRoomInfos() {
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(roomService.getAllRoomInfos());
return new ResponseEntity<>(apiMessage, HttpStatus.OK);
public ResponseEntity<BaseResponse<List<RoomResponseDto>>> getAllChatRoomInfos() {
List<RoomResponseDto> allRoomInfos = roomService.getAllRoomInfos();
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "모든 채팅방 정보 조회 성공", allRoomInfos));
}

@Operation(summary = "참여중인 채팅방 리스트 조회", description = "특정 유저가 참여중인 채팅방 리스트 조회", responses = {
@ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))})
@GetMapping("/joined")
public ResponseEntity<CommonAPIMessage> myChatRooms(@RequestParam(required = true) Long uid){
public ResponseEntity<BaseResponse<List<JoinedRoomResponseDto>>> myChatRooms(@RequestParam(required = true) Long uid) {
List<JoinedRoomResponseDto> joinedRoomResponseDtos = roomService.findJoinedRoomsByUid(uid);
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(joinedRoomResponseDtos);
return new ResponseEntity<>(apiMessage,HttpStatus.OK);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "참여중인 채팅방 리스트 조회 성공", joinedRoomResponseDtos));
}

@Operation(summary = "참여 가능한 채팅방 리스트 조회", description = "특정 유저가 참여할 수 있는 채팅방 리스트 조회", responses = {
@ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))})
@GetMapping("/unjoined")
public ResponseEntity<CommonAPIMessage> unjoinedChatRooms(@RequestParam(required = true) Long uid) {
public ResponseEntity<BaseResponse<List<RoomResponseDto>>> unjoinedChatRooms(@RequestParam(required = true) Long uid) {
List<RoomResponseDto> unjoinedRooms = roomService.findUnjoinedRooms(uid);
CommonAPIMessage apiMessage = new CommonAPIMessage();
apiMessage.setMessage(CommonAPIMessage.ResultEnum.success);
apiMessage.setData(unjoinedRooms);
return new ResponseEntity<>(apiMessage, HttpStatus.OK);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "참여 가능한 채팅방 리스트 조회 성공", unjoinedRooms));
}

@Operation(summary = "채팅방 잠시 나가기, 마지막 읽은 메시지 id 저장", description = "잠시 나가기 (완전히 나가기 아님)")
@PutMapping("/leave")
public ResponseEntity<CommonAPIMessage> updateLastReadMsgId(@RequestBody ReadMessageUpdateRequestDto readMessageUpdateRequestDto){
return new ResponseEntity<>(roomService.updateLastReadMsgId(readMessageUpdateRequestDto), HttpStatus.OK);
public ResponseEntity<BaseResponse<CommonAPIMessage>> updateLastReadMsgId(@RequestBody ReadMessageUpdateRequestDto readMessageUpdateRequestDto) {
CommonAPIMessage commonAPIMessage = roomService.updateLastReadMsgId(readMessageUpdateRequestDto);
return ResponseEntity.ok(BaseResponse.from(HttpStatus.OK, "채팅방 잠시 나가기, 마지막 읽은 메시지 id 저장 성공", commonAPIMessage));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import chattingserver.util.constant.MessageType;
import chattingserver.util.converter.EntityToResponseDtoConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lalala.exception.BusinessException;
import com.lalala.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
Expand Down Expand Up @@ -95,9 +97,7 @@ public ChatMessageDto join(ChatMessageDto chatMessageDto) {
try {
Optional<Room> optionalRoom = roomRepository.findById(chatMessageDto.getRoomId());
if (optionalRoom.isEmpty()) {
log.info("해당하는 방이 없습니다. roomId={}", chatMessageDto.getRoomId());
// TODO null처리
return null;
throw new BusinessException("존재하지 않는 채팅방입니다. 채팅방 id=" + chatMessageDto.getRoomId(), ErrorCode.UNKNOWN_ERROR);
}

Room room = optionalRoom.get();
Expand Down Expand Up @@ -134,9 +134,7 @@ public ChatMessageDto permanentLeaving(String roomId, UserEntranceRequestDto use

Optional<Room> optionalRoom = roomRepository.findById(roomId);
if (optionalRoom.isEmpty()) {
log.info("해당하는 방이 없습니다. roomId={}", roomId);
// TODO null처리
return null;
throw new BusinessException("존재하지 않는 채팅방입니다. 채팅방 id=" + roomId, ErrorCode.UNKNOWN_ERROR);
}

Room room = optionalRoom.get();
Expand Down

This file was deleted.

This file was deleted.

0 comments on commit 7d90e2e

Please sign in to comment.