Skip to content

Commit

Permalink
๐Ÿ”จ Refactor/#177 - RabbitMQ์˜ RPC ์š”์ฒญ-์‘๋‹ต ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ“๊ธ€ ๋ฐ ์ข‹์•„์š” ์ƒ์„ฑ ์‹œ, Responsโ€ฆ
Browse files Browse the repository at this point in the history
โ€ฆeBody ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ณ€๊ฒฝ (#178)

* ๐Ÿ”จ Refactor/#177 - RabbitMQ์˜ RPC ์š”์ฒญ-์‘๋‹ต ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ, ๋Œ“๊ธ€ ์ƒ์„ฑ ์‹œ

* ๐Ÿ”จ Refactor/#177 - RabbitMQ์˜ RPC ์š”์ฒญ-์‘๋‹ต ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข‹์•„์š” ์ƒ์„ฑ ์‹œ, ResponseBody ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ๋ณ€๊ฒฝ
  • Loading branch information
dongkyeomjang authored Nov 27, 2024
1 parent bb5fe1b commit 97890ff
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ public Jackson2JsonMessageConverter jsonMessageConverter() {
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonMessageConverter()); // JSON ์ปจ๋ฒ„ํ„ฐ ์„ค์ •
rabbitTemplate.setMessageConverter(jsonMessageConverter());
rabbitTemplate.setReplyTimeout(5000);
rabbitTemplate.setUseDirectReplyToContainer(true);
return rabbitTemplate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.daon.onjung.core.dto.ResponseDto;
import com.daon.onjung.suggestion.application.dto.request.CreateBoardRequestDto;
import com.daon.onjung.suggestion.application.dto.request.CreateCommentRequestDto;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.application.usecase.CreateBoardUseCase;
import com.daon.onjung.suggestion.application.usecase.CreateCommentUseCase;
import com.daon.onjung.suggestion.application.usecase.CreateOrDeleteLikeUseCase;
Expand Down Expand Up @@ -34,21 +36,19 @@ public ResponseDto<Void> createBoard(
}

@PostMapping("/api/v1/boards/{id}/comments")
public ResponseDto<Void> createComment(
public ResponseDto<CreateCommentResponseDto> createComment(
@AccountID UUID accountId,
@PathVariable Long id,
@RequestBody @Valid CreateCommentRequestDto requestDto
) {
createCommentUseCase.execute(accountId, id, requestDto);
return ResponseDto.created(null);
return ResponseDto.created(createCommentUseCase.execute(accountId, id, requestDto));
}

@PutMapping("/api/v1/boards/{id}/likes")
public ResponseDto<Void> likeBoard(
public ResponseDto<CreateOrDeleteLikeResponseDto> likeBoard(
@AccountID UUID accountId,
@PathVariable Long id
) {
createOrDeleteLikeUseCase.execute(accountId, id);
return ResponseDto.ok(null);
return ResponseDto.ok(createOrDeleteLikeUseCase.execute(accountId, id));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Comment;
import com.daon.onjung.suggestion.domain.service.BoardService;
Expand All @@ -14,6 +15,7 @@
import lombok.RequiredArgsConstructor;
import org.hibernate.dialect.lock.OptimisticEntityLockException;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -28,9 +30,11 @@ public class CommentV1Consumer {
private final CommentService commentService;
private final BoardService boardService;

private final RabbitTemplate rabbitTemplate;

@Transactional
@RabbitListener(queues = "comment-queue-1")
public void processCommentMessage1(CommentMessage commentMessage) {
public CreateCommentResponseDto processCommentMessage1(CommentMessage commentMessage) {
try {

// ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ
Expand All @@ -52,14 +56,16 @@ public void processCommentMessage1(CommentMessage commentMessage) {
// ๊ฒŒ์‹œ๊ธ€ ๋Œ“๊ธ€ ์ˆ˜ ์ฆ๊ฐ€
board = boardService.addCommentCount(board);
boardRepository.save(board);

return CreateCommentResponseDto.of(user, true, comment);
} catch (OptimisticEntityLockException e) {
throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION);
}
}

@Transactional
@RabbitListener(queues = "comment-queue-2")
public void processCommentMessage2(CommentMessage commentMessage) {
public CreateCommentResponseDto processCommentMessage2(CommentMessage commentMessage) {
try {

// ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ
Expand All @@ -81,6 +87,8 @@ public void processCommentMessage2(CommentMessage commentMessage) {
// ๊ฒŒ์‹œ๊ธ€ ๋Œ“๊ธ€ ์ˆ˜ ์ฆ๊ฐ€
board = boardService.addCommentCount(board);
boardRepository.save(board);

return CreateCommentResponseDto.of(user, true, comment);
} catch (OptimisticEntityLockException e) {
throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.daon.onjung.core.exception.error.ErrorCode;
import com.daon.onjung.core.exception.type.CommonException;
import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.domain.Like;
import com.daon.onjung.suggestion.domain.service.BoardService;
Expand All @@ -30,7 +31,7 @@ public class LikeV1Consumer {

@Transactional
@RabbitListener(queues = "like-queue")
public void processLikeMessage(LikeMessage likeMessage) {
public Boolean processLikeMessage(LikeMessage likeMessage) {
try {

// ๊ฒŒ์‹œ๊ธ€ ์กฐํšŒ
Expand All @@ -52,6 +53,7 @@ public void processLikeMessage(LikeMessage likeMessage) {
// ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š” ์ˆ˜ ๊ฐ์†Œ
board = boardService.subtractLikeCount(board);
boardRepository.save(board);
return false;
} else {

// ์ข‹์•„์š”๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ƒ์„ฑ
Expand All @@ -60,6 +62,7 @@ public void processLikeMessage(LikeMessage likeMessage) {
// ๊ฒŒ์‹œ๊ธ€ ์ข‹์•„์š” ์ˆ˜ ์ฆ๊ฐ€
board = boardService.addLikeCount(board);
boardRepository.save(board);
return true;
}
} catch (OptimisticEntityLockException e) {
throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.daon.onjung.suggestion.application.controller.producer;

import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.application.usecase.SendCommentRequestUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -11,8 +12,8 @@ public class CommentV1Producer {

private final SendCommentRequestUseCase sendCommentRequestUseCase;

public void sendComment (CommentMessage commentMessage) {
sendCommentRequestUseCase.execute(commentMessage);
public CreateCommentResponseDto sendComment (CommentMessage commentMessage) {
return sendCommentRequestUseCase.execute(commentMessage);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.daon.onjung.suggestion.application.controller.producer;

import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.application.usecase.SendLikeRequestUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -11,8 +12,8 @@ public class LikeV1Producer {

private final SendLikeRequestUseCase sendLikeRequestUseCase;

public void sendLike (LikeMessage likeMessage) {
sendLikeRequestUseCase.execute(likeMessage);
public CreateOrDeleteLikeResponseDto sendLike (LikeMessage likeMessage) {
return sendLikeRequestUseCase.execute(likeMessage);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.daon.onjung.suggestion.application.dto.response;

import com.daon.onjung.account.domain.User;
import com.daon.onjung.core.dto.SelfValidating;
import com.daon.onjung.core.utility.DateTimeUtil;
import com.daon.onjung.suggestion.domain.Comment;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;

@Getter
public class CreateCommentResponseDto extends SelfValidating<CreateCommentResponseDto> {

@JsonProperty("writer_info")
private final WriterInfoDto writerInfo;

@JsonProperty("comment_info")
private final CommentInfoDto commentInfo;

@Builder
public CreateCommentResponseDto(WriterInfoDto writerInfo, CommentInfoDto commentInfo) {
this.writerInfo = writerInfo;
this.commentInfo = commentInfo;

this.validateSelf();
}

@Getter
public static class WriterInfoDto extends SelfValidating<WriterInfoDto> {

@JsonProperty("profile_img_url")
private final String profileImgUrl;

@JsonProperty("masked_nickname")
private final String maskedNickname;

@JsonProperty("is_me")
private final Boolean isMe;

@Builder
public WriterInfoDto(String profileImgUrl, String maskedNickname, Boolean isMe) {
this.profileImgUrl = profileImgUrl;
this.maskedNickname = maskedNickname;
this.isMe = isMe;

this.validateSelf();
}

public static WriterInfoDto of(User user, Boolean isMe) {
String nickname = user.getNickName();
String maskedNickname;

if (nickname.length() == 1) {
maskedNickname = nickname;
} else if (nickname.length() == 2) {
maskedNickname = nickname.charAt(0) + "*";
} else {
String firstChar = nickname.substring(0, 1);
String lastChar = nickname.substring(nickname.length() - 1);
String middleMask = "*".repeat(nickname.length() - 2);
maskedNickname = firstChar + middleMask + lastChar;
}

return WriterInfoDto.builder()
.maskedNickname(maskedNickname)
.profileImgUrl(user.getProfileImgUrl())
.isMe(isMe)
.build();
}
}

@Getter
public static class CommentInfoDto extends SelfValidating<CommentInfoDto> {

@JsonProperty("id")
private final Long id;

@JsonProperty("content")
private final String content;

@JsonProperty("posted_at")
private final String postedAt;

@Builder
public CommentInfoDto(Long id, String content, String postedAt) {
this.id = id;
this.content = content;
this.postedAt = postedAt;

this.validateSelf();
}

public static CommentInfoDto fromEntity(Comment comment) {
return CommentInfoDto.builder()
.id(comment.getId())
.content(comment.getContent())
.postedAt(DateTimeUtil.calculatePostedAgo(comment.getCreatedAt()))
.build();
}
}

public static CreateCommentResponseDto of(User user, Boolean isMe, Comment comment) {
return CreateCommentResponseDto.builder()
.writerInfo(WriterInfoDto.of(user, isMe))
.commentInfo(CommentInfoDto.fromEntity(comment))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.daon.onjung.suggestion.application.dto.response;

import com.daon.onjung.core.dto.SelfValidating;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Builder;
import lombok.Getter;

@Getter
public class CreateOrDeleteLikeResponseDto extends SelfValidating<CreateOrDeleteLikeResponseDto> {

@JsonProperty("is_like")
private final Boolean isLike;

@Builder
public CreateOrDeleteLikeResponseDto(Boolean isLike) {
this.isLike = isLike;

this.validateSelf();
}

public static CreateOrDeleteLikeResponseDto of(Boolean isLike) {
return CreateOrDeleteLikeResponseDto.builder()
.isLike(isLike)
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.daon.onjung.suggestion.application.controller.producer.CommentV1Producer;
import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.request.CreateCommentRequestDto;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.application.usecase.CreateCommentUseCase;
import com.daon.onjung.suggestion.domain.Board;
import com.daon.onjung.suggestion.repository.mysql.BoardRepository;
Expand All @@ -27,7 +28,7 @@ public class CreateCommentService implements CreateCommentUseCase {

@Override
@Transactional
public void execute(UUID accountId, Long boardId, CreateCommentRequestDto requestDto) {
public CreateCommentResponseDto execute(UUID accountId, Long boardId, CreateCommentRequestDto requestDto) {

// ์œ ์ € ์กฐํšŒ
User user = userRepository.findById(accountId)
Expand All @@ -38,7 +39,7 @@ public void execute(UUID accountId, Long boardId, CreateCommentRequestDto reques
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE));

// ๋Œ“๊ธ€ ์ƒ์„ฑ ์š”์ฒญ ๋ฐœ์†ก
commentProducer.sendComment(CommentMessage.builder()
return commentProducer.sendComment(CommentMessage.builder()
.content(requestDto.content())
.userId(user.getId())
.boardId(board.getId())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.daon.onjung.suggestion.application.controller.producer.LikeV1Producer;
import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.application.usecase.CreateOrDeleteLikeUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -17,9 +18,9 @@ public class CreateOrDeleteLikeService implements CreateOrDeleteLikeUseCase {

@Override
@Transactional
public void execute(UUID accountId, Long boardId) {
public CreateOrDeleteLikeResponseDto execute(UUID accountId, Long boardId) {

likeProducer.sendLike(LikeMessage.builder()
return likeProducer.sendLike(LikeMessage.builder()
.boardId(boardId)
.userId(accountId)
.build());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.daon.onjung.suggestion.application.service;

import com.daon.onjung.suggestion.application.dto.request.CommentMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateCommentResponseDto;
import com.daon.onjung.suggestion.application.usecase.SendCommentRequestUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
Expand All @@ -13,12 +14,11 @@ public class SendCommentRequestService implements SendCommentRequestUseCase {
private final RabbitTemplate rabbitTemplate;

@Override
public void execute(CommentMessage commentMessage) {

public CreateCommentResponseDto execute(CommentMessage commentMessage) {
// ๋ชจ๋“ˆ๋Ÿฌ ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ Queue ๋ถ„๋ฆฌ. boardId๊ฐ€ ์ง์ˆ˜์ธ๊ฒฝ์šฐ board.0์„ ํ†ตํ•ด Queue2๋กœ ๋ผ์šฐํŒ…
// ํ™€์ˆ˜์ธ๊ฒฝ์šฐ board.1์„ ํ†ตํ•ด Queue 1 ๋กœ ๋ผ์šฐํŒ…
// Comment์˜ ๊ฒฝ์šฐ, ํ•˜๋‚˜์˜ ๊ฒŒ์‹œ๋ฌผ์— ๋Œ€ํ•ด ์ˆœ์„œ๊ฐ€ ๋ณด์žฅ๋˜์–ด์•ผ ํ•˜๋ฏ€๋กœ, routingKey๋ฅผ ์ด์šฉํ•ด boardId๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ผ์šฐํŒ…
String routingKey = "board." + (commentMessage.boardId() % 2);
rabbitTemplate.convertAndSend("board-exchange", routingKey, commentMessage);
return (CreateCommentResponseDto) rabbitTemplate.convertSendAndReceive("board-exchange", routingKey, commentMessage);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.daon.onjung.suggestion.application.service;

import com.daon.onjung.suggestion.application.dto.request.LikeMessage;
import com.daon.onjung.suggestion.application.dto.response.CreateOrDeleteLikeResponseDto;
import com.daon.onjung.suggestion.application.usecase.SendLikeRequestUseCase;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
Expand All @@ -13,7 +14,9 @@ public class SendLikeRequestService implements SendLikeRequestUseCase {
private final RabbitTemplate rabbitTemplate;

@Override
public void execute(LikeMessage likeMessage) {
rabbitTemplate.convertAndSend("like-queue", likeMessage);
public CreateOrDeleteLikeResponseDto execute(LikeMessage likeMessage) {

Boolean response = (Boolean) rabbitTemplate.convertSendAndReceive("like-queue", likeMessage);
return CreateOrDeleteLikeResponseDto.of(response);
}
}
Loading

0 comments on commit 97890ff

Please sign in to comment.