Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 정적 파일 캐싱하기 #161

Merged
merged 62 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
b86e134
[Infra] CI/CD test (#42)
DrRivaski Aug 6, 2024
8a3f2df
[Infra] CI CD test 3 (#45)
DrRivaski Aug 6, 2024
e17e1d5
config: jwt 속성을 yml에 설정
Jul 29, 2024
54bf5b6
rebase: 원본 develop 브랜치와 병합
Jul 30, 2024
0bda42a
feat: Caffeine cache 설정
Aug 19, 2024
c9abeac
feat: 메인페이지 이벤트 정보 응답 dto 구현
Aug 19, 2024
7526f50
feat: s3 파일 이름을 enum으로 관리하도록 구현
Aug 19, 2024
a932bb4
feat: static 자원 util 클래스 구현
Aug 19, 2024
9cc4b6e
feat: 정적 텍스트 entity 구현
Aug 19, 2024
624fb30
feat: 정적 텍스트 repository 구현
Aug 19, 2024
aa58abd
config: 의존성 설정
Aug 19, 2024
aa4a8d9
chore: import문 삭제
Aug 19, 2024
14f49c1
refactor: 정적 자원 가져오는 로직 변경
Aug 19, 2024
696e50f
refactor: 클래스 삭제
Aug 19, 2024
a736a86
feat: etag 필터 등록
Aug 19, 2024
49cba3b
feat: 정적 텍스트의 이름을 관리하는 enum 구현
Aug 19, 2024
74b810d
refactor: 문자열을 상수로 관리
Aug 19, 2024
352db23
feat: s3content repository 구현
Aug 19, 2024
4488988
refactor: DB 테이블명 변경
Aug 19, 2024
95b3d41
refactor: redis key 상수 변경
Aug 19, 2024
2438359
refactor: 전화번호 regex 변경
Aug 19, 2024
6644f95
refactor: 코드 리팩토링
Aug 19, 2024
6e6f117
refactor: 필드 삭제
Aug 19, 2024
31d30b2
feat: 이벤트 페이지 정보를 응답하는 메서드 구현
Aug 19, 2024
a5abc41
feat: 인증검사를 하지 않는 url 설정
Aug 19, 2024
9ee3de9
feat: setter 설정
Aug 19, 2024
7803a11
feat: 선착순 결과 캐싱하기
Aug 19, 2024
e4c716f
refactor: redirect 하지 않도록 변경
Aug 19, 2024
b0a466b
refactor: 정적 자원 가져오는 로직 변경
Aug 19, 2024
c6fd60d
refactor: 문자열을 상수로 관리
Aug 19, 2024
ab22bbb
[Infra] CI/CD test (#42)
DrRivaski Aug 6, 2024
295cb72
[Infra] CI CD test 3 (#45)
DrRivaski Aug 6, 2024
37be27a
config: jwt 속성을 yml에 설정
Jul 29, 2024
150029a
rebase: 원본 develop 브랜치와 병합
Jul 30, 2024
d524b6e
feat: Caffeine cache 설정
Aug 19, 2024
3b916e5
feat: 메인페이지 이벤트 정보 응답 dto 구현
Aug 19, 2024
037b830
feat: s3 파일 이름을 enum으로 관리하도록 구현
Aug 19, 2024
f7e409f
feat: static 자원 util 클래스 구현
Aug 19, 2024
ee0a0f3
feat: 정적 텍스트 entity 구현
Aug 19, 2024
1d4e8ae
feat: 정적 텍스트 repository 구현
Aug 19, 2024
9cd9168
config: 의존성 설정
Aug 19, 2024
7d980fc
chore: import문 삭제
Aug 19, 2024
4e81dbe
refactor: 정적 자원 가져오는 로직 변경
Aug 19, 2024
c2934ef
refactor: 클래스 삭제
Aug 19, 2024
ab1838d
feat: etag 필터 등록
Aug 19, 2024
081031e
feat: 정적 텍스트의 이름을 관리하는 enum 구현
Aug 19, 2024
933437c
rebase: 원본 repo develop 브랜치와 충돌 해결
Aug 19, 2024
e237647
feat: s3content repository 구현
Aug 19, 2024
39bc9f1
refactor: DB 테이블명 변경
Aug 19, 2024
a32232f
refactor: redis key 상수 변경
Aug 19, 2024
28d5177
refactor: 전화번호 regex 변경
Aug 19, 2024
2a364af
refactor: 코드 리팩토링
Aug 19, 2024
e32d006
refactor: 필드 삭제
Aug 19, 2024
1aaf5aa
feat: 이벤트 페이지 정보를 응답하는 메서드 구현
Aug 19, 2024
e6f2a5c
feat: 인증검사를 하지 않는 url 설정
Aug 19, 2024
9095b27
feat: setter 설정
Aug 19, 2024
273f731
feat: 선착순 결과 캐싱하기
Aug 19, 2024
434ed57
refactor: redirect 하지 않도록 변경
Aug 19, 2024
d2cbe4a
refactor: 정적 자원 가져오는 로직 변경
Aug 19, 2024
e2a0032
refactor: 문자열을 상수로 관리
Aug 19, 2024
0be2b80
refactor: 변수명 변경
Aug 19, 2024
00f60ca
Merge remote-tracking branch 'origin/feature/155' into feature/155
Aug 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ dependencies {
// Bcrypt 설정
implementation 'org.mindrot:jbcrypt:0.4'

// Spring Cache 설정
implementation 'org.springframework.boot:spring-boot-starter-cache'

// Caffeine Cache 설정
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.8'

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/softeer/backend/BackendApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public class PhoneNumberSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {

String formatted = value.replaceAll("(\\d{3})(\\d{3})(\\d+)", "$1-$2-$3");
String formatted = value.replaceAll("(\\d{3})(\\d{4})(\\d+)", "$1-$2-$3");
gen.writeString(formatted);
}
}
Original file line number Diff line number Diff line change
@@ -1,63 +1,75 @@
package com.softeer.backend.fo_domain.draw.util;

import com.softeer.backend.fo_domain.draw.dto.modal.WinModal;
import com.softeer.backend.global.staticresources.util.StaticResourcesUtil;
import com.softeer.backend.global.staticresources.constant.S3FileName;
import com.softeer.backend.global.staticresources.constant.StaticTextName;
import com.softeer.backend.global.staticresources.util.StaticResourceUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@RequiredArgsConstructor
public class DrawModalGenerateUtil {
private final StaticResourcesUtil staticResourcesUtil;

private final StaticResourceUtil staticResourceUtil;

/**
* @return 등수에 따른 WinModal을 반환
*/
@Cacheable(value = "staticResources", key = "'draw_modal_' + #ranking")
public WinModal generateWinModal(int ranking) {

Map<String, String> textContentMap = staticResourceUtil.getTextContentMap();
Map<String, String> s3ContentMap = staticResourceUtil.getS3ContentMap();

if (ranking == 1) {
return generateFirstWinModal();
return generateFirstWinModal(textContentMap, s3ContentMap);
} else if (ranking == 2) {
return generateSecondWinModal();
return generateSecondWinModal(textContentMap, s3ContentMap);
} else if (ranking == 3) {
return generateThirdWinModal();
return generateThirdWinModal(textContentMap, s3ContentMap);
} else {
return generateFullAttendModal();
return generateFullAttendModal(textContentMap, s3ContentMap);
}
}

/**
* @return 1등 WinModal 반환
*/
private WinModal generateFirstWinModal() {

private WinModal generateFirstWinModal(Map<String, String> textContentMap, Map<String, String> s3ContentMap) {
return WinModal.builder()
.title(staticResourcesUtil.getData("DRAW_WINNER_MODAL_TITLE"))
.subtitle(staticResourcesUtil.getData("DRAW_FIRST_WINNER_MODAL_SUBTITLE"))
.img(staticResourcesUtil.getData("draw_reward_image_1"))
.description(staticResourcesUtil.getData("DRAW_WINNER_MODAL_DESCRIPTION"))
.title(textContentMap.get(StaticTextName.DRAW_WINNER_MODAL_TITLE.name()))
.subtitle(textContentMap.get(StaticTextName.DRAW_FIRST_WINNER_SUBTITLE.name()))
.img(s3ContentMap.get(S3FileName.DRAW_REWARD_IMAGE_1.name()))
.description(StaticTextName.DRAW_WINNER_MODAL_DESCRIPTION.name())
.build();
}

/**
* @return 2등 WinModal 반환
*/
private WinModal generateSecondWinModal() {
private WinModal generateSecondWinModal(Map<String, String> textContentMap, Map<String, String> s3ContentMap) {
return WinModal.builder()
.title(staticResourcesUtil.getData("DRAW_WINNER_MODAL_TITLE"))
.subtitle(staticResourcesUtil.getData("DRAW_SECOND_WINNER_MODAL_SUBTITLE"))
.img(staticResourcesUtil.getData("draw_reward_image_2"))
.description(staticResourcesUtil.getData("DRAW_WINNER_MODAL_DESCRIPTION"))
.title(textContentMap.get(StaticTextName.DRAW_WINNER_MODAL_TITLE.name()))
.subtitle(textContentMap.get(StaticTextName.DRAW_SECOND_WINNER_SUBTITLE.name()))
.img(s3ContentMap.get(S3FileName.DRAW_REWARD_IMAGE_2.name()))
.description(textContentMap.get(StaticTextName.DRAW_WINNER_MODAL_DESCRIPTION.name()))
.build();
}

/**
* @return 3등 WinModal 반환
*/
private WinModal generateThirdWinModal() {
private WinModal generateThirdWinModal(Map<String, String> textContentMap, Map<String, String> s3ContentMap) {
return WinModal.builder()
.title(staticResourcesUtil.getData("DRAW_WINNER_MODAL_TITLE"))
.subtitle(staticResourcesUtil.getData("DRAW_THIRD_WINNER_MODAL_SUBTITLE"))
.img(staticResourcesUtil.getData("draw_reward_image_3"))
.description(staticResourcesUtil.getData("DRAW_WINNER_MODAL_DESCRIPTION"))
.title(textContentMap.get(StaticTextName.DRAW_WINNER_MODAL_TITLE.name()))
.subtitle(textContentMap.get(StaticTextName.DRAW_THIRD_WINNER_SUBTITLE.name()))
.img(s3ContentMap.get(S3FileName.DRAW_REWARD_IMAGE_3.name()))
.description(textContentMap.get(StaticTextName.DRAW_WINNER_MODAL_DESCRIPTION.name()))
.build();
}

Expand All @@ -66,12 +78,12 @@ private WinModal generateThirdWinModal() {
*
* @return FullAttendModal 반환
*/
public WinModal generateFullAttendModal() {
public WinModal generateFullAttendModal(Map<String, String> textContentMap, Map<String, String> s3ContentMap) {
return WinModal.builder()
.title(staticResourcesUtil.getData("FULL_ATTEND_MODAL_TITLE"))
.subtitle(staticResourcesUtil.getData("FULL_ATTEND_MODAL_SUBTITLE"))
.img(staticResourcesUtil.getData("attendance_reward_image"))
.description(staticResourcesUtil.getData("FULL_ATTEND_MODAL_DESCRIPTION"))
.title(textContentMap.get(StaticTextName.FULL_ATTEND_MODAL_TITLE.name()))
.subtitle(textContentMap.get(StaticTextName.FULL_ATTEND_MODAL_SUBTITLE.name()))
.img(s3ContentMap.get(S3FileName.ATTENDANCE_REWARD_IMAGE.name()))
.description(textContentMap.get(StaticTextName.FULL_ATTEND_MODAL_DESCRIPTION.name()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@
import com.softeer.backend.fo_domain.share.exception.ShareUrlInfoException;
import com.softeer.backend.fo_domain.share.repository.ShareUrlInfoRepository;
import com.softeer.backend.global.common.code.status.ErrorStatus;
import com.softeer.backend.global.staticresources.util.StaticResourcesUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class DrawResponseGenerateUtil {
public static final String BASE_URL = "https://softeer.shop/share/";

private final ShareUrlInfoRepository shareUrlInfoRepository;
private final DrawUtil drawUtil;
private final DrawModalGenerateUtil drawModalGenerateUtil;
private final StaticResourcesUtil staticResourcesUtil;


/**
* 7일 연속 출석 시 상품 정보 모달 만들어서 반환하는 메서드
Expand Down Expand Up @@ -112,7 +113,7 @@ public DrawHistoryLoserResponseDto generateDrawHistoryLoserResponse(Integer user
* @return 공유 url
*/
private String getShareUrl(Integer userId) {
return staticResourcesUtil.getData("BASE_URL") + shareUrlInfoRepository.findShareUrlByUserId(userId)
return BASE_URL + shareUrlInfoRepository.findShareUrlByUserId(userId)
.orElseThrow(() -> new ShareUrlInfoException(ErrorStatus._NOT_FOUND));
}
}
38 changes: 27 additions & 11 deletions src/main/java/com/softeer/backend/fo_domain/draw/util/DrawUtil.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
package com.softeer.backend.fo_domain.draw.util;

import com.softeer.backend.global.staticresources.util.StaticResourcesUtil;
import com.softeer.backend.fo_domain.fcfs.service.FcfsService;
import com.softeer.backend.global.staticresources.constant.S3FileName;
import com.softeer.backend.global.staticresources.repository.S3ContentRepository;
import com.softeer.backend.global.staticresources.util.StaticResourceUtil;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;

@Component
@RequiredArgsConstructor
public class DrawUtil {
private final StaticResourcesUtil staticResourcesUtil;

private final ObjectProvider<DrawUtil> drawUtilProvider;
private final StaticResourceUtil staticResourceUtil;

@Getter
private boolean isDrawWin = false;
@Getter
Expand Down Expand Up @@ -53,7 +62,8 @@ public List<String> generateWinImages() {
Random random = new Random();
int direction = random.nextInt(4); // 랜덤 수

String directionImage = getImageUrl(direction);
DrawUtil drawUtil = drawUtilProvider.getObject();
String directionImage = drawUtil.getImageUrl(direction);

ArrayList<String> images = new ArrayList<>(3);
images.add(directionImage);
Expand All @@ -66,6 +76,8 @@ public List<String> generateWinImages() {
* @return 낙첨자를 위한 랜덤 방향 이미지 List 반환
*/
public List<String> generateLoseImages() {
DrawUtil drawUtil = drawUtilProvider.getObject();

ArrayList<String> images = new ArrayList<>(3);
Random random = new Random();
int firstDirection, secondDirection, thirdDirection;
Expand All @@ -76,26 +88,30 @@ public List<String> generateLoseImages() {
thirdDirection = random.nextInt(4);
} while (firstDirection == secondDirection && secondDirection == thirdDirection);

images.add(getImageUrl(firstDirection));
images.add(getImageUrl(secondDirection));
images.add(getImageUrl(thirdDirection));
images.add(drawUtil.getImageUrl(firstDirection));
images.add(drawUtil.getImageUrl(secondDirection));
images.add(drawUtil.getImageUrl(thirdDirection));
return images;
}

/**
* @param direction 방향을 나타냄. 0, 1, 2, 3이 각각 위, 오른쪽, 밑, 왼쪽
* @return 방향에 따른 이미지 url을 반환
*/
private String getImageUrl(int direction) {
@Cacheable(value = "staticResources", key = "'drawImage_' + #direction")
public String getImageUrl(int direction) {

Map<String, String> textContentMap = staticResourceUtil.getTextContentMap();

String directionImage;
if (direction == 0) {
directionImage = staticResourcesUtil.getData("draw_block_up_image");
directionImage = textContentMap.get(S3FileName.DRAW_BLOCK_UP_IMAGE.name());
} else if (direction == 1) {
directionImage = staticResourcesUtil.getData("draw_block_right_image");
directionImage = textContentMap.get(S3FileName.DRAW_BLOCK_RIGHT_IMAGE.name());
} else if (direction == 2) {
directionImage = staticResourcesUtil.getData("draw_block_down_image");
directionImage = textContentMap.get(S3FileName.DRAW_BLOCK_DOWN_IMAGE.name());
} else {
directionImage = staticResourcesUtil.getData("draw_block_left_image");
directionImage = textContentMap.get(S3FileName.DRAW_BLOCK_LEFT_IMAGE.name());
}
return directionImage;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,44 +51,16 @@ public ResponseDto<FcfsPageResponseDto> getFcfsTutorialPage() {
}

@PostMapping
public ResponseEntity<Void> handleFcfs(@Parameter(hidden = true) HttpServletRequest request,
public ResponseDto<FcfsResultResponseDto> handleFcfs(@Parameter(hidden = true) HttpServletRequest request,
@Parameter(hidden = true) @AuthInfo Integer userId,
@RequestBody FcfsRequestDto fcfsRequestDto) {

int round = (Integer) request.getAttribute("round");

String fcfsCode = fcfsService.handleFcfsEvent(userId, round, fcfsRequestDto);

log.info("fcfsCode in handleFcfs : {}", fcfsCode);

HttpHeaders headers = new HttpHeaders();
String redirectUrl = "https://softeer.shop/fcfs/result";

if(fcfsCode != null){
request.getSession().setAttribute("fcfsCode", fcfsCode);
redirectUrl += "?fcfsWin=" + URLEncoder.encode("true", StandardCharsets.UTF_8);
headers.add("Location", redirectUrl);
}
else{
redirectUrl += "?fcfsWin=" + URLEncoder.encode("true", StandardCharsets.UTF_8);
headers.add("Location", redirectUrl);
}

return new ResponseEntity<>(headers, HttpStatus.FOUND);
}

@GetMapping("/result")
public ResponseDto<FcfsResultResponseDto> getFcfsResult(@Parameter(hidden = true) HttpServletRequest request,
@RequestParam("fcfsWin") Boolean fcfsWin){


String fcfsCode = (String) request.getSession().getAttribute("fcfsCode");
log.info("fcfsCode in getFcfsResult : {}", fcfsCode);
request.getSession().invalidate();

FcfsResultResponseDto fcfsResultResponseDto = fcfsService.getFcfsResult(fcfsWin, fcfsCode);
FcfsResultResponseDto fcfsResultResponseDto = fcfsService.handleFcfsEvent(userId, round, fcfsRequestDto);

return ResponseDto.onSuccess(fcfsResultResponseDto);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@AllArgsConstructor(access = AccessLevel.PUBLIC)
@Builder
@Getter
@Setter
public class FcfsSuccessResult implements FcfsResult {

private String title;
Expand Down
Loading
Loading