Skip to content

Commit

Permalink
Style: ReviewVote 이름을 Vote 로 변경 (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
Seongjun-Kwon authored Sep 8, 2023
1 parent 5fe806d commit 1e26ce4
Show file tree
Hide file tree
Showing 16 changed files with 376 additions and 358 deletions.
2 changes: 1 addition & 1 deletion docker/sql/init.sql
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ CREATE TABLE IF NOT EXISTS `comment`
`deleted_at` TIMESTAMP NULL
);

CREATE TABLE IF NOT EXISTS `review_vote`
CREATE TABLE IF NOT EXISTS `vote`
(
`id` BIGINT AUTO_INCREMENT PRIMARY KEY,
`member_id` BIGINT NOT NULL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class RedisConstant {
public static final String USER_VIEWED_REVIEW_LOGS_NAME = "userViewedReviewLogs";
public static final String REVIEW_AND_VIEW_COUNT_LOGS_NAME = "reviewViewCountLogs";
public static final String VIEW_COUNT_LOCK = "viewCountLock";
public static final String REVIEW_VOTE_LOCK = "reviewVoteLock";
public static final String VOTE_LOCK = "voteLock";
public static final int LOCK_WAIT_TIME = 10;
public static final int LEASE_TIME = 5;
public static final String REVIEW_AND_VIEW_COUNT_LOGS_NAME_PATTERN = "reviewViewCountLogs*";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,52 +23,50 @@

import com.goodseats.seatviewreviews.common.security.Authority;
import com.goodseats.seatviewreviews.domain.member.model.dto.AuthenticationDTO;
import com.goodseats.seatviewreviews.domain.review.model.dto.request.ReviewVoteCreateRequest;
import com.goodseats.seatviewreviews.domain.review.model.dto.request.ReviewVotesGetRequest;
import com.goodseats.seatviewreviews.domain.review.model.dto.response.ReviewVotesResponse;
import com.goodseats.seatviewreviews.domain.review.service.ReviewVoteRedisFacade;
import com.goodseats.seatviewreviews.domain.review.service.ReviewVoteService;
import com.goodseats.seatviewreviews.domain.review.model.dto.request.VoteCreateRequest;
import com.goodseats.seatviewreviews.domain.review.model.dto.request.VotesGetRequest;
import com.goodseats.seatviewreviews.domain.review.model.dto.response.VotesResponse;
import com.goodseats.seatviewreviews.domain.review.service.VoteRedisFacade;
import com.goodseats.seatviewreviews.domain.review.service.VoteService;

import lombok.RequiredArgsConstructor;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/reviewvotes")
public class ReviewVoteController {
@RequestMapping("/api/v1/votes")
public class VoteController {

private final ReviewVoteService reviewVoteService;
private final ReviewVoteRedisFacade reviewVoteRedisFacade;
private final VoteService voteService;
private final VoteRedisFacade voteRedisFacade;

@Authority(authorities = {USER, ADMIN})
@PostMapping(produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Void> createVote(
@Valid @RequestBody ReviewVoteCreateRequest reviewVoteCreateRequest,
@Valid @RequestBody VoteCreateRequest voteCreateRequest,
@SessionAttribute(value = LOGIN_MEMBER_INFO) AuthenticationDTO authenticationDTO,
HttpServletRequest request
) {
Long voteId = reviewVoteRedisFacade.createVote(reviewVoteCreateRequest, authenticationDTO.memberId());
Long voteId = voteRedisFacade.createVote(voteCreateRequest, authenticationDTO.memberId());
return ResponseEntity.created(URI.create(request.getRequestURI() + "/" + voteId)).build();
}

@Authority(authorities = {USER, ADMIN})
@DeleteMapping("/{reviewVoteId}")
@DeleteMapping("/{voteId}")
ResponseEntity<Void> deleteVote(
@PathVariable Long reviewVoteId,
@PathVariable Long voteId,
@SessionAttribute(value = LOGIN_MEMBER_INFO) AuthenticationDTO authenticationDTO
) {
reviewVoteRedisFacade.deleteVote(reviewVoteId, authenticationDTO.memberId());
voteRedisFacade.deleteVote(voteId, authenticationDTO.memberId());
return ResponseEntity.noContent().build();
}

@GetMapping
ResponseEntity<ReviewVotesResponse> getVotes(
ResponseEntity<VotesResponse> getVotes(
@RequestParam Long reviewId,
@SessionAttribute(value = LOGIN_MEMBER_INFO, required = false) AuthenticationDTO authenticationDTO
) {
ReviewVotesGetRequest reviewVotesGetRequest = new ReviewVotesGetRequest(
reviewId, Optional.ofNullable(authenticationDTO)
);
ReviewVotesResponse reviewVotesResponse = reviewVoteService.getVotes(reviewVotesGetRequest);
return ResponseEntity.ok(reviewVotesResponse);
VotesGetRequest votesGetRequest = new VotesGetRequest(reviewId, Optional.ofNullable(authenticationDTO));
VotesResponse votesResponse = voteService.getVotes(votesGetRequest);
return ResponseEntity.ok(votesResponse);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.goodseats.seatviewreviews.domain.review.mapper;

import com.goodseats.seatviewreviews.domain.member.model.entity.Member;
import com.goodseats.seatviewreviews.domain.review.model.dto.response.VotesResponse;
import com.goodseats.seatviewreviews.domain.review.model.entity.Review;
import com.goodseats.seatviewreviews.domain.review.model.entity.Vote;
import com.goodseats.seatviewreviews.domain.review.model.vo.VoteChoice;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class VoteMapper {

public static Vote toEntity(Member member, Review review, VoteChoice voteChoice) {
return new Vote(voteChoice, member, review);
}

public static VotesResponse toClickedVotesResponse(Review review, Vote vote) {
return new VotesResponse(review.getLikeCount(), review.getDislikeCount(), vote.isLike(), vote.isDislike());
}

public static VotesResponse toNotClickedVotesResponse(Review review) {
return new VotesResponse(review.getLikeCount(), review.getDislikeCount(), false, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import com.goodseats.seatviewreviews.domain.review.model.vo.VoteChoice;

public record ReviewVoteCreateRequest(
public record VoteCreateRequest(
@NotNull Long reviewId,
@NotNull VoteChoice voteChoice
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

import com.goodseats.seatviewreviews.domain.member.model.dto.AuthenticationDTO;

public record ReviewVotesGetRequest(Long reviewId, Optional<AuthenticationDTO> authenticationDTO) {
public record VotesGetRequest(Long reviewId, Optional<AuthenticationDTO> authenticationDTO) {
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.goodseats.seatviewreviews.domain.review.model.dto.response;

public record ReviewVotesResponse(
public record VotesResponse(
int likeCount,
int dislikeCount,
boolean clickLike,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
import lombok.NoArgsConstructor;

@Entity
@Table(name = "review_vote")
@Table(name = "vote")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class ReviewVote extends BaseEntity {
public class Vote extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand All @@ -46,7 +46,7 @@ public class ReviewVote extends BaseEntity {
@JoinColumn(name = "review_id")
private Review review;

public ReviewVote(VoteChoice voteChoice, Member member, Review review) {
public Vote(VoteChoice voteChoice, Member member, Review review) {
this.voteChoice = voteChoice;
this.member = member;
this.review = review;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

import com.goodseats.seatviewreviews.domain.member.model.entity.Member;
import com.goodseats.seatviewreviews.domain.review.model.entity.Review;
import com.goodseats.seatviewreviews.domain.review.model.entity.ReviewVote;
import com.goodseats.seatviewreviews.domain.review.model.entity.Vote;
import com.goodseats.seatviewreviews.domain.review.model.vo.VoteChoice;

public interface ReviewVoteRepository extends JpaRepository<ReviewVote, Long> {
public interface VoteRepository extends JpaRepository<Vote, Long> {

boolean existsByMemberAndReview(Member member, Review review);

Optional<ReviewVote> findReviewVoteByMemberAndReview(Member member, Review review);
Optional<Vote> findVoteByMemberAndReview(Member member, Review review);

@Query("SELECT COUNT(*) FROM ReviewVote rv WHERE rv.review.id = :reviewId AND rv.voteChoice = :voteChoice")
@Query("SELECT COUNT(*) FROM Vote v WHERE v.review.id = :reviewId AND v.voteChoice = :voteChoice")
int getVoteCount(@Param("reviewId") Long reviewId, @Param("voteChoice") VoteChoice voteChoice);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.goodseats.seatviewreviews.domain.review.service;

import static com.goodseats.seatviewreviews.common.constant.RedisConstant.*;

import java.util.concurrent.TimeUnit;

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import com.goodseats.seatviewreviews.domain.review.model.dto.request.VoteCreateRequest;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class VoteRedisFacade {

private final RedissonClient redissonClient;
private final VoteService voteService;

public Long createVote(VoteCreateRequest voteCreateRequest, Long memberId) {
RLock voteLock = redissonClient.getLock(VOTE_LOCK + voteCreateRequest.reviewId());

try {
tryLock(voteLock);
return voteService.createVote(voteCreateRequest, memberId);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (voteLock.isHeldByCurrentThread()) {
voteLock.unlock();
}
}
}

public void deleteVote(Long voteId, Long memberId) {
RLock voteLock = redissonClient.getLock(VOTE_LOCK + voteId);

try {
tryLock(voteLock);
voteService.deleteVote(voteId, memberId);
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
if (voteLock.isHeldByCurrentThread()) {
voteLock.unlock();
}
}
}

private void tryLock(RLock voteLock) throws InterruptedException {
boolean available = voteLock.tryLock(LOCK_WAIT_TIME, LEASE_TIME, TimeUnit.SECONDS);

if (!available) {
throw new InterruptedException();
}
}
}
Loading

0 comments on commit 1e26ce4

Please sign in to comment.