Skip to content

Commit

Permalink
Merge pull request #52 from oven-2023/feature/chat
Browse files Browse the repository at this point in the history
feat: add message api with stomp
  • Loading branch information
haen-su authored Nov 6, 2023
2 parents 4959199 + 448d799 commit 1b0a4ec
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.oven.server.api.chat.controller;

import com.oven.server.api.chat.dto.request.MessageRequest;
import com.oven.server.api.chat.service.MessageService;
import com.oven.server.api.user.domain.User;
import com.oven.server.common.response.Response;
import com.oven.server.common.response.ResponseCode;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Slf4j
@Tag(name = "Message", description = "메세지 API")
public class MessageController {

private final MessageService messageService;

@Operation(tags = "Message", description = "메세지 전송")
@MessageMapping(value = "/chatrooms/{chatroomId}/message")
public Response<Void> sendMessage(@PathVariable(value = "chatroomId") Long chatroomId,
@AuthenticationPrincipal User user,
@RequestBody MessageRequest messageRequest) {

messageService.sendMessage(chatroomId, user, messageRequest);
return Response.success(ResponseCode.SUCCESS_CREATED);

}

}
8 changes: 8 additions & 0 deletions src/main/java/com/oven/server/api/chat/domain/Message.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.oven.server.api.user.domain.User;
import com.oven.server.common.BaseEntity;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;


Expand All @@ -26,4 +27,11 @@ public class Message extends BaseEntity {
@Lob
private String content;

@Builder
public Message(Chatroom chatroom, User sender, String content) {
this.chatroom = chatroom;
this.sender = sender;
this.content = content;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.oven.server.api.chat.dto.request;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class MessageRequest {

private String content;

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ public class EnterChatroomResponse {
private boolean isNewEnter;

@Schema(description = "메시지")
private List<MessagesResponse> messages;
private List<MessageListResponse> messages;

@Builder
public EnterChatroomResponse(Long providerId, String title, int count, int wholeNum, boolean isNewEnter, List<MessagesResponse> messages) {
public EnterChatroomResponse(Long providerId, String title, int count, int wholeNum, boolean isNewEnter, List<MessageListResponse> messages) {
this.providerId = providerId;
this.title = title;
this.count = count;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.time.LocalDateTime;

@Getter
public class MessagesResponse {
public class MessageListResponse {

private String content;

Expand All @@ -15,7 +15,7 @@ public class MessagesResponse {
private boolean isSender;

@Builder
public MessagesResponse(String content, LocalDateTime sendTime, boolean isSender) {
public MessageListResponse(String content, LocalDateTime sendTime, boolean isSender) {
this.content = content;
this.sendTime = sendTime;
this.isSender = isSender;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.oven.server.api.chat.dto.response;

import lombok.Builder;

import java.time.LocalDateTime;

public class MessageResponse {

private String content;

private LocalDateTime sendTime;

private String senderNickname;

@Builder
public MessageResponse(String content, LocalDateTime sendTime, String senderNickname) {
this.content = content;
this.sendTime = sendTime;
this.senderNickname = senderNickname;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.oven.server.api.chat.domain.Chatroom;
import com.oven.server.api.chat.domain.Entrance;
import com.oven.server.api.chat.dto.response.EnterChatroomResponse;
import com.oven.server.api.chat.dto.response.MessagesResponse;
import com.oven.server.api.chat.dto.response.MessageListResponse;
import com.oven.server.api.chat.repository.ChatroomRepository;
import com.oven.server.api.chat.repository.EntranceRepository;
import com.oven.server.api.chat.repository.MessageRepository;
Expand All @@ -28,7 +28,7 @@ public class EnterChatroomService {
public EnterChatroomResponse enterChatroom(User user, Long chatroomId) {

Chatroom chatroom = chatroomRepository.findById(chatroomId).orElseThrow(
() -> new BaseException(ResponseCode.CHATROOM_NOt_FOUND)
() -> new BaseException(ResponseCode.CHATROOM_NOT_FOUND)
);

if(entranceRepository.findByUserAndChatroom(user, chatroom).isPresent()) {
Expand All @@ -40,7 +40,7 @@ public EnterChatroomResponse enterChatroom(User user, Long chatroomId) {
.isNewEnter(false)
.messages(messageRepository.findByChatroom(chatroom).stream()
.map(
message -> MessagesResponse.builder()
message -> MessageListResponse.builder()
.content(message.getContent())
.isSender(message.getSender() == user)
.sendTime(message.getCreatedAt())
Expand Down
52 changes: 52 additions & 0 deletions src/main/java/com/oven/server/api/chat/service/MessageService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.oven.server.api.chat.service;


import com.oven.server.api.chat.domain.Chatroom;
import com.oven.server.api.chat.domain.Message;
import com.oven.server.api.chat.dto.request.MessageRequest;
import com.oven.server.api.chat.dto.response.MessageResponse;
import com.oven.server.api.chat.repository.ChatroomRepository;
import com.oven.server.api.chat.repository.MessageRepository;
import com.oven.server.api.user.domain.User;
import com.oven.server.common.exception.BaseException;
import com.oven.server.common.response.ResponseCode;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
@Transactional
@Slf4j
public class MessageService {

private final SimpMessagingTemplate template;
private final MessageRepository messageRepository;
private final ChatroomRepository chatroomRepository;

public void sendMessage(Long chatroomId, User user, MessageRequest messageRequest) {

Chatroom chatroom = chatroomRepository.findById(chatroomId)
.orElseThrow(() -> new BaseException(ResponseCode.CHATROOM_NOT_FOUND));

Message message = Message.builder()
.sender(user)
.content(messageRequest.getContent())
.chatroom(chatroom)
.build();

messageRepository.save(message);

MessageResponse messageResponse = MessageResponse.builder()
.content(message.getContent())
.sendTime(message.getCreatedAt())
.senderNickname(user.getNickname())
.build();

template.convertAndSend("/sub/chatrooms/" + chatroomId + "/message", messageResponse);

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.oven.server.api.user.dto.request.RefreshTokenRequest;
import com.oven.server.api.user.dto.response.AccessTokenResponse;
import com.oven.server.api.user.dto.response.IdCheckResponse;
import com.oven.server.api.user.dto.response.JwtTokenResponse;
import com.oven.server.api.user.dto.response.LoginSuccessResponse;
import com.oven.server.api.user.repository.RefreshTokenRepository;
import com.oven.server.api.user.repository.UserRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public enum ResponseCode {

// Chat
PROVIDER_NOT_FOUND(BAD_REQUEST, "요청하신 OTT를 찾을 수 없습니다."),
CHATROOM_NOt_FOUND(BAD_REQUEST, "요청하신 채팅방을 찾을 수 없습니다.");
CHATROOM_NOT_FOUND(BAD_REQUEST, "요청하신 채팅방을 찾을 수 없습니다.");


private final HttpStatus httpStatus;
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/oven/server/config/WebSocketConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.oven.server.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
@Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/sub");
config.setApplicationDestinationPrefixes("/pub");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/stomp/chat").setAllowedOriginPatterns("*").withSockJS()
.setHeartbeatTime(1000);
log.info("[WebSocket Endpoints]: 소켓 열림");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.oven.server.api.user.dto.response.JwtTokenResponse;
import com.oven.server.api.user.service.RefreshTokenService;
import com.oven.server.api.user.service.UserDetailsServiceImpl;
import com.oven.server.common.exception.BaseException;
import com.oven.server.common.response.ResponseCode;
import io.jsonwebtoken.*;
Expand All @@ -13,7 +14,6 @@
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
Expand All @@ -25,7 +25,7 @@
@Slf4j
public class JwtTokenProvider {

private final UserDetailsService userDetailsService;
private final UserDetailsServiceImpl userDetailsService;
private final RefreshTokenService refreshTokenService;

@Value("${jwt.secret}")
Expand Down

0 comments on commit 1b0a4ec

Please sign in to comment.