-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
π BugFix - RabbitMQμ Optimistic Lockμ μ΄μ©ν λμμ± λ¬Έμ ν΄κ²° (#176)
* π BugFix/#175 - add: RabbitMQ μμ‘΄μ± μΆκ° * π BugFix/#175 - feat: RabbitMQConfig ꡬν * π BugFix/#175 - refactor: Optimistic Lock μ μ© * π BugFix/#175 - feat: comment μμ± μ λμμ± λ¬Έμ ν΄κ²° * π BugFix/#175 - feat: like μμ± μ λμμ± λ¬Έμ ν΄κ²°
- Loading branch information
1 parent
4664556
commit bb5fe1b
Showing
18 changed files
with
369 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
src/main/java/com/daon/onjung/core/config/RabbitMQConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.daon.onjung.core.config; | ||
|
||
import org.springframework.amqp.core.Binding; | ||
import org.springframework.amqp.core.BindingBuilder; | ||
import org.springframework.amqp.core.DirectExchange; | ||
import org.springframework.amqp.core.Queue; | ||
import org.springframework.amqp.rabbit.annotation.EnableRabbit; | ||
import org.springframework.amqp.rabbit.connection.ConnectionFactory; | ||
import org.springframework.amqp.rabbit.core.RabbitTemplate; | ||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
|
||
@Configuration | ||
@EnableRabbit | ||
public class RabbitMQConfig { | ||
|
||
@Bean | ||
public DirectExchange boardExchange() { | ||
return new DirectExchange("board-exchange"); | ||
} | ||
|
||
@Bean | ||
public Queue likeQueue() { | ||
return new Queue("like-queue", true); | ||
} | ||
|
||
@Bean | ||
public Queue commentQueue1() { | ||
return new Queue("comment-queue-1", true); | ||
} | ||
|
||
@Bean Queue commentQueue2() { | ||
return new Queue("comment-queue-2", true); | ||
} | ||
|
||
@Bean | ||
public Binding boardQueue1Binding(DirectExchange boardExchange, Queue commentQueue1) { | ||
return BindingBuilder.bind(commentQueue1).to(boardExchange).with("board.1"); | ||
} | ||
|
||
@Bean | ||
public Binding boardQueue2Binding(DirectExchange boardExchange, Queue commentQueue2) { | ||
return BindingBuilder.bind(commentQueue2).to(boardExchange).with("board.0"); | ||
} | ||
|
||
@Bean | ||
public Jackson2JsonMessageConverter jsonMessageConverter() { | ||
return new Jackson2JsonMessageConverter(); | ||
} | ||
|
||
@Bean | ||
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { | ||
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); | ||
rabbitTemplate.setMessageConverter(jsonMessageConverter()); // JSON 컨λ²ν° μ€μ | ||
return rabbitTemplate; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
...in/java/com/daon/onjung/suggestion/application/controller/consumer/CommentV1Consumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
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.CommentMessage; | ||
import com.daon.onjung.suggestion.domain.Board; | ||
import com.daon.onjung.suggestion.domain.Comment; | ||
import com.daon.onjung.suggestion.domain.service.BoardService; | ||
import com.daon.onjung.suggestion.domain.service.CommentService; | ||
import com.daon.onjung.suggestion.repository.mysql.BoardRepository; | ||
import com.daon.onjung.suggestion.repository.mysql.CommentRepository; | ||
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 CommentV1Consumer { | ||
|
||
private final BoardRepository boardRepository; | ||
private final CommentRepository commentRepository; | ||
private final UserRepository userRepository; | ||
|
||
private final CommentService commentService; | ||
private final BoardService boardService; | ||
|
||
@Transactional | ||
@RabbitListener(queues = "comment-queue-1") | ||
public void processCommentMessage1(CommentMessage commentMessage) { | ||
try { | ||
|
||
// κ²μκΈ μ‘°ν | ||
Board board = boardRepository.findById(commentMessage.boardId()) | ||
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); | ||
|
||
// μ μ μ‘°ν | ||
User user = userRepository.findById(commentMessage.userId()) | ||
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); | ||
|
||
// λκΈ μμ± | ||
Comment comment = commentService.createComment( | ||
commentMessage.content(), | ||
user, | ||
board | ||
); | ||
commentRepository.save(comment); | ||
|
||
// κ²μκΈ λκΈ μ μ¦κ° | ||
board = boardService.addCommentCount(board); | ||
boardRepository.save(board); | ||
} catch (OptimisticEntityLockException e) { | ||
throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION); | ||
} | ||
} | ||
|
||
@Transactional | ||
@RabbitListener(queues = "comment-queue-2") | ||
public void processCommentMessage2(CommentMessage commentMessage) { | ||
try { | ||
|
||
// κ²μκΈ μ‘°ν | ||
Board board = boardRepository.findById(commentMessage.boardId()) | ||
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); | ||
|
||
// μ μ μ‘°ν | ||
User user = userRepository.findById(commentMessage.userId()) | ||
.orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_RESOURCE)); | ||
|
||
// λκΈ μμ± | ||
Comment comment = commentService.createComment( | ||
commentMessage.content(), | ||
user, | ||
board | ||
); | ||
commentRepository.save(comment); | ||
|
||
// κ²μκΈ λκΈ μ μ¦κ° | ||
board = boardService.addCommentCount(board); | ||
boardRepository.save(board); | ||
} catch (OptimisticEntityLockException e) { | ||
throw new CommonException(ErrorCode.OPTIMISTIC_EXCEPTION); | ||
} | ||
} | ||
|
||
|
||
} |
69 changes: 69 additions & 0 deletions
69
src/main/java/com/daon/onjung/suggestion/application/controller/consumer/LikeV1Consumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
...in/java/com/daon/onjung/suggestion/application/controller/producer/CommentV1Producer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.daon.onjung.suggestion.application.controller.producer; | ||
|
||
import com.daon.onjung.suggestion.application.dto.request.CommentMessage; | ||
import com.daon.onjung.suggestion.application.usecase.SendCommentRequestUseCase; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class CommentV1Producer { | ||
|
||
private final SendCommentRequestUseCase sendCommentRequestUseCase; | ||
|
||
public void sendComment (CommentMessage commentMessage) { | ||
sendCommentRequestUseCase.execute(commentMessage); | ||
} | ||
|
||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/com/daon/onjung/suggestion/application/controller/producer/LikeV1Producer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/com/daon/onjung/suggestion/application/dto/request/CommentMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.daon.onjung.suggestion.application.dto.request; | ||
|
||
import lombok.Builder; | ||
|
||
import java.util.UUID; | ||
|
||
@Builder | ||
public record CommentMessage( | ||
String content, | ||
Long boardId, | ||
UUID userId | ||
) { | ||
} |
12 changes: 12 additions & 0 deletions
12
src/main/java/com/daon/onjung/suggestion/application/dto/request/LikeMessage.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
) { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.