Skip to content

Commit

Permalink
Merge pull request #37 from f-lab-edu/refactoring/36
Browse files Browse the repository at this point in the history
[#36] JwtReader 서비스 계층에서 추출
  • Loading branch information
hyeok-kong authored Jun 21, 2024
2 parents 1bc92dc + 0bd4a6b commit 1b4386a
Show file tree
Hide file tree
Showing 11 changed files with 76 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.kong.commonlibrary.util.JwtReader;
import me.kong.groupservice.domain.entity.group.Group;
import me.kong.groupservice.dto.request.GroupJoinProcessDto;
import me.kong.groupservice.dto.request.GroupJoinRequestDto;
Expand Down Expand Up @@ -35,17 +36,18 @@ public class GroupController {
private final GroupMapper groupMapper;
private final GroupJoinRequestMapper requestMapper;
private final GroupJoinFacade groupJoinFacade;
private final JwtReader jwtReader;

@PostMapping
public ResponseEntity<GroupResponseDto> addGroup(@RequestBody @Valid SaveGroupRequestDto dto) {
Group group = groupService.createNewGroup(dto);
Group group = groupService.createNewGroup(dto, jwtReader.getUserId());

return ResponseEntity.ok(groupMapper.toDto(group));
}

@PostMapping("{groupId}")
public ResponseEntity<HttpStatus> joinGroup(@PathVariable Long groupId, @RequestBody @Valid GroupJoinRequestDto dto) {
groupJoinFacade.joinGroup(dto, groupId);
groupJoinFacade.joinGroup(dto, jwtReader.getUserId(), groupId);

return ResponseEntity.status(HttpStatus.OK).build();
}
Expand All @@ -54,7 +56,9 @@ public ResponseEntity<HttpStatus> joinGroup(@PathVariable Long groupId, @Request
public ResponseEntity<List<GroupJoinResponseDto>> getGroupRequests(
@PathVariable Long groupId,
@RequestParam(name = "status", defaultValue = "PENDING") JoinRequestSearchCondition condition) {
List<GroupJoinResponseDto> requests = requestMapper.toDtoList(joinRequestService.getGroupJoinRequestsByGroupIdAndCondition(groupId, condition));
List<GroupJoinResponseDto> requests =
requestMapper.toDtoList(joinRequestService
.getGroupJoinRequestsByGroupIdAndCondition(jwtReader.getUserId(), groupId, condition));

return new ResponseEntity<>(requests, HttpStatus.OK);
}
Expand All @@ -63,7 +67,7 @@ public ResponseEntity<List<GroupJoinResponseDto>> getGroupRequests(
public ResponseEntity<HttpStatus> handleGroupJoinRequest(@PathVariable Long groupId,
@PathVariable Long requestId,
@RequestBody GroupJoinProcessDto processDto) {
groupJoinFacade.processGroupJoinRequest(groupId, requestId, processDto);
groupJoinFacade.processGroupJoinRequest(jwtReader.getUserId(), groupId, requestId, processDto);

return RESPONSE_OK;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,16 @@ public class GroupJoinFacade {
private final GroupService groupService;
private final ProfileService profileService;
private final Consumers consumers;
private final JwtReader jwtReader;


@RedisLock(key = "'group:'.concat(#groupId)")
public void processGroupJoinRequest(Long groupId, Long requestId, GroupJoinProcessDto dto) {
public void processGroupJoinRequest(Long userId, Long groupId, Long requestId, GroupJoinProcessDto dto) {
GroupJoinRequest joinRequest = joinRequestService.getGroupJoinRequestByRequestId(requestId);

if (joinRequest.getResponse() != JoinResponse.PENDING) {
throw new DuplicateElementException("이미 처리된 가입 요청입니다. 요청 id : " + requestId);
}

profileService.checkLoggedInProfileIsGroupManager(joinRequest.getGroup().getId());
profileService.checkLoggedInProfileIsGroupManager(userId, groupId);

Consumer<GroupJoinRequest> action = consumers.getJoinRequestConsumer(dto.getAction());
if (action != null) {
Expand All @@ -57,14 +55,14 @@ public void processGroupJoinRequest(Long groupId, Long requestId, GroupJoinProce
}

@RedisLock(key = "'group:'.concat(#groupId)")
public void joinGroup(GroupJoinRequestDto dto, Long groupId) {
public void joinGroup(GroupJoinRequestDto dto, Long userId, Long groupId) {
Group group = groupService.findGroupById(groupId);
if (joinRequestService.pendingRequestExists(group.getId())) {
if (joinRequestService.pendingRequestExists(userId, groupId)) {
throw new DuplicateElementException("이미 가입 요청한 그룹입니다.");
}

try {
Profile profile = profileService.getLoggedInProfile(groupId);
Profile profile = profileService.getLoggedInProfile(userId, groupId);
BiConsumer<Profile, GroupJoinRequestDto> action = consumers.getGroupJoinConsumer(profile.getState());
if (action != null) {
action.accept(profile, dto);
Expand All @@ -73,15 +71,15 @@ public void joinGroup(GroupJoinRequestDto dto, Long groupId) {
throw new IllegalStateException("No action found : " + profile.getState());
}
} catch (NoLoggedInProfileException e) {
firstJoinProcess(dto, group);
firstJoinProcess(dto, group, userId);
}
}

private void firstJoinProcess(GroupJoinRequestDto dto, Group group) {
private void firstJoinProcess(GroupJoinRequestDto dto, Group group, Long userId) {
if (group.getJoinCondition() == JoinCondition.OPEN) {
groupService.checkGroupSize(group);
group.increaseProfileCount();
profileService.createNewProfile(dto.getNickname(), jwtReader.getUserId(), GroupRole.MEMBER, group);
profileService.createNewProfile(dto.getNickname(), userId, GroupRole.MEMBER, group);
} else {
joinRequestService.createNewGroupJoinRequest(dto, group);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
@RequiredArgsConstructor
public class GroupJoinRequestService {

private final JwtReader jwtReader;
private final GroupJoinRequestRepository joinRequestRepository;
private final GroupJoinRequestMapper joinRequestMapper;
private final ProfileService profileService;
Expand All @@ -30,8 +29,8 @@ public GroupJoinRequest getGroupJoinRequestByRequestId(Long requestId) {
}

@Transactional(readOnly = true)
public boolean pendingRequestExists(Long groupId) {
return joinRequestRepository.pendingRequestExists(jwtReader.getUserId(), groupId);
public boolean pendingRequestExists(Long userId, Long groupId) {
return joinRequestRepository.pendingRequestExists(userId, groupId);
}

@Transactional
Expand All @@ -40,10 +39,10 @@ public void createNewGroupJoinRequest(GroupJoinRequestDto dto, Group group) {
}

@Transactional(readOnly = true)
public List<GroupJoinRequest> getGroupJoinRequestsByGroupIdAndCondition(Long groupId, JoinRequestSearchCondition condition) {
public List<GroupJoinRequest> getGroupJoinRequestsByGroupIdAndCondition(Long userId, Long groupId, JoinRequestSearchCondition condition) {
List<GroupJoinRequest> requests;

profileService.checkLoggedInProfileIsGroupManager(groupId);
profileService.checkLoggedInProfileIsGroupManager(userId, groupId);

switch (condition) {
case PENDING -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,12 @@ public class GroupService {
private final GroupRepository groupRepository;
private final ProfileService profileService;
private final GroupMapper groupMapper;
private final JwtReader jwtReader;

@Transactional
public Group createNewGroup(SaveGroupRequestDto dto) {
public Group createNewGroup(SaveGroupRequestDto dto, Long userId) {
Group group = groupRepository.save(groupMapper.toEntity(dto));

profileService.createNewProfile(dto.getNickname(), jwtReader.getUserId(), GroupRole.MANAGER, group);
profileService.createNewProfile(dto.getNickname(), userId, GroupRole.MANAGER, group);

return group;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
public class ProfileService {

private final ProfileRepository profileRepository;
private final JwtReader jwtReader;

@Transactional
public void createNewProfile(String nickname, Long userId, GroupRole groupRole, Group group) {
Expand All @@ -36,15 +35,13 @@ public void createNewProfile(String nickname, Long userId, GroupRole groupRole,
}

@Transactional(readOnly = true, noRollbackFor = NoLoggedInProfileException.class)
public Profile getLoggedInProfile(Long groupId) {
Long userId = jwtReader.getUserId();

public Profile getLoggedInProfile(Long userId, Long groupId) {
return profileRepository.findByUserIdAndGroupId(userId, groupId).orElseThrow(NoLoggedInProfileException::new);
}

@Transactional(readOnly = true)
public void checkLoggedInProfileIsGroupManager(Long groupId) {
Profile profile = getLoggedInProfile(groupId);
public void checkLoggedInProfileIsGroupManager(Long userId, Long groupId) {
Profile profile = getLoggedInProfile(userId, groupId);

if (profile.getGroupRole() != GroupRole.MANAGER) {
throw new UnAuthorizedException("권한이 없습니다. groupId : "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import me.kong.groupservice.domain.entity.group.Group;
import me.kong.groupservice.domain.entity.group.GroupScope;
import me.kong.groupservice.domain.entity.group.JoinCondition;
import me.kong.groupservice.domain.repository.GroupJoinRequestRepository;
import me.kong.groupservice.domain.repository.GroupRepository;
import me.kong.groupservice.domain.repository.ProfileRepository;
import me.kong.groupservice.dto.request.GroupJoinRequestDto;
Expand All @@ -14,7 +15,6 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
Expand All @@ -29,46 +29,50 @@
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class GroupJoinServiceTest {

@Autowired
private GroupService groupService;

@Autowired
private GroupRepository groupRepository;

@Autowired
private ProfileRepository profileRepository;
private GroupJoinFacade groupJoinFacade;

@Autowired
private RedissonClient redissonClient;
private GroupJoinRequestRepository joinRequestRepository;

@Autowired
private GroupJoinFacade groupJoinFacade;
private ProfileRepository profileRepository;

@BeforeEach
public void setUp() {
joinRequestRepository.deleteAll();
profileRepository.deleteAll();
groupRepository.deleteAll();
}

// 테스트에 필요한 데이터 초기화
@Test
public void testConcurrentGroupJoin() throws InterruptedException {
SaveGroupRequestDto saveGroupRequestDto = SaveGroupRequestDto.builder()
.groupName("test")
.joinCondition(JoinCondition.OPEN)
.groupScope(GroupScope.PUBLIC)
.nickname("testuser")
.description("desc")
.build();
groupService.createNewGroup(saveGroupRequestDto);
}
Long userId = 1L;
Long groupId = groupService.createNewGroup(saveGroupRequestDto, userId).getId();

@Test
public void testConcurrentGroupJoin() throws InterruptedException {
int numberOfThreads = 10;

int numberOfThreads = 9;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);

Group g = groupRepository.findAll().getFirst();

for (int i = 0; i < numberOfThreads; i++) {
final int index = i;
for (long i = 2; i < numberOfThreads + 2; i++) {
final Long uId = i;
String nickname = "joinTest" + i;
executorService.execute(() -> {
try {
Expand All @@ -77,7 +81,7 @@ public void testConcurrentGroupJoin() throws InterruptedException {
.nickname(nickname)
.requestInfo("info")
.build();
groupJoinFacade.joinGroup(dto, g.getId());
groupJoinFacade.joinGroup(dto, uId, g.getId());
} finally {
latch.countDown();
}
Expand All @@ -87,11 +91,11 @@ public void testConcurrentGroupJoin() throws InterruptedException {
latch.await();

Awaitility.await()
.atMost(5, TimeUnit.SECONDS)
.atMost(3, TimeUnit.SECONDS)
.untilAsserted(() -> {
// 그룹에 성공적으로 가입된 인원의 수를 확인
Group group = groupRepository.findById(1L).orElseThrow();
assertThat(group.getProfileCount()).isEqualTo(1);
Group group = groupRepository.findById(groupId).orElseThrow();
assertThat(group.getProfileCount()).isEqualTo(10);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,13 @@ void createGroupTransactionPropagationTest() {
.joinCondition(JoinCondition.OPEN)
.nickname("testUser")
.build();

Long userId = 1L;
doThrow(new RuntimeException())
.when(profileService).createNewProfile(anyString(), any(Long.class), any(GroupRole.class), any(Group.class));

//when
try {
groupService.createNewGroup(dto);
groupService.createNewGroup(dto, userId);
} catch (RuntimeException e) {
// 예외 발생!!!
}
Expand Down
Loading

0 comments on commit 1b4386a

Please sign in to comment.