Skip to content

Commit

Permalink
refactor: 엑셀 다운로드 따닥 방지 (#1133)
Browse files Browse the repository at this point in the history
* feat: 엑셀 다운로드 중복 방지 redis 적용

* feat: 엑셀 다운로드 중복 방지 로직 추가

* style: 라인 포맷팅

* fix: 리뷰 반영

* fix: 개행 추가

* fix: ExcelDownloadCache.from 매개변수 변경
  • Loading branch information
dradnats1012 authored Dec 15, 2024
1 parent 23c5f96 commit f9b0f38
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package in.koreatech.koin.domain.coop.exception;

import java.time.LocalDate;

import in.koreatech.koin.global.exception.DuplicationException;

public class DuplicateExcelRequestException extends DuplicationException {

private static final String DEFAULT_MESSAGE = "동일한 요청을 30초 안에 다시 보낼 수 없습니다!";

public DuplicateExcelRequestException(String message) {
super(message);
}

public DuplicateExcelRequestException(String message, String detail) {
super(message, detail);
}

public static DuplicateExcelRequestException withDetail(LocalDate startDate, LocalDate endDate) {
return new DuplicateExcelRequestException(DEFAULT_MESSAGE,
"startDate: '" + startDate + "'" + "endDate: " + endDate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package in.koreatech.koin.domain.coop.model;

import java.time.LocalDate;
import java.util.concurrent.TimeUnit;

import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.TimeToLive;

import jakarta.persistence.Id;
import lombok.Builder;
import lombok.Getter;

@Getter
@RedisHash(value = "excelDownload")
public class ExcelDownloadCache {

private static final long CACHE_EXPIRE_SECONDS = 30L;

@Id
private String id;

@TimeToLive(unit = TimeUnit.SECONDS)
private final Long expiration;

@Builder
private ExcelDownloadCache(String id, Long expiration) {
this.id = id;
this.expiration = expiration;
}

public static ExcelDownloadCache from(LocalDate startDate, LocalDate endDate) {
return ExcelDownloadCache.builder()
.id(startDate.toString() + endDate.toString())
.expiration(CACHE_EXPIRE_SECONDS)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package in.koreatech.koin.domain.coop.repository;

import java.util.Optional;

import org.springframework.data.repository.Repository;

import in.koreatech.koin.domain.coop.model.ExcelDownloadCache;

public interface ExcelDownloadCacheRepository extends Repository<ExcelDownloadCache, String> {

ExcelDownloadCache save(ExcelDownloadCache excelDownloadCache);

Optional<ExcelDownloadCache> findById(String id);

boolean existsById(String id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@
import in.koreatech.koin.domain.coop.dto.SoldOutRequest;
import in.koreatech.koin.domain.coop.exception.DiningLimitDateException;
import in.koreatech.koin.domain.coop.exception.DiningNowDateException;
import in.koreatech.koin.domain.coop.exception.DuplicateExcelRequestException;
import in.koreatech.koin.domain.coop.exception.StartDateAfterEndDateException;
import in.koreatech.koin.domain.coop.model.Coop;
import in.koreatech.koin.domain.coop.model.DiningImageUploadEvent;
import in.koreatech.koin.domain.coop.model.DiningNotifyCache;
import in.koreatech.koin.domain.coop.model.DiningSoldOutEvent;
import in.koreatech.koin.domain.coop.model.ExcelDownloadCache;
import in.koreatech.koin.domain.coop.repository.CoopRepository;
import in.koreatech.koin.domain.coop.repository.DiningNotifyCacheRepository;
import in.koreatech.koin.domain.coop.repository.DiningSoldOutCacheRepository;
import in.koreatech.koin.domain.coop.repository.ExcelDownloadCacheRepository;
import in.koreatech.koin.domain.coopshop.model.CoopShopType;
import in.koreatech.koin.domain.coopshop.service.CoopShopService;
import in.koreatech.koin.domain.dining.model.Dining;
Expand All @@ -65,6 +68,7 @@ public class CoopService {
private final ApplicationEventPublisher eventPublisher;
private final DiningRepository diningRepository;
private final DiningSoldOutCacheRepository diningSoldOutCacheRepository;
private final ExcelDownloadCacheRepository excelDownloadCacheRepository;
private final DiningNotifyCacheRepository diningNotifyCacheRepository;
private final CoopRepository coopRepository;
private final UserTokenRepository userTokenRepository;
Expand Down Expand Up @@ -166,6 +170,7 @@ public CoopLoginResponse coopLogin(CoopLoginRequest request) {
}

public ByteArrayInputStream generateDiningExcel(LocalDate startDate, LocalDate endDate, Boolean isCafeteria) {
checkDuplicateExcelRequest(startDate, endDate);
validateDates(startDate, endDate);
List<Dining> dinings = fetchDiningData(startDate, endDate, isCafeteria);

Expand All @@ -192,7 +197,6 @@ private void validateDates(LocalDate startDate, LocalDate endDate) {
if (startDate.isAfter(today) || endDate.isAfter(today)) {
throw new DiningNowDateException("오늘 날짜 이후 기간은 설정할 수 없어요.");
}

if (startDate.isAfter(endDate)) {
throw new StartDateAfterEndDateException("시작일은 종료일 이전으로 설정해주세요.");
}
Expand Down Expand Up @@ -265,10 +269,10 @@ private void fillDiningRow(Dining dining, Row row, CellStyle commonStyle) {
row.createCell(6).setCellValue(Optional.ofNullable(dining.getSoldOut()).map(Object::toString).orElse(""));
row.createCell(7).setCellValue(Optional.ofNullable(dining.getIsChanged()).map(Object::toString).orElse(""));

for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) {
row.getCell(i).setCellStyle(commonStyle);
}
for (int i = 0; i < EXCEL_COLUMN_COUNT; i++) {
row.getCell(i).setCellStyle(commonStyle);
}
}

private String formatMenu(List<String> menu) {
return String.join("\n", menu);
Expand All @@ -281,4 +285,13 @@ private ByteArrayInputStream writeWorkbookToStream(SXSSFWorkbook workbook) throw
return new ByteArrayInputStream(out.toByteArray());
}
}

private void checkDuplicateExcelRequest(LocalDate startDate, LocalDate endDate) {
boolean isCacheExist = excelDownloadCacheRepository.existsById(startDate.toString() + endDate.toString());

if (isCacheExist) {
throw DuplicateExcelRequestException.withDetail(startDate, endDate);
}
excelDownloadCacheRepository.save(ExcelDownloadCache.from(startDate, endDate));
}
}

0 comments on commit f9b0f38

Please sign in to comment.