diff --git a/src/backend/chatting-server/build.gradle b/src/backend/chatting-server/build.gradle index a4a40fe4..e219d389 100644 --- a/src/backend/chatting-server/build.gradle +++ b/src/backend/chatting-server/build.gradle @@ -37,6 +37,8 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' + implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.1.0' + annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor' // Eureka @@ -56,6 +58,16 @@ dependencies { implementation 'net.logstash.logback:logstash-logback-encoder:6.3' } +ext { + set('springCloudVersion', "2023.0.0") +} + +dependencyManagement { + imports { + mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" + } +} + tasks.named('test') { useJUnitPlatform() } diff --git a/src/backend/chatting-server/docker-compose.yml b/src/backend/chatting-server/docker-compose.yml index 0098f03a..32422150 100644 --- a/src/backend/chatting-server/docker-compose.yml +++ b/src/backend/chatting-server/docker-compose.yml @@ -42,6 +42,8 @@ services: volumes: - chatting-mongodbdata:/data/db:cached - ./init-mongo.js:/docker-entrypoint-initdb.d/mongo-init.js:ro + networks: + - lalala-network chatting-mongo-express: image: mongo-express:1.0.2 diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/AsyncConfig.java b/src/backend/chatting-server/src/main/java/chattingserver/config/AsyncConfig.java new file mode 100644 index 00000000..af102a78 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/AsyncConfig.java @@ -0,0 +1,29 @@ +package chattingserver.config; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.Executor; + +@Slf4j +@EnableAsync +@Configuration +public class AsyncConfig { + + @Bean(name = "search") + public Executor pushAsyncExecutor() { + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + int processors = Runtime.getRuntime().availableProcessors(); + log.info("processors count {}", processors); + executor.setThreadNamePrefix("SearchAsync- "); + executor.setCorePoolSize(processors); + executor.setMaxPoolSize(processors * 2); + executor.setQueueCapacity(50); + executor.setKeepAliveSeconds(60); + executor.initialize(); + return executor; + } +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/OpenFeignConfig.java b/src/backend/chatting-server/src/main/java/chattingserver/config/OpenFeignConfig.java new file mode 100644 index 00000000..893bcbab --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/OpenFeignConfig.java @@ -0,0 +1,10 @@ +package chattingserver.config; + +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableFeignClients(basePackages = {"chattingserver.controller"}) +public class OpenFeignConfig { + +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/WebConfig.java b/src/backend/chatting-server/src/main/java/chattingserver/config/WebConfig.java index e27b07e8..56a68bfa 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/config/WebConfig.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/WebConfig.java @@ -1,17 +1,23 @@ package chattingserver.config; +import org.apache.catalina.filters.CorsFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +@Configuration public class WebConfig implements WebMvcConfigurer { + @Override public void addCorsMappings(CorsRegistry registry) { - registry - .addMapping("/**") - .allowedOrigins("*") + registry.addMapping("/**") + .allowedOriginPatterns("http://localhost:3000") .allowedMethods("*") - .allowedHeaders("*") - .allowCredentials(false) - .maxAge(60000); + .allowedHeaders("*"); } + } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Consumers.java b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Consumers.java index 0b53fb4a..1626c19a 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Consumers.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Consumers.java @@ -1,5 +1,7 @@ package chattingserver.config.kafka; +import chattingserver.dto.ChatMessageDto; +import chattingserver.dto.request.IndexingRequestMessageDto; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -24,14 +26,10 @@ public void listenChat(ChatMessageDto chatMessageDto) { template.convertAndSend("/chat/topic/room/" + chatMessageDto.getRoomId(), chatMessageDto); } - @KafkaListener( - groupId = "${spring.kafka.consumer.room-consumer.group-id}", - topics = "${spring.kafka.topic.room-name}", - containerFactory = "kafkaListenerContainerFactory") - public void listenGroupCreation(RoomMessageDto roomMessageDto) { - RoomResponseDto roomResponseDto = roomMessageDto.getRoomResponseDto(); - for (Long userId : roomMessageDto.getReceivers()) { - template.convertAndSend("/chat/topic/new-room/" + userId, roomResponseDto); - } + // TODO search indexing test용 추후 삭제 예정 + @KafkaListener(groupId = "${spring.kafka.consumer.room-consumer.group-id}", topics = "${kafka.topic.room-name}", containerFactory = "kafkaListenerContainerFactory") + public void listenRoomCreation(IndexingRequestMessageDto indexingRequestMessageDto) { + + template.convertAndSend("/chat/topic/search/room/index", indexingRequestMessageDto); } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/KafkaProducerConfig.java b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/KafkaProducerConfig.java index fb1c0658..d39b4748 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/KafkaProducerConfig.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/KafkaProducerConfig.java @@ -1,8 +1,9 @@ package chattingserver.config.kafka; -import java.util.HashMap; -import java.util.Map; - +import chattingserver.dto.ChatMessageDto; +import chattingserver.dto.request.IndexingRequestMessageDto; +import org.apache.kafka.clients.producer.ProducerConfig; +import org.apache.kafka.common.serialization.StringSerializer; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,7 +37,7 @@ public class KafkaProducerConfig { private String chatValueSerializer; @Bean - public ProducerFactory producerFactory() { + public ProducerFactory chatProducerFactory() { return new DefaultKafkaProducerFactory<>(chatProducerConfigurations()); } @@ -51,11 +52,11 @@ public Map chatProducerConfigurations() { @Bean public KafkaTemplate chatKafkaTemplate() { - return new KafkaTemplate<>(producerFactory()); + return new KafkaTemplate<>(chatProducerFactory()); } @Bean - public ProducerFactory roomProducerFactory() { + public ProducerFactory roomProducerFactory() { return new DefaultKafkaProducerFactory<>(roomProducerConfigurations()); } @@ -69,7 +70,7 @@ public Map roomProducerConfigurations() { } @Bean - public KafkaTemplate roomKafkaTemplate() { + public KafkaTemplate roomKafkaTemplate() { return new KafkaTemplate<>(roomProducerFactory()); } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Producers.java b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Producers.java index 1fa69090..3aaa7eec 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Producers.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/kafka/Producers.java @@ -1,21 +1,10 @@ package chattingserver.config.kafka; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.stream.Collectors; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.kafka.core.KafkaTemplate; -import org.springframework.kafka.support.SendResult; -import org.springframework.stereotype.Component; - -import chattingserver.domain.room.User; import chattingserver.dto.ChatMessageDto; import chattingserver.dto.RoomMessageDto; +import chattingserver.dto.request.IndexingRequestMessageDto; import chattingserver.dto.response.RoomResponseDto; +import chattingserver.dto.response.UserListResponseDto; import chattingserver.service.ChatMessageService; import chattingserver.service.RoomService; import chattingserver.util.constant.MessageType; @@ -32,58 +21,46 @@ public class Producers { @Value("${spring.kafka.topic.room-name}") private String topicRoomName; - private final KafkaTemplate roomKafkaTemplate; + private final KafkaTemplate roomKafkaTemplate; private final ChatMessageService chatMessageService; private final RoomService roomService; public void sendMessage(ChatMessageDto chatMessageDto) { - if (chatMessageDto.getMessageType() == MessageType.ENTRANCE) { + if (chatMessageDto.getMessageType() == MessageType.CREATION) { RoomResponseDto roomResponseDto = roomService.getRoomInfo(chatMessageDto.getRoomId()); - List receivers = - roomResponseDto.getUsers().stream().map(User::getUid).collect(Collectors.toList()); + List receivers = roomResponseDto.getUsers().stream().map(UserListResponseDto::getUid).collect(Collectors.toList()); receivers.remove(chatMessageDto.getSenderId()); - sendRoomMessage( - RoomMessageDto.builder().receivers(receivers).roomResponseDto(roomResponseDto).build()); + sendRoomMessage(IndexingRequestMessageDto.builder() + .roomId(roomResponseDto.getId()) + .roomName(roomResponseDto.getRoomName()) + .playlistId(roomResponseDto.getPlaylist().getId()) + .thumbnailImage(roomResponseDto.getThumbnailImage()) + .build()); } else { - CompletableFuture> completableFuture = - chatKafkaTemplate.send(topicChatName, chatMessageDto); - completableFuture.whenComplete( - (result, ex) -> { - if (ex == null) { - log.info( - "채팅방 id: {}, 발신자 id: {}, 메시지: {}", - chatMessageDto.getRoomId(), - chatMessageDto.getSenderId(), - chatMessageDto.getContent()); - } else { - log.error("메시지 전송 불가=[" + chatMessageDto.getContent() + "] 원인 : " + ex.getMessage()); - chatMessageService.deleteChat(chatMessageDto.getId()); - log.info("삭제된 메시지={}", chatMessageDto.getId()); - } - }); + + CompletableFuture> completableFuture = chatKafkaTemplate.send(topicChatName, chatMessageDto); + completableFuture.whenComplete((result, ex) -> { + if (ex == null) { + log.info("채팅방 id: {}, 발신자 id: {}, 메시지: {}", chatMessageDto.getRoomId(), chatMessageDto.getSenderId(), chatMessageDto.getContent()); + } else { + log.error("메시지 전송 불가=[" + chatMessageDto.getContent() + "] 원인 : " + ex.getMessage()); + chatMessageService.deleteChat(chatMessageDto.getId()); + log.info("삭제된 메시지={}", chatMessageDto.getId()); + } + }); } } - public void sendRoomMessage(RoomMessageDto roomMessageDto) { - CompletableFuture> completableFuture = - roomKafkaTemplate.send(topicRoomName, roomMessageDto); - completableFuture.whenComplete( - (result, ex) -> { - if (ex == null) { - log.info( - "메시지 전송 성공=[" - + roomMessageDto.getRoomResponseDto().getId() - + "] with offset=[" - + result.getRecordMetadata().offset() - + "]"); - } else { - log.info( - "메시지 전송 불가=[" - + roomMessageDto.getRoomResponseDto().getId() - + "] 원인 : " - + ex.getMessage()); - } - }); + public void sendRoomMessage(IndexingRequestMessageDto roomMessageDto) { + CompletableFuture> completableFuture = roomKafkaTemplate.send(topicRoomName, roomMessageDto); + completableFuture.whenComplete((result, ex) -> { + if (ex == null) { + log.info("메시지 전송 성공=[" + roomMessageDto.getRoomId() + "] with offset=[" + result.getRecordMetadata().offset() + "]"); + log.info("roomMessageDto={}", roomMessageDto.toString()); + } else { + log.info("메시지 전송 불가=[" + roomMessageDto.getRoomId() + "] 원인 : " + ex.getMessage()); + } + }); } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/config/util/SwaggerConfig.java b/src/backend/chatting-server/src/main/java/chattingserver/config/util/SwaggerConfig.java index 16c9ac67..0cccbde3 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/config/util/SwaggerConfig.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/config/util/SwaggerConfig.java @@ -17,7 +17,7 @@ public class SwaggerConfig { @Bean public GroupedOpenApi chatOpenApi() { - String[] paths = {"/api/**", "/chat/**"}; + String[] paths = {"/v1/**", "/**/chat"}; return GroupedOpenApi.builder().group("CHATTING-SERVER API V1").pathsToMatch(paths).build(); } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/controller/ChatController.java b/src/backend/chatting-server/src/main/java/chattingserver/controller/ChatController.java index 37ee34a8..d7f91f6f 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/controller/ChatController.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/controller/ChatController.java @@ -10,8 +10,8 @@ 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; @@ -25,10 +25,11 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; + @Tag(name = "chat", description = "채팅 API") @RequiredArgsConstructor @RestController -@RequestMapping("/chat") +@RequestMapping("v1/api/chat") @Slf4j public class ChatController { @@ -36,7 +37,7 @@ public class ChatController { private final ChatMessageService chatMessageService; private final RoomService roomService; - @MessageMapping("/chat/pub") + @MessageMapping("/send") @Operation(summary = "웹소켓 메시지 전송") public void sendSocketMessage(@Valid @RequestBody ChatMessageDto chatMessageDto) { if (!roomService.isExistingRoom(chatMessageDto.getRoomId())) { @@ -44,50 +45,47 @@ public void sendSocketMessage(@Valid @RequestBody ChatMessageDto chatMessageDto) throw new CustomAPIException( ErrorCode.ROOM_NOT_FOUND_ERROR, "채팅방 id=" + chatMessageDto.getRoomId()); } - - ChatMessageResponseDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto); - producers.sendMessage(chatMessageDto); + ChatMessageDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto); + producers.sendMessage(savedMessage); log.info("메시지 전송 완료 - message={}", chatMessageDto); } @Operation(summary = "메시지 전송") - @PostMapping( - value = "/api/v1/message", - consumes = "application/json", - produces = "application/json") + @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()); } - ChatMessageResponseDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto); + ChatMessageDto savedMessage = chatMessageService.saveChatMessage(chatMessageDto); - producers.sendMessage(chatMessageDto); + producers.sendMessage(savedMessage); log.info("메시지 전송 완료 - message={}", chatMessageDto); } - @Operation(summary = "채팅방 새 메시지 조회") - @ApiResponses( - value = { - @ApiResponse( - responseCode = "200", - description = "채팅방 새 메시지 조회 성공", - content = @Content(schema = @Schema(implementation = CommonAPIMessage.class))) - }) - @GetMapping("/api/v1/new-message/{roomId}/{readMsgId}") - public ResponseEntity newMessagesAtRoom( - @PathVariable String roomId, @PathVariable String readMsgId) { + @Operation(summary = "참여중인 채팅방 재입장, 새 메시지 조회") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "채팅방 입장, 새 메시지 조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))}) + @GetMapping("/rooms/joined/{roomId}") // TODO 웹소켓 연결 ?? + public ResponseEntity newMessagesAtRoom(@PathVariable String roomId, @RequestParam String readMsgId) { CommonAPIMessage apiMessage = new CommonAPIMessage(); apiMessage.setMessage(CommonAPIMessage.ResultEnum.success); - apiMessage.setData(chatMessageService.getNewMessages(roomId, 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); } @Operation(summary = "특정 채팅방 히스토리 조회", description = "내림차순으로 특정 채팅방의 전체 메세지를 조회합니다.") - @GetMapping("/api/v1/history/{roomId}") + @GetMapping("/history/{roomId}") public ResponseEntity allMessagesAtRoom(@PathVariable String roomId) { CommonAPIMessage apiMessage = new CommonAPIMessage(); apiMessage.setMessage(CommonAPIMessage.ResultEnum.success); @@ -95,9 +93,7 @@ public ResponseEntity allMessagesAtRoom(@PathVariable String r return new ResponseEntity<>(apiMessage, HttpStatus.OK); } - @Operation( - summary = "채팅 메시지 Pagination", - description = "내림차순으로 해당 채팅방 메시지 Pagination, 사이즈 N = 12 고정") + @Operation(summary = "채팅 메시지 Pagination", description = "내림차순으로 해당 채팅방 메시지 Pagination, 사이즈 N = 20 고정") @GetMapping("/history") public ResponseEntity chatMessagePagination( @RequestParam String roomId, @@ -108,15 +104,10 @@ public ResponseEntity chatMessagePagination( return new ResponseEntity<>(apiMessage, HttpStatus.OK); } - @MessageMapping("/api/v1/join") + @MessageMapping("/join") public void join(ChatMessageDto message) { producers.sendMessage(chatMessageService.join(message)); } - @MessageMapping("/api/v1/leave") - public void leave(ChatMessageDto message) { - - producers.sendMessage(chatMessageService.leave(message)); - } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/controller/RoomController.java b/src/backend/chatting-server/src/main/java/chattingserver/controller/RoomController.java index 4276221a..d56e1b94 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/controller/RoomController.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/controller/RoomController.java @@ -12,28 +12,41 @@ import org.springframework.web.bind.annotation.*; import chattingserver.config.kafka.Producers; -import chattingserver.domain.room.User; -import chattingserver.dto.RoomMessageDto; +import chattingserver.dto.request.IndexingRequestMessageDto; +import chattingserver.dto.request.ReadMessageUpdateRequestDto; import chattingserver.dto.request.RoomCreateRequestDto; +import chattingserver.dto.request.UserEntranceRequestDto; import chattingserver.dto.response.CommonAPIMessage; import chattingserver.dto.response.JoinedRoomResponseDto; import chattingserver.dto.response.RoomResponseDto; +import chattingserver.service.ChatMessageService; import chattingserver.service.RoomService; +import chattingserver.service.SearchService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.HashMap; +import java.util.List; @Tag(name = "room", description = "채팅방 API") @Slf4j @RestController -@RequestMapping("/api/v1/rooms") +@RequestMapping("/v1/api/rooms") @RequiredArgsConstructor public class RoomController { private final RoomService roomService; + private final ChatMessageService chatMessageService; + private final SearchService searchService; private final Producers producers; @Operation( @@ -46,56 +59,40 @@ public class RoomController { content = @Content(schema = @Schema(implementation = RoomResponseDto.class))) }) @PostMapping("/create") - public ResponseEntity groupCreation( - @Valid @RequestBody RoomCreateRequestDto roomCreateRequestDto) { + public ResponseEntity groupCreation(@Valid @RequestBody RoomCreateRequestDto roomCreateRequestDto) { + - // 채팅방 C RoomResponseDto roomResponseDto = roomService.create(roomCreateRequestDto); - // publish - producers.sendRoomMessage( - RoomMessageDto.builder() - .receivers( - roomResponseDto.getUsers().stream().map(User::getUid).collect(Collectors.toList())) - .roomResponseDto(roomResponseDto) - .build()); + producers.sendRoomMessage(IndexingRequestMessageDto.builder() + .roomId(roomResponseDto.getId()) + .roomName(roomResponseDto.getRoomName()) + .playlistId(roomResponseDto.getPlaylist().getId()) + .thumbnailImage(roomResponseDto.getThumbnailImage()) + .build()); + CommonAPIMessage apiMessage = new CommonAPIMessage(); + apiMessage.setMessage(CommonAPIMessage.ResultEnum.success); + apiMessage.setData(roomResponseDto); - return new ResponseEntity<>(roomResponseDto, HttpStatus.CREATED); + searchService.sendIndexingRequestToSearchServer(roomResponseDto); + + return new ResponseEntity<>(apiMessage, HttpStatus.CREATED); } - @Operation( - summary = "채팅방 나가기", - description = "그룹 채팅방에서 유저 삭제", - responses = { - @ApiResponse( - responseCode = "200", - description = "삭제 성공", - content = @Content(schema = @Schema(implementation = CommonAPIMessage.class))) - }) - @DeleteMapping("/exit/{roomId}") - public ResponseEntity outOfTheRoom( - @PathVariable(value = "roomId") String roomId, @RequestParam Long uid) { - if (roomService.exitRoom(roomId, uid)) { - return new ResponseEntity<>( - new CommonAPIMessage( - CommonAPIMessage.ResultEnum.success, - new HashMap() { - { - put("roomId", roomId); - } - }), - HttpStatus.OK); + @Operation(summary = "채팅방 영구적으로 나가기", description = "그룹 채팅방에서 유저 삭제", responses = { + @ApiResponse(responseCode = "200", description = "삭제 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))}) + @PostMapping("/exit/{roomId}") + public ResponseEntity 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() {{ + put("roomId", roomId); + }}), HttpStatus.OK); } - return new ResponseEntity<>( - new CommonAPIMessage( - CommonAPIMessage.ResultEnum.failed, - new HashMap() { - { - log.error("exitRoom 채팅방 나가기 실패 roomId: {}, userId: {}", roomId, uid); - put("roomId", roomId); - } - }), - HttpStatus.BAD_REQUEST); + return new ResponseEntity<>(new CommonAPIMessage(CommonAPIMessage.ResultEnum.failed, new HashMap() {{ + log.error("exitRoom 채팅방 나가기 실패 roomId: {}, userId: {}", roomId, userDto.getUid()); + put("roomId", roomId); + }}), HttpStatus.BAD_REQUEST); } @Operation( @@ -108,20 +105,26 @@ public ResponseEntity outOfTheRoom( content = @Content(schema = @Schema(implementation = RoomResponseDto.class))) }) @GetMapping("/{roomId}") - public ResponseEntity chatRoomInfo( - @PathVariable(value = "roomId") String roomId) { - return new ResponseEntity<>(roomService.getRoomInfo(roomId), HttpStatus.OK); + public ResponseEntity 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); } - @Operation( - summary = "채팅방 리스트 조회", - description = "특정 유저가 참여중인 채팅방 리스트 조회", - responses = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = @Content(schema = @Schema(implementation = CommonAPIMessage.class))) - }) + @Operation(summary = "모든 채팅방 정보 조회 API", description = "모든 채팅방 정보 조회", responses = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = RoomResponseDto.class)))}) + @GetMapping("/") + public ResponseEntity getAllChatRoomInfos() { + CommonAPIMessage apiMessage = new CommonAPIMessage(); + apiMessage.setMessage(CommonAPIMessage.ResultEnum.success); + apiMessage.setData(roomService.getAllRoomInfos()); + return new ResponseEntity<>(apiMessage, HttpStatus.OK); + } + + @Operation(summary = "참여중인 채팅방 리스트 조회", description = "특정 유저가 참여중인 채팅방 리스트 조회", responses = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))}) + @GetMapping("/joined") public ResponseEntity myChatRooms(@RequestParam(required = true) Long uid) { List joinedRoomResponseDtos = roomService.findJoinedRoomsByUid(uid); @@ -131,15 +134,9 @@ public ResponseEntity myChatRooms(@RequestParam(required = tru return new ResponseEntity<>(apiMessage, HttpStatus.OK); } - @Operation( - summary = "채팅방 리스트 조회", - description = "특정 유저가 참여할 수 있는 채팅방 리스트 조회", - responses = { - @ApiResponse( - responseCode = "200", - description = "조회 성공", - content = @Content(schema = @Schema(implementation = CommonAPIMessage.class))) - }) + @Operation(summary = "참여 가능한 채팅방 리스트 조회", description = "특정 유저가 참여할 수 있는 채팅방 리스트 조회", responses = { + @ApiResponse(responseCode = "200", description = "조회 성공", content = @Content(schema = @Schema(implementation = CommonAPIMessage.class)))}) + @GetMapping("/unjoined") public ResponseEntity unjoinedChatRooms( @RequestParam(required = true) Long uid) { @@ -149,4 +146,11 @@ public ResponseEntity unjoinedChatRooms( apiMessage.setData(unjoinedRooms); return new ResponseEntity<>(apiMessage, HttpStatus.OK); } + + @Operation(summary = "채팅방 잠시 나가기, 마지막 읽은 메시지 id 저장", description = "잠시 나가기 (완전히 나가기 아님)") + @PutMapping("/leave") + public ResponseEntity updateLastReadMsgId(@RequestBody ReadMessageUpdateRequestDto readMessageUpdateRequestDto){ + return new ResponseEntity<>(roomService.updateLastReadMsgId(readMessageUpdateRequestDto), HttpStatus.OK); + } + } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/controller/SearchProxy.java b/src/backend/chatting-server/src/main/java/chattingserver/controller/SearchProxy.java new file mode 100644 index 00000000..3849c2a9 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/controller/SearchProxy.java @@ -0,0 +1,12 @@ +package chattingserver.controller; + +import chattingserver.dto.request.IndexingRequestMessageDto; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +@FeignClient(name = "search-service", url = "localhost:20000") +public interface SearchProxy { + @PostMapping("/search/index/send") + void sendIndexingRequest(@RequestBody IndexingRequestMessageDto dto); +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/ChatMessage.java b/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/ChatMessage.java index 29bdeb0f..52fc3d80 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/ChatMessage.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/ChatMessage.java @@ -21,6 +21,8 @@ public class ChatMessage { private MessageType messageType; private String roomId; private Long senderId; + private String nickName; + private String senderProfileImage; private String content; private LocalDateTime createdAt; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/LastMessage.java b/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/LastMessage.java new file mode 100644 index 00000000..9e80d5c2 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/domain/chat/LastMessage.java @@ -0,0 +1,20 @@ +package chattingserver.domain.chat; + +import lombok.*; + +import java.time.LocalDateTime; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class LastMessage { + private String messageId; + private Long senderId; + private String nickName; + private String senderProfileImage; + private String content; + private LocalDateTime createdAt; +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Playlist.java b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Playlist.java index 58402f08..5ac06693 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Playlist.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Playlist.java @@ -12,5 +12,22 @@ public class Playlist { private String id; private String name; + + private Long playlistOwnerId; + private String playlistOwnerNickName; + private String playlistOwnerProfileImage; + private List musics; + + public Music getFirstMusic() { + return musics.get(0); // 무조건 있음 신뢰 + } + + public User getPlaylistOwner() { + return User.builder() + .uid(playlistOwnerId) + .nickName(playlistOwnerNickName) + .profileImage(playlistOwnerProfileImage) + .build(); + } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Room.java b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Room.java index b5e8bb10..0714ea08 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Room.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/Room.java @@ -19,10 +19,12 @@ public class Room { @Id private String id; private String roomName; private Playlist playlist; + private String thumbnailImage; private List users; private LocalDateTime createdAt; + private User playlistOwner; public void setMembers(List users) { this.users = users; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/User.java b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/User.java index 8052029f..b3d524f2 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/domain/room/User.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/domain/room/User.java @@ -13,6 +13,7 @@ public class User { private Long uid; private String nickName; + private String profileImage; private String lastReadMessageId; private LocalDateTime enteredAt; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/ChatMessageDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/ChatMessageDto.java index b43a1427..11d5b5e7 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/ChatMessageDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/ChatMessageDto.java @@ -16,9 +16,17 @@ public class ChatMessageDto { private String id; - @NotBlank private MessageType messageType; - @NotBlank private String roomId; - @NotBlank private Long senderId; - @NotBlank private String content; + @NotBlank + private MessageType messageType; + @NotBlank + private String roomId; + @NotBlank + private Long senderId; + @NotBlank + private String nickName; + + private String senderProfileImage; + @NotBlank + private String content; private LocalDateTime createdAt; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/IndexingRequestMessageDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/IndexingRequestMessageDto.java new file mode 100644 index 00000000..5b386da8 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/IndexingRequestMessageDto.java @@ -0,0 +1,16 @@ +package chattingserver.dto.request; + +import lombok.*; + + +@ToString +@AllArgsConstructor +@NoArgsConstructor +@Getter +@Builder +public class IndexingRequestMessageDto { + private String roomId; + private String roomName; + private String playlistId; + private String thumbnailImage; +} \ No newline at end of file diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/ReadMessageUpdateRequestDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/ReadMessageUpdateRequestDto.java index 67d173c5..20335183 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/ReadMessageUpdateRequestDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/ReadMessageUpdateRequestDto.java @@ -12,7 +12,10 @@ @AllArgsConstructor @Builder public class ReadMessageUpdateRequestDto { - @NotBlank private String roomId; - @NotBlank private String uid; - @NotBlank private String messageId; + @NotBlank + private String roomId; + @NotBlank + private Long uid; + @NotBlank + private String messageId; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/RoomCreateRequestDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/RoomCreateRequestDto.java index 9c44a8ab..cdc023ef 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/RoomCreateRequestDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/RoomCreateRequestDto.java @@ -12,7 +12,16 @@ @Builder public class RoomCreateRequestDto { - @NotBlank private Long uid; - @NotBlank private String nickName; - @NotBlank private Playlist playlist; + @NotBlank + private Long uid; + @NotBlank + private String nickName; + @NotBlank + private String userProfileImage; + @NotBlank + private Playlist playlist; + + public String getThumbnailImage() { + return this.playlist.getFirstMusic().getThumbnail(); + } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/request/UserEntranceRequestDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/UserEntranceRequestDto.java new file mode 100644 index 00000000..91c931a8 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/request/UserEntranceRequestDto.java @@ -0,0 +1,18 @@ +package chattingserver.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.*; + +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class UserEntranceRequestDto { + + @NotBlank + private Long uid; + @NotBlank + private String nickName; + private String profileImage; +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ChatMessageResponseDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ChatMessageResponseDto.java index 3904de2d..4ffccf52 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ChatMessageResponseDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ChatMessageResponseDto.java @@ -17,6 +17,8 @@ public class ChatMessageResponseDto { private MessageType messageType; private String roomId; private Long senderId; + private String nickName; + private String senderProfileImage; private String content; private LocalDateTime createdAt; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/JoinedRoomResponseDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/JoinedRoomResponseDto.java index f9980568..9ac634c1 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/JoinedRoomResponseDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/JoinedRoomResponseDto.java @@ -1,5 +1,8 @@ package chattingserver.dto.response; +import chattingserver.domain.chat.LastMessage; +import chattingserver.domain.room.User; +import lombok.*; import java.util.List; import lombok.*; @@ -14,7 +17,8 @@ public class JoinedRoomResponseDto { private String roomId; private String roomName; + private String thumbnailImage; private List users; - - // private LastMessage last_message; + private UserListResponseDto playlistOwner; + private LastMessage lastMessage; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ReEnterResponseDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ReEnterResponseDto.java new file mode 100644 index 00000000..f612dc0c --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/ReEnterResponseDto.java @@ -0,0 +1,15 @@ +package chattingserver.dto.response; + +import lombok.*; + +import java.util.List; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class ReEnterResponseDto { + private List beforeMessages; + private List newMessages; +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/RoomResponseDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/RoomResponseDto.java index f479c947..b44b180e 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/RoomResponseDto.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/RoomResponseDto.java @@ -17,9 +17,10 @@ public class RoomResponseDto { private String id; private String roomName; private long userCount; - private List users; + private List users; + private UserListResponseDto playlistOwner; private Playlist playlist; + private String thumbnailImage; private LocalDateTime createdAt; - // private Music thumbnail; } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/dto/response/UserListResponseDto.java b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/UserListResponseDto.java new file mode 100644 index 00000000..f816c897 --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/dto/response/UserListResponseDto.java @@ -0,0 +1,17 @@ +package chattingserver.dto.response; + +import lombok.*; + +import java.time.LocalDateTime; + +@Getter +@Builder +@ToString +@AllArgsConstructor +@NoArgsConstructor + +public class UserListResponseDto { + private Long uid; + private String nickName; + private String profileImage; +} \ No newline at end of file diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepository.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepository.java index 5773f48d..657bccd4 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepository.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepository.java @@ -1,8 +1,12 @@ package chattingserver.repository; +import chattingserver.domain.chat.ChatMessage; import org.springframework.data.mongodb.repository.MongoRepository; -import chattingserver.domain.chat.ChatMessage; +import java.util.List; + +public interface ChatMessageRepository extends MongoRepository, ChatMessageRepositoryCustom { + -public interface ChatMessageRepository - extends MongoRepository, ChatMessageRepositoryCustom {} + ChatMessage getLastMessage(String roomId); +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryCustom.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryCustom.java index b7ac73eb..1525577c 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryCustom.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryCustom.java @@ -14,4 +14,8 @@ public interface ChatMessageRepositoryCustom { Collection getAllMessagesAtRoom(String roomId); List getNewMessages(String roomId, String readMsgId); + + ChatMessage getLastMessage(String roomId); + List findPreviousMessages(String roomId, String readMsgId, int limit); + } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryImpl.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryImpl.java index 8d01e09a..ad69ee2a 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryImpl.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatMessageRepositoryImpl.java @@ -62,4 +62,28 @@ public List getNewMessages(String roomId, String readMsgId) { .with(Sort.by(Sort.Direction.DESC, "createdAt")), ChatMessage.class); } + + @Override + public ChatMessage getLastMessage(String roomId) { + + Query query = Query.query(Criteria.where("roomId").is(roomId)).with(Sort.by(Sort.Direction.DESC,"createdAt")); + + query.fields().exclude("roomId"); + query.fields().exclude("type"); + + ChatMessage chatMessage = mongoTemplate.findOne(query, ChatMessage.class); + if(chatMessage == null){ + return new ChatMessage(); + } + return chatMessage; + } + + @Override + public List findPreviousMessages(String roomId, String readMsgId, int limit) { + ObjectId readMsgObjectId = new ObjectId(readMsgId); + Query query = new Query(); + query.addCriteria(Criteria.where("roomId").is(roomId).and("_id").lt(readMsgObjectId)); + query.limit(20); + return mongoTemplate.find(query, ChatMessage.class); + } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatroomDummyInitializer.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatroomDummyInitializer.java new file mode 100644 index 00000000..cd9b75fe --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/ChatroomDummyInitializer.java @@ -0,0 +1,192 @@ +package chattingserver.repository; + +import chattingserver.domain.chat.ChatMessage; +import chattingserver.domain.room.Music; +import chattingserver.domain.room.Playlist; +import chattingserver.domain.room.Room; +import chattingserver.domain.room.User; +import chattingserver.util.constant.MessageType; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@RequiredArgsConstructor +@Slf4j +@Component +public class ChatroomDummyInitializer implements ApplicationRunner { + + private final RoomRepository roomRepository; + private final ChatMessageRepository chatMessageRepository; + + @Override + public void run(ApplicationArguments args) throws Exception { + User dummyUser1 = User.builder() + .uid(1L) + .nickName("유저닉네임1") + .profileImage("https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_960_720.png") + .enteredAt(LocalDateTime.now()) + .build(); + + User dummyUser2 = User.builder() + .uid(2L) + .nickName("유저닉네임2") + .profileImage("") + .enteredAt(LocalDateTime.now()) + .build(); + + List users = new ArrayList<>(); + users.add(dummyUser1); + users.add(dummyUser2); + + Music dummyMusic1 = Music.builder() + .title("음원1") + .artist("아티스트1") + .playtime("12:34") + .thumbnail("https://marketplace.canva.com/EAFHtE880QY/1/0/1600w/canva-blue-and-red-modern-music-youtube-thumbnail-cBAYqTj4TLk.jpg") + .build(); + + Music dummyMusic2 = Music.builder() + .title("음원2") + .artist("아티스트2") + .playtime("01:23") + .thumbnail("https://marketplace.canva.com/EAFOwKVP0Ck/1/0/1600w/canva-blue-orange-colorful-aesthetic-minimalist-lofi-music-youtube-thumbnail-ETT-krmERlk.jpg") + .build(); + + List dummyMusics = new ArrayList<>(); + dummyMusics.add(dummyMusic1); + dummyMusics.add(dummyMusic2); + + + Playlist dummyPlaylist = Playlist.builder() + .id("qwer1234") + .name("플레이리스트1") + .musics(dummyMusics) + .playlistOwnerId(dummyUser1.getUid()) + .playlistOwnerNickName(dummyUser1.getNickName()) + .playlistOwnerProfileImage(dummyUser1.getProfileImage()) + .build(); + + // room build + Room dummyRoom = Room.builder() + .roomName(dummyPlaylist.getName()) + .playlist(dummyPlaylist) + .thumbnailImage(dummyPlaylist.getFirstMusic().getThumbnail()) + .users(users) + .playlistOwner(dummyUser1) + .createdAt(LocalDateTime.now()) + .build(); + + roomRepository.save(dummyRoom); + log.info("방 생성 성공 room={}", dummyRoom); + + ChatMessage message1 = chatMessageRepository.save(ChatMessage.builder() + .messageType(MessageType.MSG) + .roomId(dummyRoom.getId()) + .senderId(dummyUser1.getUid()) + .nickName(dummyUser1.getNickName()) + .senderProfileImage(dummyUser1.getProfileImage()) + .content("메시지메시지1") + .createdAt(LocalDateTime.now()) + .build()); + + ChatMessage message2 = chatMessageRepository.save(ChatMessage.builder() + .messageType(MessageType.MSG) + .roomId(dummyRoom.getId()) + .senderId(dummyUser2.getUid()) + .nickName(dummyUser2.getNickName()) + .senderProfileImage(dummyUser2.getProfileImage()) + .content("메시지메시지2") + .createdAt(LocalDateTime.now()) + .build()); + + log.info("메시지 생성 성공 message1={}", message1); + log.info("메시지 생성 성공 message2={}", message2); + + User dummyUser3 = User.builder() + .uid(3L) + .nickName("유저닉네임3") + .profileImage("https://t4.ftcdn.net/jpg/03/64/21/11/360_F_364211147_1qgLVxv1Tcq0Ohz3FawUfrtONzz8nq3e.jpg") + .enteredAt(LocalDateTime.now()) + .build(); + + User dummyUser4 = User.builder() + .uid(3L) + .nickName("유저닉네임4") + .profileImage("https://images.pexels.com/photos/771742/pexels-photo-771742.jpeg?cs=srgb&dl=pexels-mohamed-abdelghaffar-771742.jpg&fm=jpg") + .enteredAt(LocalDateTime.now()) + .build(); + + List users2 = new ArrayList<>(); + users2.add(dummyUser3); + users2.add(dummyUser4); + users2.add(dummyUser1); + + Music dummyMusic3 = Music.builder() + .title("음원3") + .artist("아티스트3") + .playtime("12:34") + .thumbnail("https://content.wepik.com/statics/13638236/preview-page0.jpg") + .build(); + + List dummyMusics2 = new ArrayList<>(); + dummyMusics2.add(dummyMusic1); + dummyMusics2.add(dummyMusic3); + + + Playlist dummyPlaylist2 = Playlist.builder() + .id("098765432qwerty") + .name("플레이리스트2") + .musics(dummyMusics2) + .playlistOwnerId(dummyUser3.getUid()) + .playlistOwnerNickName(dummyUser3.getNickName()) + .playlistOwnerProfileImage(dummyUser3.getProfileImage()) + .build(); + + log.info("dummyPlaylist2={}", dummyPlaylist2.toString()); + log.info("dummyPlaylist2 firstMusic={}", dummyPlaylist2.getFirstMusic().toString()); + + // room build + Room dummyRoom2 = Room.builder() + .roomName(dummyPlaylist2.getName()) + .playlist(dummyPlaylist2) + .thumbnailImage(dummyPlaylist2.getFirstMusic().getThumbnail()) + .users(users2) + .playlistOwner(dummyUser3) + .createdAt(LocalDateTime.now()) + .build(); + + roomRepository.save(dummyRoom2); + log.info("방 생성 성공 room={}", dummyRoom); + + ChatMessage message3 = chatMessageRepository.save(ChatMessage.builder() + .messageType(MessageType.MSG) + .roomId(dummyRoom2.getId()) + .senderId(dummyUser1.getUid()) + .nickName(dummyUser1.getNickName()) + .senderProfileImage(dummyUser1.getProfileImage()) + .content("메시지메시지3") + .createdAt(LocalDateTime.now()) + .build()); + + ChatMessage message4 = chatMessageRepository.save(ChatMessage.builder() + .messageType(MessageType.MSG) + .roomId(dummyRoom2.getId()) + .senderId(dummyUser4.getUid()) + .nickName(dummyUser4.getNickName()) + .senderProfileImage(dummyUser4.getProfileImage()) + .content("메시지메시지4") + .createdAt(LocalDateTime.now()) + .build()); + + log.info("메시지 생성 성공 message3={}", message3); + log.info("메시지 생성 성공 message4={}", message4); + + + } +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepository.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepository.java index 161d91a9..8effe417 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepository.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepository.java @@ -1,8 +1,7 @@ package chattingserver.repository; -import java.util.List; -import java.util.Optional; - +import chattingserver.domain.room.Room; +import chattingserver.domain.room.User; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.repository.MongoRepository; import org.springframework.data.mongodb.repository.Query; diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryCustom.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryCustom.java index 7955d7d7..00007873 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryCustom.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryCustom.java @@ -1,11 +1,13 @@ package chattingserver.repository; +import chattingserver.domain.room.User; import chattingserver.dto.request.ReadMessageUpdateRequestDto; import com.mongodb.client.result.UpdateResult; public interface RoomRepositoryCustom { void exitRoom(String roomId, Long uid); + UpdateResult addUserToRoom(String roomId, User user); UpdateResult updateLastReadMsgId(ReadMessageUpdateRequestDto requestDto); } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryImpl.java b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryImpl.java index 299b74e6..7f0a0f08 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryImpl.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/repository/RoomRepositoryImpl.java @@ -1,5 +1,9 @@ package chattingserver.repository; +import chattingserver.domain.room.Room; +import chattingserver.domain.room.User; +import chattingserver.dto.request.ReadMessageUpdateRequestDto; +import com.mongodb.client.result.UpdateResult; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; @@ -29,16 +33,19 @@ public void exitRoom(String roomId, Long uid) { @Override public UpdateResult updateLastReadMsgId(ReadMessageUpdateRequestDto requestDto) { - Query query = - Query.query( - Criteria.where("roomId") - .is(requestDto.getRoomId()) - .andOperator( - Criteria.where("users") - .elemMatch(Criteria.where("uid").is(requestDto.getUid())))); + Query query = Query.query( + Criteria.where("_id").is(requestDto.getRoomId()) + .andOperator(Criteria.where("users").elemMatch(Criteria.where("uid").is(requestDto.getUid()))) + ); - Update update = new Update().set("users.$.lastReadMsgId", requestDto.getMessageId()); + Update update = new Update().set("users.$.lastReadMessageId", requestDto.getMessageId()); + return mongoTemplate.updateFirst(query, update, Room.class); + } + @Override + public UpdateResult addUserToRoom(String roomId, User user) { + Query query = new Query(Criteria.where("_id").is(roomId)); + Update update = new Update().addToSet("users", user); return mongoTemplate.updateFirst(query, update, Room.class); } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/service/ChatMessageService.java b/src/backend/chatting-server/src/main/java/chattingserver/service/ChatMessageService.java index c7c01bce..95c33469 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/service/ChatMessageService.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/service/ChatMessageService.java @@ -1,26 +1,32 @@ package chattingserver.service; -import java.io.IOException; -import java.time.LocalDateTime; -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; - +import chattingserver.domain.chat.ChatMessage; +import chattingserver.domain.room.Room; +import chattingserver.domain.room.User; +import chattingserver.dto.ChatMessageDto; +import chattingserver.dto.request.UserEntranceRequestDto; +import chattingserver.dto.response.ChatMessageResponseDto; +import chattingserver.repository.ChatMessageRepository; +import chattingserver.repository.RoomRepository; +import chattingserver.util.constant.MessageType; +import chattingserver.util.converter.EntityToResponseDtoConverter; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; +import org.springframework.data.mongodb.MongoTransactionManager; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; -import chattingserver.domain.chat.ChatMessage; -import chattingserver.dto.ChatMessageDto; -import chattingserver.dto.response.ChatMessageResponseDto; -import chattingserver.repository.ChatMessageRepository; -import chattingserver.util.constant.MessageType; -import chattingserver.util.converter.EntityToResponseDtoConverter; -import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import java.time.LocalDateTime; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; @RequiredArgsConstructor @Slf4j @@ -29,9 +35,11 @@ public class ChatMessageService { private final ObjectMapper objectMapper; private final ChatMessageRepository chatMessageRepository; + private final RoomRepository roomRepository; private final EntityToResponseDtoConverter entityToResponseDtoConverter; - private static final int SIZE = 12; + + private static final int SIZE = 20; public void sendMessage(WebSocketSession session, T message) { try { @@ -41,95 +49,128 @@ public void sendMessage(WebSocketSession session, T message) { } } - public ChatMessageResponseDto saveChatMessage(ChatMessageDto chatMessageDto) { + public ChatMessageDto saveChatMessage(ChatMessageDto chatMessageDto) { - ChatMessage message = - chatMessageRepository.save( - ChatMessage.builder() - .messageType(chatMessageDto.getMessageType()) - .roomId(chatMessageDto.getRoomId()) - .senderId(chatMessageDto.getSenderId()) - .content(chatMessageDto.getContent()) - .createdAt(LocalDateTime.now()) - .build()); + ChatMessage message = chatMessageRepository.save(ChatMessage.builder() + .messageType(chatMessageDto.getMessageType()) + .roomId(chatMessageDto.getRoomId()) + .senderId(chatMessageDto.getSenderId()) + .nickName(chatMessageDto.getNickName()) + .senderProfileImage(chatMessageDto.getSenderProfileImage()) + .content(chatMessageDto.getContent()) + .createdAt(LocalDateTime.now()) + .build()); log.info("메시지 저장 성공 message={}", message); return entityToResponseDtoConverter.convertMessage(message); } - public Object getNewMessages(String roomId, String readMsgId) { + public List getNewMessages(String roomId, String readMsgId) { List messages = chatMessageRepository.getNewMessages(roomId, readMsgId); - log.info("신규 메시지 조회 성공 roomId={}, readMsgId={}", roomId, readMsgId); - return messages.stream() - .map(entityToResponseDtoConverter::convertMessage) - .collect(Collectors.toList()); + log.info("신규 메시지 조회 성공 roomId={}, readMsgId={}, messages={}", roomId, readMsgId, messages); + return messages.stream().map(entityToResponseDtoConverter::convertToResponseMessage).collect(Collectors.toList()); } public List getAllMessagesAtRoom(String roomId) { - return chatMessageRepository.getAllMessagesAtRoom(roomId).stream() - .map(entityToResponseDtoConverter::convertMessage) - .collect(Collectors.toList()); + return chatMessageRepository.getAllMessagesAtRoom(roomId).stream().map(entityToResponseDtoConverter::convertToResponseMessage).collect(Collectors.toList()); } public Page chatMessagePagination(String roomId, int page) { Page messagePage = chatMessageRepository.findByRoomIdWithPagingAndFiltering(roomId, page, SIZE); log.info("특정 채팅방 메시지 페이지네이션 조회 성공 roomId={}", roomId); - return messagePage.map( - new Function() { - @Override - public ChatMessageResponseDto apply(ChatMessage message) { - return entityToResponseDtoConverter.convertMessage(message); - } - }); + return messagePage.map(new Function() { + @Override + public ChatMessageResponseDto apply(ChatMessage message) { + return entityToResponseDtoConverter.convertToResponseMessage(message); + } + }); } public void deleteChat(String id) { chatMessageRepository.deleteById(id); } + @Transactional public ChatMessageDto join(ChatMessageDto chatMessageDto) { + try { + Optional optionalRoom = roomRepository.findById(chatMessageDto.getRoomId()); + if (optionalRoom.isEmpty()) { + log.info("해당하는 방이 없습니다. roomId={}", chatMessageDto.getRoomId()); + // TODO null처리 + return null; + } + + Room room = optionalRoom.get(); + + ChatMessage message = chatMessageRepository.save(ChatMessage.builder() + .messageType(MessageType.ENTRANCE) + .roomId(chatMessageDto.getRoomId()) + .senderId(chatMessageDto.getSenderId()) + .nickName(chatMessageDto.getNickName()) + .content(chatMessageDto.getNickName() + "님이 입장하셨습니다.") + .senderProfileImage(chatMessageDto.getSenderProfileImage()) + .createdAt(LocalDateTime.now()) + .build()); + + User joinedUser = User.builder() + .uid(chatMessageDto.getSenderId()) + .nickName(chatMessageDto.getNickName()) + .profileImage(chatMessageDto.getSenderProfileImage()) + .enteredAt(LocalDateTime.now()) + .lastReadMessageId(message.getId()) + .build(); + + roomRepository.addUserToRoom(room.getId(), joinedUser); + + return entityToResponseDtoConverter.convertMessage(message); + } catch (Exception e) { + log.error("트랜잭션 오류: {}", e.getMessage()); + // TODO 트랜잭션 롤백 또는 예외 처리 로직 추가 + throw new RuntimeException("트랜잭션 오류 발생"); + } + } + + public ChatMessageDto permanentLeaving(String roomId, UserEntranceRequestDto userDto) { - ChatMessage message = - chatMessageRepository.save( - ChatMessage.builder() - .messageType(MessageType.ENTRANCE) - .roomId(chatMessageDto.getRoomId()) - .senderId(chatMessageDto.getSenderId()) - .content(chatMessageDto.getSenderId() + "님이 입장하셨습니다.") - .createdAt(LocalDateTime.now()) - .build()); - - return ChatMessageDto.builder() - .id(message.getId()) - .messageType(message.getMessageType()) - .roomId(message.getRoomId()) - .senderId(message.getSenderId()) - .content(message.getContent()) - .createdAt(message.getCreatedAt()) + Optional optionalRoom = roomRepository.findById(roomId); + if (optionalRoom.isEmpty()) { + log.info("해당하는 방이 없습니다. roomId={}", roomId); + // TODO null처리 + return null; + } + + Room room = optionalRoom.get(); + Optional optionalUser = room.getUsers().stream().filter(u -> u.getUid().equals(userDto.getUid())).findAny(); + if (optionalUser.isEmpty()) { + log.info("해당하는 유저가 없습니다. uId={}", userDto.getUid()); + // TODO null처리 + return null; + } + + room.getUsers().remove(optionalUser.get()); + + ChatMessage chatMessage = ChatMessage.builder() + .messageType(MessageType.ENTRANCE) + .roomId(roomId) + .senderId(userDto.getUid()) + .nickName(userDto.getNickName()) + .senderProfileImage(userDto.getProfileImage()) + .content(userDto.getNickName() + "님이 퇴장하셨습니다.") + .createdAt(LocalDateTime.now()) .build(); + + chatMessageRepository.save(chatMessage); + + return entityToResponseDtoConverter.convertMessage(chatMessage); + } - public ChatMessageDto leave(ChatMessageDto chatMessageDto) { - - ChatMessage message = - chatMessageRepository.save( - ChatMessage.builder() - .messageType(MessageType.ENTRANCE) - .roomId(chatMessageDto.getRoomId()) - .senderId(chatMessageDto.getSenderId()) - .content(chatMessageDto.getSenderId() + "님이 퇴장하셨습니다.") - .createdAt(LocalDateTime.now()) - .build()); - - return ChatMessageDto.builder() - .id(message.getId()) - .messageType(message.getMessageType()) - .roomId(message.getRoomId()) - .senderId(message.getSenderId()) - .content(message.getContent()) - .createdAt(message.getCreatedAt()) - .build(); + public List getMessagesBefore(String roomId, String readMsgId) { + List messages = chatMessageRepository.findPreviousMessages(roomId, readMsgId, SIZE); + log.info("이전 메시지 조회 성공 roomId={}, readMsgId={}, messages={}", roomId, readMsgId, messages); + return messages.stream().map(entityToResponseDtoConverter::convertToResponseMessage).collect(Collectors.toList()); } + } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/service/RoomService.java b/src/backend/chatting-server/src/main/java/chattingserver/service/RoomService.java index 51a58b80..ea20846b 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/service/RoomService.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/service/RoomService.java @@ -1,31 +1,35 @@ package chattingserver.service; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; - +import chattingserver.domain.chat.ChatMessage; +import chattingserver.domain.chat.LastMessage; import chattingserver.domain.room.Room; import chattingserver.domain.room.User; import chattingserver.dto.request.ReadMessageUpdateRequestDto; import chattingserver.dto.request.RoomCreateRequestDto; +import chattingserver.dto.response.CommonAPIMessage; import chattingserver.dto.response.JoinedRoomResponseDto; import chattingserver.dto.response.RoomResponseDto; +import chattingserver.repository.ChatMessageRepository; import chattingserver.repository.RoomRepository; import chattingserver.util.converter.EntityToResponseDtoConverter; +import com.mongodb.client.result.UpdateResult; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; @Service @Slf4j @RequiredArgsConstructor public class RoomService { private final RoomRepository roomRepository; + private final ChatMessageRepository chatMessageRepository; private final EntityToResponseDtoConverter entityToResponseDtoConverter; public RoomResponseDto getRoomInfo(String roomId) { @@ -42,23 +46,25 @@ public List findJoinedRoomsByUid(Long uid) { for (Room room : roomList) { String roomId = room.getId(); - // MessageCollection messageCollection = - // chatMessageRepository.getLastMessage(roomId); - - // LastMessage lastMessage = LastMessage.builder() - // - // .message_id(messageCollection.get_id()).sender_id(messageCollection.getSenderId()) - // - // .content(messageCollection.getContent()).created_at(messageCollection.getCreatedAt()) - // .build(); - - myRoomsDto.add( - JoinedRoomResponseDto.builder() - .roomId(roomId) - .roomName(room.getRoomName()) - .users(room.getUsers()) - // .last_message(lastMessage) - .build()); + ChatMessage message = chatMessageRepository.getLastMessage(roomId); + + LastMessage lastMessage = LastMessage.builder() + .messageId(message.getId()) + .senderId(message.getSenderId()) + .nickName(message.getNickName()) + .senderProfileImage(message.getSenderProfileImage()) + .content(message.getContent()) + .createdAt(message.getCreatedAt()) + .build(); + + myRoomsDto.add(JoinedRoomResponseDto.builder() + .roomId(roomId) + .roomName(room.getRoomName()) + .thumbnailImage(room.getThumbnailImage()) + .users(room.getUsers()) + .playlistOwner(entityToResponseDtoConverter.convertUser(room.getPlaylistOwner())) + .lastMessage(lastMessage) + .build()); } return myRoomsDto; @@ -73,37 +79,38 @@ public List findUnjoinedRooms(Long uid) { log.info("참여하지 않은 방 리스트 조회 성공 uid={}", uid); return unjoinedRooms.stream() - .map( - room -> - RoomResponseDto.builder() - .id(room.getId()) - .roomName(room.getRoomName()) - .userCount(room.getUsers().size()) - .users(room.getUsers()) - .playlist(room.getPlaylist()) - .build()) + .map(room -> RoomResponseDto.builder() + .id(room.getId()) + .roomName(room.getRoomName()) + .thumbnailImage(room.getThumbnailImage()) + .userCount(room.getUsers().size()) + .users(room.getUsers().stream().map(entityToResponseDtoConverter::convertUser).collect(Collectors.toList())) + .playlist(room.getPlaylist()) + .playlistOwner(entityToResponseDtoConverter.convertUser(room.getPlaylistOwner())) + .build()) .collect(Collectors.toList()); } public RoomResponseDto create(RoomCreateRequestDto roomCreateRequestDto) { // user build - User user = - User.builder() - .uid(roomCreateRequestDto.getUid()) - .nickName(roomCreateRequestDto.getNickName()) - .enteredAt(LocalDateTime.now()) - .build(); + User owner = User.builder() + .uid(roomCreateRequestDto.getUid()) + .nickName(roomCreateRequestDto.getNickName()) + .profileImage(roomCreateRequestDto.getUserProfileImage()) + .enteredAt(LocalDateTime.now()) + .build(); List users = new ArrayList<>(); - users.add(user); + users.add(owner); // room build - Room room = - Room.builder() - .roomName(roomCreateRequestDto.getPlaylist().getName()) - .playlist(roomCreateRequestDto.getPlaylist()) - .users(users) - .build(); + Room room = Room.builder() + .roomName(roomCreateRequestDto.getPlaylist().getName()) + .playlist(roomCreateRequestDto.getPlaylist()) + .thumbnailImage(roomCreateRequestDto.getThumbnailImage()) + .playlistOwner(owner) + .users(users) + .build(); log.info("생성된 방에 생성자 추가 성공 user={}", room.getUsers().toString()); Room savedRoom = roomRepository.save(room); @@ -122,23 +129,20 @@ public boolean exitRoom(String roomId, Long uid) { } } - public boolean updateLastReadMsgId( - String roomId, Long uid, ReadMessageUpdateRequestDto requestDto) { - try { - roomRepository.updateLastReadMsgId(requestDto); - log.info( - "LastReadMsgId 업데이트 성공 uid={}, roomId={}, 업데이트 완료 message_id={}", - uid, - roomId, - requestDto.getMessageId()); - return true; - } catch (Exception e) { - log.error("LastReadMsgId 업데이트 실패 uid={}, roomId={}: {}", uid, roomId, e.getMessage()); - return false; - } + public CommonAPIMessage updateLastReadMsgId(ReadMessageUpdateRequestDto requestDto) { + UpdateResult updateResult = roomRepository.updateLastReadMsgId(requestDto); + if (updateResult.getModifiedCount() == 0) + return new CommonAPIMessage(CommonAPIMessage.ResultEnum.failed, updateResult.getModifiedCount()); + return new CommonAPIMessage(CommonAPIMessage.ResultEnum.success, updateResult.getModifiedCount()); } public boolean isExistingRoom(String roomId) { return roomRepository.existsById(roomId); } + + public List getAllRoomInfos() { + return roomRepository.findAll().stream() + .map(entityToResponseDtoConverter::convertRoom) + .collect(Collectors.toList()); + } } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/service/SearchService.java b/src/backend/chatting-server/src/main/java/chattingserver/service/SearchService.java new file mode 100644 index 00000000..6a3beddd --- /dev/null +++ b/src/backend/chatting-server/src/main/java/chattingserver/service/SearchService.java @@ -0,0 +1,33 @@ +package chattingserver.service; + +import chattingserver.controller.SearchProxy; +import chattingserver.dto.request.IndexingRequestMessageDto; +import chattingserver.dto.response.RoomResponseDto; +import feign.FeignException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@Async("search") +@RequiredArgsConstructor +public class SearchService { + private final SearchProxy searchProxy; + + public void sendIndexingRequestToSearchServer(RoomResponseDto roomResponseDto) { + + try { + searchProxy.sendIndexingRequest(IndexingRequestMessageDto.builder() + .roomId(roomResponseDto.getId()) + .roomName(roomResponseDto.getRoomName()) + .playlistId(roomResponseDto.getPlaylist().getId()) + .thumbnailImage(roomResponseDto.getThumbnailImage()) + .build()); + } catch (FeignException e) { + log.error("searchProxy.sendIndexingRequest, 검색 서버 연결 불가"); + } + log.info("검색 서버에 인덱싱 요청 성공"); + } +} diff --git a/src/backend/chatting-server/src/main/java/chattingserver/util/constant/MessageType.java b/src/backend/chatting-server/src/main/java/chattingserver/util/constant/MessageType.java index 8028f6d4..622149e2 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/util/constant/MessageType.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/util/constant/MessageType.java @@ -1,6 +1,5 @@ package chattingserver.util.constant; -public enum MessageType { - ENTRANCE, - MSG +public enum MessageType{ + ENTRANCE, CREATION, MSG } diff --git a/src/backend/chatting-server/src/main/java/chattingserver/util/converter/EntityToResponseDtoConverter.java b/src/backend/chatting-server/src/main/java/chattingserver/util/converter/EntityToResponseDtoConverter.java index 152d8a5a..0ffd336b 100644 --- a/src/backend/chatting-server/src/main/java/chattingserver/util/converter/EntityToResponseDtoConverter.java +++ b/src/backend/chatting-server/src/main/java/chattingserver/util/converter/EntityToResponseDtoConverter.java @@ -2,8 +2,13 @@ import chattingserver.domain.chat.ChatMessage; import chattingserver.domain.room.Room; +import chattingserver.domain.room.User; +import chattingserver.dto.ChatMessageDto; import chattingserver.dto.response.ChatMessageResponseDto; import chattingserver.dto.response.RoomResponseDto; +import chattingserver.dto.response.UserListResponseDto; + +import java.util.stream.Collectors; public class EntityToResponseDtoConverter { @@ -12,18 +17,41 @@ public RoomResponseDto convertRoom(Room room) { .id(room.getId()) .roomName(room.getRoomName()) .userCount(room.getUsers().size()) - .users(room.getUsers()) + .users(room.getUsers().stream().map(this::convertUser).collect(Collectors.toList())) .playlist(room.getPlaylist()) - // .thumbnail(room.getPlaylist().getMusics().get(0)) // 플레이리스트에 곡 무조건 존재함을 신뢰 + .thumbnailImage(room.getThumbnailImage()) // 플레이리스트에 곡 무조건 존재함을 신뢰 + .build(); + } + + public UserListResponseDto convertUser(User user) { + return UserListResponseDto.builder() + .uid(user.getUid()) + .nickName(user.getNickName()) + .profileImage(user.getProfileImage()) + .build(); + } + + public ChatMessageDto convertMessage(ChatMessage message) { + return ChatMessageDto.builder() + .id(message.getId()) + .messageType(message.getMessageType()) + .roomId(message.getRoomId()) + .senderId(message.getSenderId()) + .nickName(message.getNickName()) + .senderProfileImage(message.getSenderProfileImage()) + .content(message.getContent()) + .createdAt(message.getCreatedAt()) .build(); } - public ChatMessageResponseDto convertMessage(ChatMessage message) { + public ChatMessageResponseDto convertToResponseMessage(ChatMessage message) { return ChatMessageResponseDto.builder() .id(message.getId()) .messageType(message.getMessageType()) .roomId(message.getRoomId()) .senderId(message.getSenderId()) + .nickName(message.getNickName()) + .senderProfileImage(message.getSenderProfileImage()) .content(message.getContent()) .createdAt(message.getCreatedAt()) .build(); diff --git a/src/backend/chatting-server/src/main/resources/application.yml b/src/backend/chatting-server/src/main/resources/application.yml index d3efb829..5bcfbdc9 100644 --- a/src/backend/chatting-server/src/main/resources/application.yml +++ b/src/backend/chatting-server/src/main/resources/application.yml @@ -7,19 +7,15 @@ spring: data: mongodb: - host: localhost - port: 18100 + host: chatting-mongo + port: 27017 database: chatting username: chatting-admin password: JMTpdsu8YkLEX4RA authentication-database: admin kafka: - bootstrap-servers: localhost:40000,localhost:40001,localhost:40002 - - topic: - chat-name: message - room-name: room + bootstrap-servers: Kafka00Service:9092,Kafka01Service:9092,Kafka02Service:9092 consumer: room-consumer: