diff --git a/src/main/java/com/daon/onjung/suggestion/application/controller/command/SuggestionCommandV1Controller.java b/src/main/java/com/daon/onjung/suggestion/application/controller/command/SuggestionCommandV1Controller.java index 1d67e51..933b997 100644 --- a/src/main/java/com/daon/onjung/suggestion/application/controller/command/SuggestionCommandV1Controller.java +++ b/src/main/java/com/daon/onjung/suggestion/application/controller/command/SuggestionCommandV1Controller.java @@ -48,10 +48,7 @@ public ResponseDto likeBoard( @AccountID UUID accountId, @PathVariable Long id ) { - if (createOrDeleteLikeUseCase.execute(accountId, id)) { - return ResponseDto.created(null); - } else { - return ResponseDto.ok(null); - } + createOrDeleteLikeUseCase.execute(accountId, id); + return ResponseDto.ok(null); } } diff --git a/src/main/java/com/daon/onjung/suggestion/application/controller/consumer/LikeV1Consumer.java b/src/main/java/com/daon/onjung/suggestion/application/controller/consumer/LikeV1Consumer.java new file mode 100644 index 0000000..e4a278d --- /dev/null +++ b/src/main/java/com/daon/onjung/suggestion/application/controller/consumer/LikeV1Consumer.java @@ -0,0 +1,69 @@ +package com.daon.onjung.suggestion.application.controller.consumer; + +import com.daon.onjung.account.domain.User; +import com.daon.onjung.account.repository.mysql.UserRepository; +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.domain.Board; +import com.daon.onjung.suggestion.domain.Like; +import com.daon.onjung.suggestion.domain.service.BoardService; +import com.daon.onjung.suggestion.domain.service.LikeService; +import com.daon.onjung.suggestion.repository.mysql.BoardRepository; +import com.daon.onjung.suggestion.repository.mysql.LikeRepository; +import lombok.RequiredArgsConstructor; +import org.hibernate.dialect.lock.OptimisticEntityLockException; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class LikeV1Consumer { + + private final LikeRepository likeRepository; + private final BoardRepository boardRepository; + private final UserRepository userRepository; + + private final LikeService likeService; + private final BoardService boardService; + + @Transactional + @RabbitListener(queues = "like-queue") + public void processLikeMessage(LikeMessage likeMessage) { + try { + + // 게시글 조회 + Board board = boardRepository.findById(likeMessage.boardId()) + .orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); + + // 유저 조회 + User user = userRepository.findById(likeMessage.userId()) + .orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); + + // 좋아요가 존재하는지 확인 + Like like = likeRepository.findByBoardAndUser(board, user) + .orElse(null); + + if (like != null) { + + // 좋아요가 이미 존재하면 삭제 + likeRepository.delete(like); + // 게시글 좋아요 수 감소 + board = boardService.subtractLikeCount(board); + boardRepository.save(board); + } else { + + // 좋아요가 존재하지 않으면 생성 + likeRepository.save(likeService.createLike(user, board)); + + // 게시글 좋아요 수 증가 + board = boardService.addLikeCount(board); + boardRepository.save(board); + } + } catch (OptimisticEntityLockException e) { + throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION); + } + } + +} diff --git a/src/main/java/com/daon/onjung/suggestion/application/controller/producer/LikeV1Producer.java b/src/main/java/com/daon/onjung/suggestion/application/controller/producer/LikeV1Producer.java new file mode 100644 index 0000000..2da27c5 --- /dev/null +++ b/src/main/java/com/daon/onjung/suggestion/application/controller/producer/LikeV1Producer.java @@ -0,0 +1,18 @@ +package com.daon.onjung.suggestion.application.controller.producer; + +import com.daon.onjung.suggestion.application.dto.request.LikeMessage; +import com.daon.onjung.suggestion.application.usecase.SendLikeRequestUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class LikeV1Producer { + + private final SendLikeRequestUseCase sendLikeRequestUseCase; + + public void sendLike (LikeMessage likeMessage) { + sendLikeRequestUseCase.execute(likeMessage); + } + +} diff --git a/src/main/java/com/daon/onjung/suggestion/application/dto/request/LikeMessage.java b/src/main/java/com/daon/onjung/suggestion/application/dto/request/LikeMessage.java new file mode 100644 index 0000000..8f96453 --- /dev/null +++ b/src/main/java/com/daon/onjung/suggestion/application/dto/request/LikeMessage.java @@ -0,0 +1,12 @@ +package com.daon.onjung.suggestion.application.dto.request; + +import lombok.Builder; + +import java.util.UUID; + +@Builder +public record LikeMessage( + Long boardId, + UUID userId +) { +} diff --git a/src/main/java/com/daon/onjung/suggestion/application/service/CreateOrDeleteLikeService.java b/src/main/java/com/daon/onjung/suggestion/application/service/CreateOrDeleteLikeService.java index 82e3350..6c0089d 100644 --- a/src/main/java/com/daon/onjung/suggestion/application/service/CreateOrDeleteLikeService.java +++ b/src/main/java/com/daon/onjung/suggestion/application/service/CreateOrDeleteLikeService.java @@ -1,16 +1,8 @@ package com.daon.onjung.suggestion.application.service; -import com.daon.onjung.account.domain.User; -import com.daon.onjung.account.repository.mysql.UserRepository; -import com.daon.onjung.core.exception.error.ErrorCode; -import com.daon.onjung.core.exception.type.CommonException; +import com.daon.onjung.suggestion.application.controller.producer.LikeV1Producer; +import com.daon.onjung.suggestion.application.dto.request.LikeMessage; import com.daon.onjung.suggestion.application.usecase.CreateOrDeleteLikeUseCase; -import com.daon.onjung.suggestion.domain.Board; -import com.daon.onjung.suggestion.domain.Like; -import com.daon.onjung.suggestion.domain.service.BoardService; -import com.daon.onjung.suggestion.domain.service.LikeService; -import com.daon.onjung.suggestion.repository.mysql.BoardRepository; -import com.daon.onjung.suggestion.repository.mysql.LikeRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -21,51 +13,16 @@ @RequiredArgsConstructor public class CreateOrDeleteLikeService implements CreateOrDeleteLikeUseCase { - private final BoardRepository boardRepository; - private final UserRepository userRepository; - private final LikeRepository likeRepository; - - private final BoardService boardService; - private final LikeService likeService; - + private final LikeV1Producer likeProducer; @Override @Transactional - public Boolean execute(UUID accountId, Long boardId) { - - // 유저 조회 - User user = userRepository.findById(accountId) - .orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); - - // 게시글 조회 - Board board = boardRepository.findById(boardId) - .orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); - - // 좋아요 여부 확인 - Like like = likeRepository.findByBoardAndUser(board, user) - .orElse(null); - - // 좋아요 생성 또는 삭제 - if (like != null) { - - // 좋아요가 이미 존재하면 삭제 - likeRepository.delete(like); - - // 게시글 좋아요 수 감소 - board = boardService.subtractLikeCount(board); - boardRepository.save(board); - - return false; - } else { - - // 좋아요가 존재하지 않으면 생성 - likeRepository.save(likeService.createLike(user,board)); + public void execute(UUID accountId, Long boardId) { - // 게시글 좋아요 수 증가 - board = boardService.addLikeCount(board); - boardRepository.save(board); + likeProducer.sendLike(LikeMessage.builder() + .boardId(boardId) + .userId(accountId) + .build()); - return true; - } } } diff --git a/src/main/java/com/daon/onjung/suggestion/application/service/SendLikeRequestService.java b/src/main/java/com/daon/onjung/suggestion/application/service/SendLikeRequestService.java new file mode 100644 index 0000000..7fea94b --- /dev/null +++ b/src/main/java/com/daon/onjung/suggestion/application/service/SendLikeRequestService.java @@ -0,0 +1,19 @@ +package com.daon.onjung.suggestion.application.service; + +import com.daon.onjung.suggestion.application.dto.request.LikeMessage; +import com.daon.onjung.suggestion.application.usecase.SendLikeRequestUseCase; +import lombok.RequiredArgsConstructor; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class SendLikeRequestService implements SendLikeRequestUseCase { + + private final RabbitTemplate rabbitTemplate; + + @Override + public void execute(LikeMessage likeMessage) { + rabbitTemplate.convertAndSend("like-queue", likeMessage); + } +} diff --git a/src/main/java/com/daon/onjung/suggestion/application/usecase/CreateOrDeleteLikeUseCase.java b/src/main/java/com/daon/onjung/suggestion/application/usecase/CreateOrDeleteLikeUseCase.java index dadff5f..17bdde5 100644 --- a/src/main/java/com/daon/onjung/suggestion/application/usecase/CreateOrDeleteLikeUseCase.java +++ b/src/main/java/com/daon/onjung/suggestion/application/usecase/CreateOrDeleteLikeUseCase.java @@ -7,5 +7,5 @@ @UseCase public interface CreateOrDeleteLikeUseCase { - Boolean execute(UUID accountId, Long boardId); + void execute(UUID accountId, Long boardId); } diff --git a/src/main/java/com/daon/onjung/suggestion/application/usecase/SendLikeRequestUseCase.java b/src/main/java/com/daon/onjung/suggestion/application/usecase/SendLikeRequestUseCase.java new file mode 100644 index 0000000..4742a64 --- /dev/null +++ b/src/main/java/com/daon/onjung/suggestion/application/usecase/SendLikeRequestUseCase.java @@ -0,0 +1,9 @@ +package com.daon.onjung.suggestion.application.usecase; + +import com.daon.onjung.core.annotation.bean.UseCase; +import com.daon.onjung.suggestion.application.dto.request.LikeMessage; + +@UseCase +public interface SendLikeRequestUseCase { + void execute(LikeMessage likeMessage); +}