Skip to content

Commit

Permalink
Merge pull request #216 from softeerbootcamp4th/feat/#213-lottery-cac…
Browse files Browse the repository at this point in the history
…hing

Feat/#213 lottery caching
  • Loading branch information
wjddn2165 authored Aug 22, 2024
2 parents 9ae4172 + 516f40f commit 8e621fe
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import JGS.CasperEvent.domain.event.repository.participantsRepository.LotteryParticipantsRepository;
import JGS.CasperEvent.domain.event.repository.participantsRepository.LotteryWinnerRepository;
import JGS.CasperEvent.domain.event.repository.participantsRepository.RushParticipantsRepository;
import JGS.CasperEvent.domain.event.service.eventService.EventCacheService;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.enums.Position;
import JGS.CasperEvent.global.enums.Role;
Expand Down Expand Up @@ -58,6 +59,7 @@ public class AdminService {
private final CasperBotRepository casperBotRepository;
private final LotteryWinnerRepository lotteryWinnerRepository;
private final RedisTemplate<String, CasperBotResponseDto> casperBotRedisTemplate;
private final EventCacheService eventCacheService;
private final Random random = new Random();

// 어드민 인증
Expand All @@ -75,7 +77,7 @@ public ResponseDto postAdmin(AdminRequestDto adminRequestDto) {
if (admin != null) throw new CustomException("이미 등록된 ID입니다.", CustomErrorCode.CONFLICT);
adminRepository.save(new Admin(adminId, password, Role.ADMIN));

return ResponseDto.of("관리자 생성 성공");
return new ResponseDto("관리자 생성 성공");
}

// 이미지 업로드
Expand All @@ -93,6 +95,7 @@ public LotteryEventResponseDto createLotteryEvent(LotteryEventRequestDto lottery
lotteryEventRequestDto.getWinnerCount()
));

eventCacheService.setLotteryEvent();
return LotteryEventResponseDto.of(lotteryEvent, LocalDateTime.now());
}

Expand Down Expand Up @@ -280,7 +283,7 @@ public void deleteLotteryEvent() {
lotteryEventRepository.deleteById(currentLotteryEvent.getLotteryEventId());
}

// 선착순 이벤트 업데이트
// 추첨 이벤트 업데이트
@Transactional
public LotteryEventDetailResponseDto updateLotteryEvent(LotteryEventRequestDto lotteryEventRequestDto) {
LotteryEvent currentLotteryEvent = getCurrentLotteryEvent();
Expand Down Expand Up @@ -311,7 +314,7 @@ else if (newStartDateTime.isBefore(now)) {

// 필드 업데이트
currentLotteryEvent.updateLotteryEvent(newStartDateTime, newEndDateTime, lotteryEventRequestDto.getWinnerCount());

eventCacheService.setLotteryEvent();
return LotteryEventDetailResponseDto.of(currentLotteryEvent);
}

Expand Down Expand Up @@ -508,7 +511,7 @@ public ResponseDto deleteRushEvent(Long rushEventId) {
if (now.isAfter(startDateTime) && now.isBefore(endDateTime))
throw new CustomException(CustomErrorCode.EVENT_IN_PROGRESS_CANNOT_DELETE);
rushEventRepository.delete(rushEvent);
return ResponseDto.of("요청에 성공하였습니다.");
return new ResponseDto("요청에 성공하였습니다.");
}

// 선착순 이벤트 선택지 조회
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package JGS.CasperEvent.domain.event.service.eventService;

import JGS.CasperEvent.domain.event.dto.ResponseDto.rushEventResponseDto.RushEventResponseDto;
import JGS.CasperEvent.domain.event.entity.event.LotteryEvent;
import JGS.CasperEvent.domain.event.entity.event.RushEvent;
import JGS.CasperEvent.domain.event.repository.eventRepository.LotteryEventRepository;
import JGS.CasperEvent.domain.event.repository.eventRepository.RushEventRepository;
import JGS.CasperEvent.global.enums.CustomErrorCode;
import JGS.CasperEvent.global.error.exception.CustomException;
Expand All @@ -17,9 +19,36 @@
@Service
@RequiredArgsConstructor
@Slf4j
public class RushEventCacheService {
public class EventCacheService {

private final RushEventRepository rushEventRepository;
private final LotteryEventRepository lotteryEventRepository;

@Cacheable(value = "ongoingLotteryEvent")
public LotteryEvent getLotteryEvent(){
return fetchOngoingLotteryEvent();
}

@CachePut(value = "ongoingLotteryEvent")
public LotteryEvent setLotteryEvent() {
// 오늘 날짜에 해당하는 모든 이벤트 꺼내옴
return fetchOngoingLotteryEvent();
}

private LotteryEvent fetchOngoingLotteryEvent() {
// 오늘 날짜에 해당하는 모든 이벤트 꺼내옴
List<LotteryEvent> lotteryEventList = lotteryEventRepository.findAll();

if (lotteryEventList.isEmpty()) {
throw new CustomException("현재 진행중인 lotteryEvent가 존재하지 않습니다.", CustomErrorCode.NO_LOTTERY_EVENT);
}

if (lotteryEventList.size() > 1) {
throw new CustomException("현재 진행중인 lotteryEvent가 2개 이상입니다.", CustomErrorCode.TOO_MANY_LOTTERY_EVENT);
}

return lotteryEventList.get(0);
}

@Cacheable(value = "todayEventCache", key = "#today")
public RushEventResponseDto getTodayEvent(LocalDate today) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
package JGS.CasperEvent.domain.event.service.eventService;

import JGS.CasperEvent.domain.event.dto.RequestDto.lotteryEventDto.CasperBotRequestDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.CasperBotResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.LotteryEventResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.LotteryParticipantResponseDto;
import JGS.CasperEvent.domain.event.dto.ResponseDto.lotteryEventResponseDto.*;
import JGS.CasperEvent.domain.event.entity.casperBot.CasperBot;
import JGS.CasperEvent.domain.event.entity.event.LotteryEvent;
import JGS.CasperEvent.domain.event.entity.participants.LotteryParticipants;
Expand All @@ -29,7 +27,6 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
Expand All @@ -39,16 +36,16 @@ public class LotteryEventService {

private static final Logger log = LoggerFactory.getLogger(LotteryEventService.class);
private final UserRepository userRepository;
private final LotteryEventRepository lotteryEventRepository;
private final LotteryParticipantsRepository lotteryParticipantsRepository;
private final CasperBotRepository casperBotRepository;
private final RedisService redisService;
private final SecretKey secretKey;
private final EventCacheService eventCacheService;

public CasperBotResponseDto postCasperBot(BaseUser user, CasperBotRequestDto casperBotRequestDto) throws CustomException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
LotteryParticipants participants = registerUserIfNeed(user, casperBotRequestDto);

LotteryEvent lotteryEvent = getEvent();
LotteryEvent lotteryEvent = eventCacheService.getLotteryEvent();

CasperBot casperBot = casperBotRepository.save(new CasperBot(casperBotRequestDto, user.getId()));
lotteryEvent.addAppliedCount();
Expand Down Expand Up @@ -112,21 +109,7 @@ private void addReferralAppliedCount(CasperBotRequestDto casperBotRequestDto) th
}

public LotteryEventResponseDto getLotteryEvent() {
LotteryEvent lotteryEvent = getEvent();
LotteryEvent lotteryEvent = eventCacheService.getLotteryEvent();
return LotteryEventResponseDto.of(lotteryEvent, LocalDateTime.now());
}

private LotteryEvent getEvent() {
List<LotteryEvent> lotteryEventList = lotteryEventRepository.findAll();

if (lotteryEventList.isEmpty()) {
throw new CustomException("현재 진행중인 lotteryEvent가 존재하지 않습니다.", CustomErrorCode.NO_LOTTERY_EVENT);
}

if (lotteryEventList.size() > 1) {
throw new CustomException("현재 진행중인 lotteryEvent가 2개 이상입니다.", CustomErrorCode.TOO_MANY_LOTTERY_EVENT);
}

return lotteryEventList.get(0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ public class RushEventService {
private final RushEventRepository rushEventRepository;
private final RushParticipantsRepository rushParticipantsRepository;
private final RushOptionRepository rushOptionRepository;
private final RushEventCacheService rushEventCacheService;
private final EventCacheService eventCacheService;

@Transactional
public RushEventListResponseDto getAllRushEvents() {
LocalDate today = LocalDate.now();

// 오늘의 선착순 이벤트 꺼내오기
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);
RushEventResponseDto todayEvent = eventCacheService.getTodayEvent(today);

// DB에서 모든 RushEvent 가져오기
List<RushEvent> rushEventList = rushEventRepository.findAll();
Expand Down Expand Up @@ -69,14 +69,14 @@ public RushEventListResponseDto getAllRushEvents() {
// 응모 여부 조회
public boolean isExists(String userId) {
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();
Long todayEventId = eventCacheService.getTodayEvent(today).rushEventId();
return rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, userId);
}

@Transactional
public void apply(BaseUser user, int optionId) {
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();
Long todayEventId = eventCacheService.getTodayEvent(today).rushEventId();

// 이미 응모한 회원인지 검증
if (rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, user.getId())) {
Expand All @@ -94,7 +94,7 @@ public void apply(BaseUser user, int optionId) {
// 진행중인 게임의 응모 비율 반환
public RushEventRateResponseDto getRushEventRate(BaseUser user) {
LocalDate today = LocalDate.now();
Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId();
Long todayEventId = eventCacheService.getTodayEvent(today).rushEventId();
Optional<Integer> optionId = rushParticipantsRepository.getOptionIdByUserId(user.getId());
long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 1);
long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 2);
Expand All @@ -109,7 +109,7 @@ public RushEventRateResponseDto getRushEventRate(BaseUser user) {
@Transactional
public RushEventResultResponseDto getRushEventResult(BaseUser user) {
LocalDate today = LocalDate.now();
RushEventResponseDto todayRushEvent = rushEventCacheService.getTodayEvent(today);
RushEventResponseDto todayRushEvent = eventCacheService.getTodayEvent(today);
Long todayEventId = todayRushEvent.rushEventId();

// 최종 선택 비율을 조회
Expand Down Expand Up @@ -228,14 +228,14 @@ public void setRushEvents() {
rushEvents.add(rushEvent);
}

rushEventCacheService.setCacheValue(LocalDate.now());
eventCacheService.setCacheValue(LocalDate.now());
}


// 오늘의 이벤트 옵션 정보를 반환
public MainRushEventOptionsResponseDto getTodayRushEventOptions() {
LocalDate today = LocalDate.now();
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);
RushEventResponseDto todayEvent = eventCacheService.getTodayEvent(today);
Set<RushEventOptionResponseDto> options = todayEvent.options();

RushEventOptionResponseDto leftOption = options.stream()
Expand All @@ -257,7 +257,7 @@ public MainRushEventOptionsResponseDto getTodayRushEventOptions() {
public ResultRushEventOptionResponseDto getRushEventOptionResult(int optionId) {
Position position = Position.of(optionId);
LocalDate today = LocalDate.now();
RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today);
RushEventResponseDto todayEvent = eventCacheService.getTodayEvent(today);
Set<RushEventOptionResponseDto> options = todayEvent.options();

if (options.size() != 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class CacheConfig {

@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager("todayEventCache");
return new ConcurrentMapCacheManager("todayEventCache", "ongoingLotteryEvent");
}

}
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package JGS.CasperEvent.global.response;

public record ResponseDto(String message) {
public static ResponseDto of(String message) {
return new ResponseDto(message);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ void postAdminSuccessTest() throws Exception {
AdminRequestDto adminRequestDto = AdminRequestDto.builder().adminId(adminId).password(password).build();
String requestBody = objectMapper.writeValueAsString(adminRequestDto);

given(adminService.postAdmin(adminRequestDto)).willReturn(ResponseDto.of("관리자 생성 성공"));
given(adminService.postAdmin(adminRequestDto)).willReturn(new ResponseDto("관리자 생성 성공"));
//when
ResultActions perform = mockMvc.perform(post("/admin/join").contentType(APPLICATION_JSON).content(requestBody));

Expand Down Expand Up @@ -666,7 +666,7 @@ void deleteLotteryEventExpectationSuccessTest() throws Exception {
void pickLotteryEventWinnerSuccessTest() throws Exception {
//given
given(adminService.pickLotteryEventWinners())
.willReturn(ResponseDto.of("추첨이 완료되었습니다."));
.willReturn(new ResponseDto("추첨이 완료되었습니다."));

//when
ResultActions perform = mockMvc.perform(post("/admin/event/lottery/winner")
Expand All @@ -684,7 +684,7 @@ void pickLotteryEventWinnerSuccessTest() throws Exception {
void deleteLotteryEventWinners() throws Exception {
//given
given(adminService.deleteLotteryEventWinners())
.willReturn(ResponseDto.of("당첨자 명단을 삭제했습니다."));
.willReturn(new ResponseDto("당첨자 명단을 삭제했습니다."));

//when
ResultActions perform = mockMvc.perform(delete("/admin/event/lottery/winner")
Expand Down
Loading

0 comments on commit 8e621fe

Please sign in to comment.