Skip to content

Commit

Permalink
[Feat] 정적 파일 캐싱하기 (#161)
Browse files Browse the repository at this point in the history
* [Infra] CI/CD test (#42)

* infra: 빌드 테스트 yml 작성

* infra: DB 정보 추가

* infra: ssh-agent 버전 변경

* infra: known_hosts 추가

* infra: db port 변경

* infra: database test 설정 변경

* infra: DB 환경변수 설정 및 application.yml 생성

* infra: application.yml 동적 생성 스크립트 수정

* infra: 레디스 설정 추가

* infra: redis test 추가

* infra: redis 버전 변경

* infra: redis cli 설치

* infra: application.yml 위치 및 내용 확인

* infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가

* infra: 환경변수 확인 추가

* infra: zip file 만들기 추가, AWS credentials 추가

* infra: 환경변수 이름 변경

- ARN -> AWS_ARN

* infra: s3 bucket에 업로드 추가

* infra: code deploy 추가

* infra: code deploy 수정

* infra: code deploy 수정

* infra: appspec.yml 작성

* infra: application.yml 생성 경로 변경

* infra: application.yml 확인 스크립트 삭제

* infra: application.yml 생성 스크립트 수정

* infra: application-prod.yml 추가

* infra: appspec.yml 수정, 배포를 위한 sh파일 추가

* infra: deploy.yml 이름 변경

- test_deploy -> deploy

* infra: body = null 설정

* infra: develop에 머지되었을 때만 발동하도록 수정

* feat: draw_rank column 이름 수정

* Infra: environment 삭제

* [Infra] CI CD test 3 (#45)

* infra: 빌드 테스트 yml 작성

* infra: DB 정보 추가

* infra: ssh-agent 버전 변경

* infra: known_hosts 추가

* infra: db port 변경

* infra: database test 설정 변경

* infra: DB 환경변수 설정 및 application.yml 생성

* infra: application.yml 동적 생성 스크립트 수정

* infra: 레디스 설정 추가

* infra: redis test 추가

* infra: redis 버전 변경

* infra: redis cli 설치

* infra: application.yml 위치 및 내용 확인

* infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가

* infra: 환경변수 확인 추가

* infra: zip file 만들기 추가, AWS credentials 추가

* infra: 환경변수 이름 변경

- ARN -> AWS_ARN

* infra: s3 bucket에 업로드 추가

* infra: code deploy 추가

* infra: code deploy 수정

* infra: code deploy 수정

* infra: appspec.yml 작성

* infra: application.yml 생성 경로 변경

* infra: application.yml 확인 스크립트 삭제

* infra: application.yml 생성 스크립트 수정

* infra: application-prod.yml 추가

* infra: appspec.yml 수정, 배포를 위한 sh파일 추가

* infra: deploy.yml 이름 변경

- test_deploy -> deploy

* infra: body = null 설정

* infra: develop에 머지되었을 때만 발동하도록 수정

* feat: draw_rank column 이름 수정

* Infra: environment 삭제

* Infra: environment 삭제

* config: jwt 속성을 yml에 설정

* rebase: 원본 develop 브랜치와 병합

* feat: Caffeine cache 설정

* feat: 메인페이지 이벤트 정보 응답 dto 구현

* feat: s3 파일 이름을 enum으로 관리하도록 구현

* feat: static 자원 util 클래스 구현

* feat: 정적 텍스트 entity 구현

* feat: 정적 텍스트 repository 구현

* config: 의존성 설정

- spring cache 설정
- caffeine cache 설정

* chore: import문 삭제

* refactor: 정적 자원 가져오는 로직 변경

* refactor: 클래스 삭제

* feat: etag 필터 등록

* feat: 정적 텍스트의 이름을 관리하는 enum 구현

* refactor: 문자열을 상수로 관리

* feat: s3content repository 구현

* refactor: DB 테이블명 변경

* refactor: redis key 상수 변경

* refactor: 전화번호 regex 변경

* refactor: 코드 리팩토링

* refactor: 필드 삭제

* feat: 이벤트 페이지 정보를 응답하는 메서드 구현

* feat: 인증검사를 하지 않는 url 설정

* feat: setter 설정

* feat: 선착순 결과 캐싱하기

* refactor: redirect 하지 않도록 변경

* refactor: 정적 자원 가져오는 로직 변경

* refactor: 문자열을 상수로 관리

* [Infra] CI/CD test (#42)

* infra: 빌드 테스트 yml 작성

* infra: DB 정보 추가

* infra: ssh-agent 버전 변경

* infra: known_hosts 추가

* infra: db port 변경

* infra: database test 설정 변경

* infra: DB 환경변수 설정 및 application.yml 생성

* infra: application.yml 동적 생성 스크립트 수정

* infra: 레디스 설정 추가

* infra: redis test 추가

* infra: redis 버전 변경

* infra: redis cli 설치

* infra: application.yml 위치 및 내용 확인

* infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가

* infra: 환경변수 확인 추가

* infra: zip file 만들기 추가, AWS credentials 추가

* infra: 환경변수 이름 변경

- ARN -> AWS_ARN

* infra: s3 bucket에 업로드 추가

* infra: code deploy 추가

* infra: code deploy 수정

* infra: code deploy 수정

* infra: appspec.yml 작성

* infra: application.yml 생성 경로 변경

* infra: application.yml 확인 스크립트 삭제

* infra: application.yml 생성 스크립트 수정

* infra: application-prod.yml 추가

* infra: appspec.yml 수정, 배포를 위한 sh파일 추가

* infra: deploy.yml 이름 변경

- test_deploy -> deploy

* infra: body = null 설정

* infra: develop에 머지되었을 때만 발동하도록 수정

* feat: draw_rank column 이름 수정

* Infra: environment 삭제

* [Infra] CI CD test 3 (#45)

* infra: 빌드 테스트 yml 작성

* infra: DB 정보 추가

* infra: ssh-agent 버전 변경

* infra: known_hosts 추가

* infra: db port 변경

* infra: database test 설정 변경

* infra: DB 환경변수 설정 및 application.yml 생성

* infra: application.yml 동적 생성 스크립트 수정

* infra: 레디스 설정 추가

* infra: redis test 추가

* infra: redis 버전 변경

* infra: redis cli 설치

* infra: application.yml 위치 및 내용 확인

* infra: Github Actions 환경변수에 REDIS_HOST, REDIS_PORT 추가

* infra: 환경변수 확인 추가

* infra: zip file 만들기 추가, AWS credentials 추가

* infra: 환경변수 이름 변경

- ARN -> AWS_ARN

* infra: s3 bucket에 업로드 추가

* infra: code deploy 추가

* infra: code deploy 수정

* infra: code deploy 수정

* infra: appspec.yml 작성

* infra: application.yml 생성 경로 변경

* infra: application.yml 확인 스크립트 삭제

* infra: application.yml 생성 스크립트 수정

* infra: application-prod.yml 추가

* infra: appspec.yml 수정, 배포를 위한 sh파일 추가

* infra: deploy.yml 이름 변경

- test_deploy -> deploy

* infra: body = null 설정

* infra: develop에 머지되었을 때만 발동하도록 수정

* feat: draw_rank column 이름 수정

* Infra: environment 삭제

* Infra: environment 삭제

* config: jwt 속성을 yml에 설정

* rebase: 원본 develop 브랜치와 병합

* feat: Caffeine cache 설정

* feat: 메인페이지 이벤트 정보 응답 dto 구현

* feat: s3 파일 이름을 enum으로 관리하도록 구현

* feat: static 자원 util 클래스 구현

* feat: 정적 텍스트 entity 구현

* feat: 정적 텍스트 repository 구현

* config: 의존성 설정

- spring cache 설정
- caffeine cache 설정

* chore: import문 삭제

* refactor: 정적 자원 가져오는 로직 변경

* refactor: 클래스 삭제

* feat: etag 필터 등록

* feat: 정적 텍스트의 이름을 관리하는 enum 구현

* rebase: 원본 repo develop 브랜치와 충돌 해결

* feat: s3content repository 구현

* refactor: DB 테이블명 변경

* refactor: redis key 상수 변경

* refactor: 전화번호 regex 변경

* refactor: 코드 리팩토링

* refactor: 필드 삭제

* feat: 이벤트 페이지 정보를 응답하는 메서드 구현

* feat: 인증검사를 하지 않는 url 설정

* feat: setter 설정

* feat: 선착순 결과 캐싱하기

* refactor: redirect 하지 않도록 변경

* refactor: 정적 자원 가져오는 로직 변경

* refactor: 문자열을 상수로 관리

* refactor: 변수명 변경

---------

Co-authored-by: DrRivaski <[email protected]>
Co-authored-by: hyeokson <[email protected]>
  • Loading branch information
3 people authored Aug 19, 2024
1 parent 8ad2ac2 commit cf3f1e4
Show file tree
Hide file tree
Showing 28 changed files with 735 additions and 522 deletions.
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

0 comments on commit cf3f1e4

Please sign in to comment.