Skip to content

Commit

Permalink
Refactor/CQRS: Session 및 Attendee Service layer에 CQRS 적용 (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
SHEOMM authored Apr 1, 2024
1 parent bba64f9 commit f70f75e
Show file tree
Hide file tree
Showing 16 changed files with 645 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import com.waruru.areyouhere.attendee.service.AttendeeService;
import com.waruru.areyouhere.attendee.service.dto.AttendeeInfo;
import com.waruru.areyouhere.common.annotation.LoginRequired;
import com.waruru.areyouhere.attendance.service.AuthCodeService;
import com.waruru.areyouhere.attendance.service.AttendanceRedisService;
import com.waruru.areyouhere.session.service.dto.AuthCodeInfo;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -40,7 +40,7 @@
public class AttendanceController {
public static final String ATTENDANCE_API_URL = "/api/attendance";

private final AuthCodeService authCodeService;
private final AttendanceRedisService attendanceRedisService;
private final AttendanceService attendanceService;
private final AttendeeService attendeeService;

Expand All @@ -56,7 +56,7 @@ public ResponseEntity<AttendResponseDto> attend(HttpServletRequest request, @Req
LocalDateTime attendanceTime = LocalDateTime.now();


List<AttendeeInfo> nameSakeAttendees = authCodeService.hasNameSake(authCode, attendeeName);
List<AttendeeInfo> nameSakeAttendees = attendanceRedisService.getNameSakeInfos(authCode, attendeeName);

// 동명이인 응답
if(attendeeId == null && nameSakeAttendees.size() > 1){
Expand All @@ -67,7 +67,7 @@ public ResponseEntity<AttendResponseDto> attend(HttpServletRequest request, @Req
);
}

AuthCodeInfo authCodeInfo = authCodeService.isAttendPossible(authCode, attendeeName, attendeeId);
AuthCodeInfo authCodeInfo = attendanceRedisService.isAttendPossible(authCode, attendeeName, attendeeId);
checkAuthCodeCookie(request.getCookies(), authCode);
attendanceService.setAttend(authCodeInfo.getSessionId(), attendeeName, attendeeId);

Expand Down Expand Up @@ -107,7 +107,7 @@ ResponseEntity<CurrentAttendanceCountResponseDto> getCurrentAttendancesCount(@Re
@LoginRequired
@GetMapping("/detail")
ResponseEntity<CurrentSessionAttendeeAttendance> getCurrentSessionAttendeeAttendance(@RequestParam("authCode") String authCode){
return ResponseEntity.ok(authCodeService.getCurrentSessionAttendanceInfo(authCode));
return ResponseEntity.ok(attendanceRedisService.getCurrentSessionAttendanceInfo(authCode));
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.waruru.areyouhere.session.domain.entity.Session;
import com.waruru.areyouhere.attendance.dto.request.AuthCodeDeactivationRequestDto;
import com.waruru.areyouhere.attendance.dto.request.AuthCodeRequestDto;
import com.waruru.areyouhere.attendance.service.AuthCodeService;
import com.waruru.areyouhere.attendance.service.AttendanceRedisService;
import com.waruru.areyouhere.session.service.SessionService;
import java.time.LocalDateTime;
import lombok.RequiredArgsConstructor;
Expand All @@ -25,7 +25,7 @@ public class AuthCodeController {

public static final String AUTH_CODE_API_URL = "/api/auth-code";

private final AuthCodeService authCodeService;
private final AttendanceRedisService attendanceRedisService;
private final AttendanceService attendanceService;
private final SessionService sessionService;
private final CourseService courseService;
Expand All @@ -39,7 +39,7 @@ public ResponseEntity<String> create(@RequestBody AuthCodeRequestDto authCodeReq
Course course = courseService.get(courseId);
Session session = sessionService.get(sessionId);
sessionService.setStartTime(sessionId, currentTime);
return ResponseEntity.ok(authCodeService.createAuthCode(course, session, currentTime));
return ResponseEntity.ok(attendanceRedisService.createAuthCode(course, session, currentTime));
}

@PostMapping("/deactivate")
Expand All @@ -51,7 +51,7 @@ public ResponseEntity<HttpStatus> deactivate(@RequestBody AuthCodeDeactivationRe

sessionService.checkNotDeactivated(sessionId);
sessionService.deactivate(sessionId);
authCodeService.deactivate(authCode);
attendanceRedisService.deactivate(authCode);
attendanceService.setAbsentAfterDeactivation(courseId, sessionId);
return ResponseEntity.ok().build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
import java.time.LocalDateTime;
import java.util.List;

public interface AuthCodeService {
public interface AttendanceRedisService {

public List<AttendeeInfo> hasNameSake(String authCode, String attendeeName);
public List<AttendeeInfo> getNameSakeInfos(String authCode, String attendeeName);
public AuthCodeInfo isAttendPossible(String authCode, String attendanceName, Long attendeeId);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
@Service
@RequiredArgsConstructor
@Transactional
public class AuthCodeServiceImpl implements AuthCodeService{
public class AttendanceRedisServiceImpl implements AttendanceRedisService {

private final AuthCodeRedisRepository authCodeRedisRepository;
private final SessionIdRedisRepository sessionIdRedisRepository;
Expand All @@ -40,7 +40,7 @@ public class AuthCodeServiceImpl implements AuthCodeService{
private final AttendanceRedisRepository attendanceRedisRepository;

@Override
public List<AttendeeInfo> hasNameSake(String authCode, String attendeeName){
public List<AttendeeInfo> getNameSakeInfos(String authCode, String attendeeName){
AuthCode authCodeData = authCodeRedisRepository
.findById(authCode)
.orElseThrow(AuthCodeNotFoundException::new);
Expand All @@ -62,17 +62,7 @@ public AuthCodeInfo isAttendPossible(String authCode, String attendeeName, Long
.findById(authCode)
.orElseThrow(AuthCodeNotFoundException::new);

AttendeeRedisData attendeeInfo = authCodeData.getAttendees().stream()
.filter(att -> att.getName().equals(attendeeName))
.findAny()
.orElseThrow(AttendeeNotFoundException::new);

if(attendeeId != null){
attendeeInfo = authCodeData.getAttendees().stream()
.filter(att -> att.getId().equals(attendeeId))
.findAny()
.orElseThrow(AttendeeNotFoundException::new);
}
AttendeeRedisData attendeeInfo = getAttendeeInSession(attendeeName, attendeeId, authCodeData);

if(attendanceRedisRepository.isAlreadyAttended(authCode, attendeeInfo)){
throw new AlreadyAttendException();
Expand All @@ -88,17 +78,11 @@ public AuthCodeInfo isAttendPossible(String authCode, String attendeeName, Long
.build();
}



@Override
public String createAuthCode(Course course, Session session, LocalDateTime currentTime){
String generatedAuthCode = "";
while(true){
generatedAuthCode = randomIdentifierGenerator.generateRandomIdentifier(4);
Optional<AuthCode> authCodeData = authCodeRedisRepository
.findById(generatedAuthCode);

if(authCodeData.isEmpty())
break;
}
String generatedAuthCode = generateAuthCode();

List<Attendee> attendeesByCourseId = attendeeRepository.findAttendeesByCourse_Id(course.getId());

Expand All @@ -122,6 +106,9 @@ public String createAuthCode(Course course, Session session, LocalDateTime curre

return generatedAuthCode;
}



// TODO : sessionId 검증, 해당 sessionId가 user 소유인지 검증.
@Override
public void deactivate(String authCode){
Expand Down Expand Up @@ -154,6 +141,34 @@ public CurrentSessionAttendeeAttendance getCurrentSessionAttendanceInfo(String a
.build();
}

private AttendeeRedisData getAttendeeInSession(String attendeeName, Long attendeeId, AuthCode authCodeData) {
AttendeeRedisData attendeeInfo = authCodeData.getAttendees().stream()
.filter(att -> att.getName().equals(attendeeName))
.findAny()
.orElseThrow(AttendeeNotFoundException::new);

if(attendeeId != null){
attendeeInfo = authCodeData.getAttendees().stream()
.filter(att -> att.getId().equals(attendeeId))
.findAny()
.orElseThrow(AttendeeNotFoundException::new);
}
return attendeeInfo;
}

private String generateAuthCode() {
String generatedAuthCode = "";
while(true){
generatedAuthCode = randomIdentifierGenerator.generateRandomIdentifier(4);
Optional<AuthCode> authCodeData = authCodeRedisRepository
.findById(generatedAuthCode);

if(authCodeData.isEmpty())
break;
}
return generatedAuthCode;
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,8 @@ public void setAttend(Long sessionId, String attendanceName, Long attendeeId){
Long courseId = session.getCourse().getId(); // lazy loading?
List<Attendee> attendeesByCourseId = attendeeRepository.findAttendeesByCourse_Id(courseId);

Attendee attendee = attendeeId == null ?
attendeesByCourseId.stream()
.filter(s -> s.getName().equals(attendanceName))
.findFirst()
.orElse(null) :
attendeesByCourseId.stream()
.filter(s -> s.getId().equals(attendeeId))
.findFirst()
.orElse(null);
Attendee attendee = getAttendee(attendanceName, attendeeId,
attendeesByCourseId);

// TODO : attendeesByCourseId null 및 empty 체크

Expand All @@ -90,6 +83,7 @@ public void setAttend(Long sessionId, String attendanceName, Long attendeeId){

}


public void setAttendanceStatuses(Long sessionId , List<UpdateAttendance> updateAttendances){
List<Attendance> attendancesToUpdate = updateAttendances.stream()
.map(updateAttendance -> {
Expand All @@ -115,5 +109,20 @@ public int currentAttendance(Long sessionId){
}


// AttendeeId가 null이 아니라는 것은 duplicatedAttendee가 발생하여 Id 기준으로 찾아야 한다는 것.
private Attendee getAttendee(String attendanceName, Long attendeeId, List<Attendee> attendeesByCourseId) {
Attendee attendee = attendeeId == null ?
attendeesByCourseId.stream()
.filter(s -> s.getName().equals(attendanceName))
.findFirst()
.orElse(null) :
attendeesByCourseId.stream()
.filter(s -> s.getId().equals(attendeeId))
.findFirst()
.orElse(null);
return attendee;
}



}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.waruru.areyouhere.attendee.controller;

import com.waruru.areyouhere.attendee.dto.request.UpdateAttendeesRequestDto;
import com.waruru.areyouhere.attendee.service.command.AttendeeCommandService;
import com.waruru.areyouhere.attendee.service.dto.AttendeeDetailDto;
import com.waruru.areyouhere.attendee.dto.response.ClassAttendeesResponseDto;
import com.waruru.areyouhere.attendee.dto.request.DeleteAttendeesRequestDto;
Expand All @@ -9,6 +10,7 @@
import com.waruru.areyouhere.attendee.service.AttendeeService;
import com.waruru.areyouhere.attendee.service.dto.ClassAttendees;
import com.waruru.areyouhere.attendee.service.dto.DuplicateAttendees;
import com.waruru.areyouhere.attendee.service.query.AttendeeQueryService;
import com.waruru.areyouhere.common.annotation.LoginRequired;
import java.util.List;
import lombok.RequiredArgsConstructor;
Expand All @@ -30,12 +32,13 @@
public class AttendeeController {
public static final String ATTENDEE_API_URL = "/api/attendee";

private final AttendeeService attendeeService;
private final AttendeeCommandService attendeeCommandService;
private final AttendeeQueryService attendeeQueryService;

@LoginRequired
@GetMapping
public ResponseEntity<ClassAttendeesResponseDto> getClassAttendees(@RequestParam("courseId") Long courseId){
List<ClassAttendees> classAttendees = attendeeService.getClassAttendeesIfExistsOrEmpty(courseId);
List<ClassAttendees> classAttendees = attendeeQueryService.getClassAttendeesIfExistsOrEmpty(courseId);

return ResponseEntity.ok(ClassAttendeesResponseDto.builder()
.classAttendees(classAttendees)
Expand All @@ -45,33 +48,33 @@ public ResponseEntity<ClassAttendeesResponseDto> getClassAttendees(@RequestParam
@LoginRequired
@PostMapping
public ResponseEntity<HttpStatus> create(@RequestBody NewAttendeesRequestDto newAttendeesRequestDto){
attendeeService.createAll(newAttendeesRequestDto.getCourseId(), newAttendeesRequestDto.getNewAttendees());
attendeeCommandService.createAll(newAttendeesRequestDto.getCourseId(), newAttendeesRequestDto.getNewAttendees());
return ResponseEntity.ok().build();
}

@LoginRequired
@PostMapping("/delete")
public ResponseEntity<HttpStatus> delete(@RequestBody DeleteAttendeesRequestDto deleteAttendeesRequestDto){
attendeeService.deleteAll(deleteAttendeesRequestDto.getAttendeeIds());
attendeeCommandService.deleteAll(deleteAttendeesRequestDto.getAttendeeIds());
return ResponseEntity.ok().build();
}

@LoginRequired
@PostMapping("/duplicate")
public ResponseEntity<DuplicateAttendees> checkDuplicate(@RequestBody DuplicateCheckAttendeesRequestDto duplicateCheckAttendeesRequestDto){
return ResponseEntity.ok(attendeeService.getDuplicatesAll(duplicateCheckAttendeesRequestDto.getCourseId(), duplicateCheckAttendeesRequestDto.getNewAttendees()));
return ResponseEntity.ok(attendeeQueryService.getDuplicatesAll(duplicateCheckAttendeesRequestDto.getCourseId(), duplicateCheckAttendeesRequestDto.getNewAttendees()));
}

@LoginRequired
@GetMapping("/detail")
public ResponseEntity<AttendeeDetailDto> getAttendeeDetail(@RequestParam("attendeeId") Long attendeeId){
return ResponseEntity.ok(attendeeService.getAttendanceCount(attendeeId));
return ResponseEntity.ok(attendeeQueryService.getAttendanceCount(attendeeId));
}

@LoginRequired
@PutMapping
public ResponseEntity<HttpStatus> update(@RequestBody UpdateAttendeesRequestDto UpdateAttendeesRequestDto){
attendeeService.updateAll(UpdateAttendeesRequestDto.getCourseId(), UpdateAttendeesRequestDto.getUpdatedAttendees());
attendeeCommandService.updateAll(UpdateAttendeesRequestDto.getCourseId(), UpdateAttendeesRequestDto.getUpdatedAttendees());
return ResponseEntity.ok().build();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.waruru.areyouhere.attendee.service.command;

import com.waruru.areyouhere.attendee.service.dto.AttendeeInfo;
import java.util.List;

public interface AttendeeCommandService {
public void createAll(Long courseId, List<AttendeeInfo> newAttendees);
public void deleteAll(List<Long> deleteAttendees);

public void updateAll(Long courseId, List<AttendeeInfo> updatedAttendees);
}
Loading

0 comments on commit f70f75e

Please sign in to comment.