Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 수정, 삭제 분산락 적용 #152

Merged
merged 7 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import allchive.server.api.archiving.model.dto.response.ArchivingsResponse;
import allchive.server.api.archiving.service.*;
import allchive.server.api.common.slice.SliceResponse;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.domain.domains.archiving.domain.enums.Category;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -118,13 +119,15 @@ public ArchivingContentsResponse getArchivingContents(
@PatchMapping(value = "/{archivingId}/scrap")
public void updateArchivingScrap(
@RequestParam("cancel") Boolean cancel, @PathVariable("archivingId") Long archivingId) {
updateArchivingScrapUseCase.execute(archivingId, cancel);
Long userId = SecurityUtil.getCurrentUserId();
updateArchivingScrapUseCase.execute(archivingId, cancel, userId);
}

@Operation(summary = "아카이빙을 고정합니다.", description = "고정 취소면 cancel에 true 값 보내주세요")
@PatchMapping(value = "/{archivingId}/pin")
public void updateArchivingPin(
@RequestParam("cancel") Boolean cancel, @PathVariable("archivingId") Long archivingId) {
updateArchivingPinUseCase.execute(archivingId, cancel);
Long userId = SecurityUtil.getCurrentUserId();
updateArchivingPinUseCase.execute(archivingId, cancel, userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.mapper.RecycleMapper;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.recycle.domain.Recycle;
Expand All @@ -20,6 +22,7 @@ public class DeleteArchivingUseCase {
private final RecycleDomainService recycleDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.ARCHIVING, identifier ={"archivingId"})
public void execute(Long archivingId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(archivingId, userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import lombok.RequiredArgsConstructor;
Expand All @@ -15,8 +17,8 @@ public class UpdateArchivingPinUseCase {
private final ArchivingDomainService archivingDomainService;

@Transactional
public void execute(Long archivingId, Boolean cancel) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.ARCHIVING_PIN, identifier ={"archivingId", "userId"})
public void execute(Long archivingId, Boolean cancel, Long userId) {
validateExecution(archivingId, userId, cancel);
archivingDomainService.updatePin(archivingId, userId, !cancel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
Expand All @@ -25,8 +27,8 @@ public class UpdateArchivingScrapUseCase {
private final ScrapValidator scrapValidator;

@Transactional
public void execute(Long archivingId, Boolean cancel) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.ARCHIVING_SCRAP, identifier ={"archivingId", "userId"})
public void execute(Long archivingId, Boolean cancel, Long userId) {
validateExecution(archivingId, userId, cancel);
User user = userAdaptor.findById(userId);
if (cancel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.common.util.UrlUtil;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
Expand All @@ -22,9 +24,9 @@ public class UpdateArchivingUseCase {
private final ArchivingDomainService archivingDomainService;
private final ArchivingAdaptor archivingAdaptor;
private final ArchivingValidator archivingValidator;
private final S3DeleteObjectService s3DeleteObjectService;

@Transactional
@DistributedLock(lockType = DistributedLockType.ARCHIVING, identifier ={"archivingId"})
public void execute(Long archivingId, UpdateArchivingRequest request) {
validateExecution(archivingId);
Archiving archiving = archivingAdaptor.findById(archivingId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import allchive.server.api.auth.service.LogOutUserUseCase;
import allchive.server.api.auth.service.TokenRefreshUseCase;
import allchive.server.api.auth.service.WithdrawUserUseCase;
import allchive.server.api.config.security.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
Expand All @@ -26,7 +27,8 @@ public class AuthController {
public void withDrawUser(
@RequestParam(required = false, name = "appleCode", value = "") String appleCode,
@RequestHeader(value = "referer", required = false) String referer) {
withdrawUserUseCase.execute(appleCode, referer);
Long userId = SecurityUtil.getCurrentUserId();
withdrawUserUseCase.execute(appleCode, referer, userId);
}

@Operation(summary = "회원탈퇴를 합니다. (개발용)", deprecated = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.core.error.exception.InvalidOauthProviderException;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
import allchive.server.domain.domains.archiving.domain.Archiving;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
Expand Down Expand Up @@ -47,8 +49,8 @@ public class WithdrawUserUseCase {
private final ArchivingDomainService archivingDomainService;

@Transactional
public void execute(String appleAccessToken, String referer) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.USER, identifier ={"userId"})
public void execute(String appleAccessToken, String referer, Long userId) {
User user = userAdaptor.findById(userId);
// oauth쪽 탈퇴
withdrawOauth(user.getOauthInfo().getProvider(), appleAccessToken, user, referer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import allchive.server.api.block.service.CreateBlockUseCase;
import allchive.server.api.block.service.DeleteBlockUseCase;
import allchive.server.api.block.service.GetBlockUseCase;
import allchive.server.api.config.security.SecurityUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
Expand All @@ -32,7 +33,8 @@ public BlockResponse createBlock(@RequestBody BlockRequest blockRequest) {
@Operation(summary = "유저 차단을 해제합니다.")
@DeleteMapping()
public BlockResponse deleteBlock(@RequestBody BlockRequest blockRequest) {
return deleteBlockUseCase.execute(blockRequest);
Long userId = SecurityUtil.getCurrentUserId();
return deleteBlockUseCase.execute(blockRequest, userId, blockRequest.getUserId());
}

@Operation(summary = "차단한 유저 정보를 가져옵니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.block.model.dto.response.BlockResponse;
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.block.service.BlockDomainService;
import allchive.server.domain.domains.block.validator.BlockValidator;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
Expand All @@ -21,7 +23,8 @@ public class DeleteBlockUseCase {
private final UserAdaptor userAdaptor;

@Transactional
public BlockResponse execute(BlockRequest request) {
@DistributedLock(lockType = DistributedLockType.BLOCK, identifier ={"fromUserId, toUserId"})
public BlockResponse execute(BlockRequest request, Long fromUserId, Long toUserId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(userId, request);
blockDomainService.deleteByBlockFromAndBlockUser(userId, request.getUserId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.mapper.RecycleMapper;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingAsyncDomainService;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
import allchive.server.domain.domains.content.domain.Content;
Expand All @@ -27,6 +29,7 @@ public class DeleteContentUseCase {
private final ArchivingAsyncDomainService archivingAsyncDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.CONTENT, identifier ={"contentId"})
public void execute(Long contentId) {
Long userId = SecurityUtil.getCurrentUserId();
validateExecution(contentId, userId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingAsyncDomainService;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
import allchive.server.domain.domains.content.adaptor.ContentTagGroupAdaptor;
Expand Down Expand Up @@ -42,6 +44,7 @@ public class UpdateContentUseCase {
private final ArchivingAsyncDomainService archivingAsyncDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.CONTENT, identifier ={"contentId"})
public void execute(Long contentId, UpdateContentRequest request) {
validateExecution(contentId, request);
regenerateContentTagGroup(contentId, request.getTagIds());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allchive.server.api.recycle.controller;


import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.dto.request.ClearDeletedObjectRequest;
import allchive.server.api.recycle.model.dto.request.RestoreDeletedObjectRequest;
import allchive.server.api.recycle.model.dto.response.DeletedObjectResponse;
Expand All @@ -13,6 +14,9 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/recycles")
@RequiredArgsConstructor
Expand All @@ -26,7 +30,8 @@ public class RecycleController {
@Operation(summary = "삭제된 아카이빙, 컨텐츠를 복구합니다.")
@PatchMapping()
public void restoreDeletedObject(@RequestBody RestoreDeletedObjectRequest request) {
restoreDeletedObjectUseCase.execute(request);
Long userId = SecurityUtil.getCurrentUserId();
restoreDeletedObjectUseCase.execute(request, userId);
}

@Operation(summary = "삭제된 아카이빙, 컨텐츠를 가져옵니다.")
Expand All @@ -38,6 +43,7 @@ public DeletedObjectResponse getDeletedObject() {
@Operation(summary = "삭제된 아카이빙, 컨텐츠를 영구적으로 삭제합니다.")
@DeleteMapping()
public void clearDeletedObject(@RequestBody ClearDeletedObjectRequest request) {
clearDeletedObjectUseCase.execute(request);
Long userId = SecurityUtil.getCurrentUserId();
clearDeletedObjectUseCase.execute(request, userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.adaptor.ArchivingAdaptor;
import allchive.server.domain.domains.archiving.domain.Archiving;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
Expand Down Expand Up @@ -44,8 +46,8 @@ public class ClearDeletedObjectUseCase {
private final ArchivingAdaptor archivingAdaptor;

@Transactional
public void execute(ClearDeletedObjectRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.RECYCLE, identifier ={"userId"})
public void execute(ClearDeletedObjectRequest request, Long userId) {
validateExecution(userId, request);
List<Content> contents = contentAdaptor.findAllByArchivingIds(request.getArchivingIds());
List<Long> contentsId = getContentsId(contents, request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.recycle.model.dto.request.RestoreDeletedObjectRequest;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.archiving.service.ArchivingDomainService;
import allchive.server.domain.domains.archiving.validator.ArchivingValidator;
import allchive.server.domain.domains.content.adaptor.ContentAdaptor;
Expand All @@ -28,8 +30,8 @@ public class RestoreDeletedObjectUseCase {
private final ContentAdaptor contentAdaptor;

@Transactional
public void execute(RestoreDeletedObjectRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.RECYCLE, identifier ={"userId"})
public void execute(RestoreDeletedObjectRequest request, Long userId) {
validateExecution(request, userId);
archivingDomainService.restoreByIdIn(request.getArchivingIds());
contentDomainService.restoreByIdIn(request.getContentIds());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

import allchive.server.api.config.security.SecurityUtil;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.content.adaptor.TagAdaptor;
import allchive.server.domain.domains.content.domain.Tag;
import allchive.server.domain.domains.content.service.ContentTagGroupDomainService;
Expand All @@ -20,6 +22,7 @@ public class DeleteTagUseCase {
private final TagDomainService tagDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.TAG, identifier ={"tagId"})
public void execute(Long tagId) {
validateExecution(tagId);
Tag tag = tagAdaptor.findById(tagId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.tag.model.dto.request.UpdateTagRequest;
import allchive.server.core.annotation.UseCase;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.content.service.TagDomainService;
import allchive.server.domain.domains.content.validator.TagValidator;
import lombok.RequiredArgsConstructor;
Expand All @@ -16,6 +18,7 @@ public class UpdateTagUseCase {
private final TagDomainService tagDomainService;

@Transactional
@DistributedLock(lockType = DistributedLockType.TAG, identifier ={"tagId"})
public void execute(Long tagId, UpdateTagRequest request) {
validateExecution(tagId);
tagDomainService.updateTag(tagId, request.getName());
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package allchive.server.api.user.controller;


import allchive.server.api.config.security.SecurityUtil;
import allchive.server.api.user.model.dto.request.CheckUserNicknameRequest;
import allchive.server.api.user.model.dto.request.UpdateUserInfoRequest;
import allchive.server.api.user.model.dto.response.GetUserInfoResponse;
Expand Down Expand Up @@ -41,7 +42,8 @@ public GetUserInfoResponse getUserInfo() {
@Operation(summary = "내 정보를 수정합니다.")
@PostMapping(value = "/info")
public void getUserInfo(@RequestBody UpdateUserInfoRequest updateUserInfoRequest) {
updateUserInfoUseCase.execute(updateUserInfoRequest);
Long userId = SecurityUtil.getCurrentUserId();
updateUserInfoUseCase.execute(updateUserInfoRequest, userId);
}

@Operation(summary = "닉네임 중복체크합니다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import allchive.server.core.annotation.UseCase;
import allchive.server.core.event.Event;
import allchive.server.core.event.events.s3.S3ImageDeleteEvent;
import allchive.server.domain.common.aop.distributedLock.DistributedLock;
import allchive.server.domain.common.enums.DistributedLockType;
import allchive.server.domain.domains.user.adaptor.UserAdaptor;
import allchive.server.domain.domains.user.domain.User;
import allchive.server.domain.domains.user.service.UserDomainService;
Expand All @@ -25,8 +27,8 @@ public class UpdateUserInfoUseCase {
private final S3DeleteObjectService s3DeleteObjectService;

@Transactional
public void execute(UpdateUserInfoRequest request) {
Long userId = SecurityUtil.getCurrentUserId();
@DistributedLock(lockType = DistributedLockType.USER, identifier ={"userId"})
public void execute(UpdateUserInfoRequest request, Long userId) {
validateExecution(userId);
eliminateOldImage(userId, request.getImgUrl());
userDomainService.updateUserInfo(
Expand Down
7 changes: 7 additions & 0 deletions Core/src/main/java/allchive/server/core/CoreApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package allchive.server.core;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CoreApplication {
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public class AllchiveConst {
public static final String REFRESH_TOKEN = "REFRESH_TOKEN";

public static final String KID = "kid";
public static final String KR_YES = "예";
public static final String KR_NO = "아니요";

public static final String PROD = "prod";
public static final String DEV = "dev";
Expand Down Expand Up @@ -47,6 +45,10 @@ public class AllchiveConst {
public static final int MINUS_ONE = -1;
public static final int ZERO = 0;

public static final Long LOCK_WAIT_TIME = 5L;
public static final Long LOCK_LEASE_TIME = 3L;
public static final String REDISSON_LOCK_PREFIX = "LOCK:";

public static final int CORE_POOL_SIZE = 1;
public static final int MAX_POOL_SIZE = 30;
public static final int QUEUE_CAPACITY = 500;
Expand Down
Loading
Loading