Skip to content

Commit

Permalink
[feat] : Board 위치 수정 및 Redisson 분산락 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackBean99 committed Aug 31, 2023
1 parent f6cad8b commit 517b98f
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 57 deletions.
Binary file modified server/.gradle/7.6.1/executionHistory/executionHistory.bin
Binary file not shown.
Binary file modified server/.gradle/7.6.1/executionHistory/executionHistory.lock
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/fileHashes.bin
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/fileHashes.lock
Binary file not shown.
Binary file modified server/.gradle/7.6.1/fileHashes/resourceHashesCache.bin
Binary file not shown.
Binary file modified server/.gradle/buildOutputCleanup/buildOutputCleanup.lock
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.econovation.recruitcommon.consts.RecruitStatic.APPLICANT_SUCCESS_REGISTER_MESSAGE;

import com.econovation.recruit.api.applicant.docs.CreateApplicantExceptionDocs;
import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase;
import com.econovation.recruit.api.applicant.usecase.ApplicantRegisterUseCase;
import com.econovation.recruit.api.applicant.usecase.QuestionRegisterUseCase;
import com.econovation.recruit.api.applicant.usecase.TimeTableLoadUseCase;
Expand Down Expand Up @@ -36,6 +37,7 @@ public class ApplicantController {
private final TimeTableRegisterUseCase timeTableRegisterUseCase;
private final TimeTableLoadUseCase timeTableLoadUseCase;
private final QuestionRegisterUseCase questionRegisterUseCase;
private final AnswerLoadUseCase answerLoadUseCase;

@Operation(summary = "지원자가 지원서를 작성합니다.", description = "반환 값은 생성된 지원자의 ID입니다.")
@ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class)
Expand All @@ -45,6 +47,19 @@ public ResponseEntity registerApplicant(@RequestBody List<BlockRequestDto> block
return new ResponseEntity<>(applicantId, HttpStatus.OK);
}

@Operation(summary = "지원자 id로 지원서를 조회합니다.")
@GetMapping("/applicants/{applicant-id}")
public ResponseEntity<Map<String, String>> getApplicantById(
@PathVariable(value = "applicant-id") String applicantId) {
return new ResponseEntity<>(answerLoadUseCase.execute(applicantId), HttpStatus.OK);
}

@Operation(summary = "모든 지원자의 지원서를 조회합니다.")
@GetMapping("/applicants")
public ResponseEntity<List<Map<String, String>>> getApplicants() {
return new ResponseEntity<>(answerLoadUseCase.execute(), HttpStatus.OK);
}

@Operation(summary = "지원자가 면접 가능 시간을 작성합니다.")
@ApiErrorExceptionsExample(CreateApplicantExceptionDocs.class)
@PostMapping("/applicants/{applicant-id}/timetables")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
Expand Down Expand Up @@ -128,20 +127,7 @@ public ResponseEntity<String> createWorkBoard(
public ResponseEntity<String> updateLocationBoard(
@RequestBody UpdateLocationBoardDto updateLocationBoardDto) {
boardRecordUseCase.relocateCard(updateLocationBoardDto);
return new ResponseEntity(HttpStatus.OK);
}

@Operation(summary = "지원자 id로 지원서를 조회합니다.")
@GetMapping("/applicants/{applicant-id}")
public ResponseEntity<Map<String, String>> getApplicantById(
@PathVariable(value = "applicant-id") String applicantId) {
return new ResponseEntity<>(answerLoadUseCase.execute(applicantId), HttpStatus.OK);
}

@Operation(summary = "모든 지원자의 지원서를 조회합니다.")
@GetMapping("/applicants")
public ResponseEntity<List<Map<String, String>>> getApplicants() {
return new ResponseEntity<>(answerLoadUseCase.execute(), HttpStatus.OK);
return new ResponseEntity(BOARD_SUCCESS_LOCATION_CHANGE_MESSAGE, HttpStatus.OK);
}

@Operation(
Expand All @@ -153,11 +139,6 @@ public ResponseEntity<List<BoardCardResponseDto>> getBoardByNavigationId(
return new ResponseEntity<>(cardLoadUseCase.getByNavigationId(navigationId), HttpStatus.OK);
}

// @GetMapping("/boards/cards")
// public List<Card> getCardAll() {
// return new ArrayList<>(cardLoadUseCase.findAll());
// }

@Operation(summary = "카드 삭제", description = "카드를 삭제합니다")
@PostMapping("/boards/cards/{card-id}/delete")
public ResponseEntity<String> deleteCard(Long cardId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
import com.econovation.recruit.api.applicant.usecase.AnswerLoadUseCase;
import com.econovation.recruit.api.card.usecase.BoardLoadUseCase;
import com.econovation.recruit.api.card.usecase.BoardRegisterUseCase;
import com.econovation.recruitdomain.common.aop.redissonLock.RedissonLock;
import com.econovation.recruitdomain.domains.board.domain.Board;
import com.econovation.recruitdomain.domains.board.domain.BoardRepository;
import com.econovation.recruitdomain.domains.board.domain.CardType;
import com.econovation.recruitdomain.domains.board.domain.Columns;
import com.econovation.recruitdomain.domains.board.domain.Navigation;
import com.econovation.recruitdomain.domains.board.dto.ColumnsResponseDto;
import com.econovation.recruitdomain.domains.board.exception.BoardSameLocationException;
import com.econovation.recruitdomain.domains.board.exception.InvalidHopeFieldException;
import com.econovation.recruitdomain.domains.dto.UpdateLocationBoardDto;
import com.econovation.recruitdomain.out.BoardLoadPort;
Expand All @@ -19,6 +21,7 @@
import com.econovation.recruitdomain.out.ColumnRecordPort;
import com.econovation.recruitdomain.out.NavigationLoadPort;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessagingTemplate;
Expand Down Expand Up @@ -289,51 +292,38 @@ public List<ColumnsResponseDto> getColumnsByNavigationId(Integer navigationId) {

@Override
@Transactional
// @RedissonLock(LockName = "지원서",
// paramClassType = UpdateLocationBoardDto.class,
// identifier = "boardId",
// needSameTransaction = true)
@RedissonLock(
LockName = "보드 위치 변경",
identifier = "boardId",
paramClassType = UpdateLocationBoardDto.class)
public void relocateCard(UpdateLocationBoardDto updateLocationBoardDto) {
Board currentBoard = boardLoadPort.getBoardById(updateLocationBoardDto.getBoardId());
Board targetBoard = boardLoadPort.getBoardById(updateLocationBoardDto.getTargetBoardId());

// Update nextBoardId
// 같은 board 끼리는 위치 변경이 불가하다.
if (currentBoard.getId().equals(targetBoard.getId()))
throw BoardSameLocationException.EXCEPTION;

updateNextBoardIds(currentBoard, targetBoard);

// TODO: Send data to the socket server
// messagingTemplate.convertAndSend("/sub/boards/", boards);
}

private void updateNextBoardIds(Board board1, Board board2) {
Board board1Next = boardLoadPort.getByNextBoardId(board1.getId());
Board board2Next = boardLoadPort.getByNextBoardId(board2.getId());
Optional<Board> board1Prev = boardLoadPort.getByNextBoardId(board1.getId());
Optional<Board> board2Prev = boardLoadPort.getByNextBoardId(board2.getId());

// Update nextBoardId references
if (board2.getNextBoardId() != null) {
board2.updateNextBoardID(board1.getNextBoardId());
if (board1Prev.isPresent()) {
board1Prev.get().updateNextBoardID(board2.getId());
}

if (board1.getNextBoardId() != null) {
board1.updateNextBoardID(board2.getId());
if (board2Prev.isPresent()) {
board2Prev.get().updateNextBoardID(board1.getId());
}

if (board1Next != null && board2.getNextBoardId() != null) {
board1Next.updateNextBoardID(board2.getId());
}

if (board2Next != null && board1.getNextBoardId() != null) {
board2Next.updateNextBoardID(board1.getId());
}
}

/*
@Override
public boolean isDuplicateLocation(Integer navLoc, Integer columnId, Integer boardId) {
Map<String, Integer> location = new HashMap<>();
location.put("columnId", columnId);
location.put("boardId", boardId);
Board boardByLocation = boardLoadPort.getBoardByLocation(navLoc, colLoc, boardId);
return false;
Integer board2NextBoardId = board2.getNextBoardId();
Integer board1NextBoardId = board1.getNextBoardId();
board1.updateNextBoardID(board2NextBoardId);
board2.updateNextBoardID(board1NextBoardId);
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionPhase;
import org.springframework.transaction.event.TransactionalEventListener;
Expand All @@ -28,7 +29,7 @@ public class ApplicantRegisterEventHandler {
@TransactionalEventListener(
classes = ApplicantRegisterEvent.class,
phase = TransactionPhase.AFTER_COMMIT)
@Transactional
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void handle(ApplicantRegisterEvent applicantRegistEvent) {
String message = generateApplicantRegisterMessage(applicantRegistEvent);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public class RecruitStatic {
public static final String NO_MATCH_RECORD = "해당하는 RECORD가 존재하지 않습니다";
public static final String RECORD_SUCCESS_CREATE_MESSAGE = "성공적으로 지원자의 면접 기록이 생성됐습니다";
public static final String COLUMN_SUCCESS_REGISTER_MESSAGE = "성공적으로 Column이 등록됐습니다";
public static final String BOARD_SUCCESS_LOCATION_CHANGE_MESSAGE = "성공적으로 카드의 위치가 변경되었습니다.";
public static final List<Map.Entry<String, String>> SUBMIT_APPLICANT_EVENT_SEPERATOR_LIST =
new ArrayList<Map.Entry<String, String>>(
List.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,8 @@ public List<Board> getBoardByNavLoc(Integer navigationId) {
}

@Override
public Board getByNextBoardId(Integer nextBoardId) {
return boardRepository
.findByNextBoardId(nextBoardId)
.orElseThrow(() -> BoardNotFoundException.EXCEPTION);
public Optional<Board> getByNextBoardId(Integer nextBoardId) {
return boardRepository.findByNextBoardId(nextBoardId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public enum BoardErrorCode implements BaseErrorCode {
BOARD_INVALID_LOCATION(BAD_REQUEST, "BOARD_400_1", "유효하지 않은 위치입니다."),
INVALID_HOPE_FIELD(BAD_REQUEST, "BOARD_400_2", "유효하지 않은 희망 분야입니다."),
BOARD_NOT_FOUND(NOT_FOUND, "BOARD_400_3", "보드를 찾을 수 없습니다."),
BOARD_SAME_LOCATION(BAD_REQUEST, "BOARD_400_4", "같은 위치에 보드 사이는 수정이 불가합니다"),
;

private Integer status;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.econovation.recruitdomain.domains.board.exception;

import com.econovation.recruitcommon.exception.RecruitCodeException;

public class BoardSameLocationException extends RecruitCodeException {
public static final BoardSameLocationException EXCEPTION = new BoardSameLocationException();

private BoardSameLocationException() {
super(BoardErrorCode.BOARD_SAME_LOCATION);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.econovation.recruitdomain.domains.board.domain.Board;
import java.util.List;
import java.util.Optional;

public interface BoardLoadPort {
Board getBoardById(Integer id);
Expand All @@ -12,7 +13,7 @@ public interface BoardLoadPort {

List<Board> getBoardByNavLoc(Integer navLoc);

Board getByNextBoardId(Integer id);
Optional<Board> getByNextBoardId(Integer id);

List<Board> getBoardByColumnsIds(List<Integer> columnsIds);
}

0 comments on commit 517b98f

Please sign in to comment.