Skip to content

Commit

Permalink
feat: 나만의 생일 축하 카드 생성을 위한 presigned url 발급 API (#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
hocaron authored Sep 22, 2024
2 parents 81d46c7 + 03d0029 commit 57f8dfe
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 8 deletions.
2 changes: 2 additions & 0 deletions mashup-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ dependencies{
annotationProcessor 'jakarta.persistence:jakarta.persistence-api'
annotationProcessor 'jakarta.annotation:jakarta.annotation-api'

implementation 'com.amazonaws:aws-java-sdk-s3:1.11.64'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package kr.mashup.branding.config;

import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3Client;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import static com.amazonaws.regions.Region.getRegion;
import static com.amazonaws.regions.Regions.*;

@Configuration
public class S3Config {

@Value("${aws.s3.access-key}")
private String accessKey;

@Value("${aws.s3.secret-key}")
private String secretKey;

@Bean
public AmazonS3Client amazonS3() {
AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials(accessKey, secretKey));
s3Client.setRegion(getRegion(AP_NORTHEAST_2));
return s3Client;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package kr.mashup.branding.service.birthday;

import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.Headers;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.Date;

@Service
@RequiredArgsConstructor
public class FileService {

private final AmazonS3Client amazonS3Client;

public String generatePresignedUrl(String bucket, String identifier, long expiresIn) {
String fileName = createFileName(identifier);
GeneratePresignedUrlRequest request = createPresignedUrlRequest(bucket, fileName, expiresIn);
return amazonS3Client.generatePresignedUrl(request).toString();
}

private GeneratePresignedUrlRequest createPresignedUrlRequest(String bucket, String filePath, long expiresIn) {
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucket, filePath)
.withMethod(HttpMethod.PUT)
.withExpiration(Date.from(Instant.now().plusSeconds(expiresIn)));
request.addRequestParameter(Headers.S3_CANNED_ACL, CannedAccessControlList.PublicRead.toString());

return request;
}

private String createFileName(String fileName) {
return String.format("%d-%s", System.currentTimeMillis(), fileName);
}
}
3 changes: 3 additions & 0 deletions mashup-domain/src/main/resources/application-develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ aws:
ses:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)
s3:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)

cipherKey: ENC(DvN35rX337al/XKbdH/YHkPyh/LKwqL30pi7pZmikFYPlDEa37Rcr4TkmW8v2m9+Pjrjmqvp0QSjC5NQyd7zaQ==)
cipherTime: 3600
3 changes: 3 additions & 0 deletions mashup-domain/src/main/resources/application-local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ aws:
ses:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)
s3:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)

cipherKey: ENC(DvN35rX337al/XKbdH/YHkPyh/LKwqL30pi7pZmikFYPlDEa37Rcr4TkmW8v2m9+Pjrjmqvp0QSjC5NQyd7zaQ==)
cipherTime: 3600
3 changes: 3 additions & 0 deletions mashup-domain/src/main/resources/application-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ aws:
ses:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)
s3:
access-key: ENC(aQntk9Wm8gCrHsIvt+q7+cIDTGI6hWIlRisZXE3q/BNACqKQXrXnpzrgnhHIpeALhhAe82v0niu93NTZyomkwQ==)
secret-key: ENC(/B1+2Mflsgv1enwFvvmdzffHKGM0F6MV/Of6hdLyE+f6zkDI25TF8Av502lO0cV7PeYKdHje0FJPo22idqzsVQaRN1QM9cqvHbs1hgudDkE=)

cipherKey: ENC(DvN35rX337al/XKbdH/YHkPyh/LKwqL30pi7pZmikFYPlDEa37Rcr4TkmW8v2m9+Pjrjmqvp0QSjC5NQyd7zaQ==)
cipherTime: 3
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@
import kr.mashup.branding.domain.member.MemberGeneration;
import kr.mashup.branding.domain.randommessage.RandomMessage;
import kr.mashup.branding.service.birthday.BirthdayCardService;
import kr.mashup.branding.service.birthday.FileService;
import kr.mashup.branding.service.member.MemberService;
import kr.mashup.branding.ui.birthday.request.BirthdayCardRequest;
import kr.mashup.branding.ui.birthday.response.BirthdayCardDefaultImageResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardImageResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardDefaultImagesResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardsResponse;
import kr.mashup.branding.ui.danggn.response.DanggnRandomMessageResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -25,17 +27,29 @@ public class BirthdayCardFacadeService {

private final BirthdayCardService birthdayCardService;
private final MemberService memberService;
private final FileService fileService;

@Value("${aws.s3.birthday.bucket-name}")
private String bucketName;

@Value("${aws.s3.birthday.expires-in}")
private long expiresIn;

@Transactional(readOnly = true)
public BirthdayCardDefaultImagesResponse getDefault() {
List<BirthdayCardDefaultImageResponse> cardImages = birthdayCardService.getDefault()
List<BirthdayCardImageResponse> cardImages = birthdayCardService.getDefault()
.stream()
.map(cardImage -> BirthdayCardDefaultImageResponse.of(cardImage.getImageUrl()))
.map(cardImage -> BirthdayCardImageResponse.of(cardImage.getImageUrl()))
.collect(Collectors.toList());

return BirthdayCardDefaultImagesResponse.of(cardImages);
}

public BirthdayCardImageResponse generatePresignedUrl(long memberId) {

return BirthdayCardImageResponse.of(fileService.generatePresignedUrl(bucketName, String.valueOf(memberId), expiresIn));
}

@Transactional
public void send(Long memberId, BirthdayCardRequest request) {
Member senderMember = memberService.findMemberById(memberId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import kr.mashup.branding.ui.ApiResponse;
import kr.mashup.branding.ui.birthday.request.BirthdayCardRequest;
import kr.mashup.branding.ui.birthday.response.BirthdayCardDefaultImagesResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardImageResponse;
import kr.mashup.branding.ui.birthday.response.BirthdayCardsResponse;
import kr.mashup.branding.ui.danggn.response.DanggnRandomMessageResponse;
import lombok.RequiredArgsConstructor;
Expand All @@ -31,6 +32,15 @@ public ApiResponse<BirthdayCardDefaultImagesResponse> getDefault() {
return ApiResponse.success(response);
}

@ApiOperation("생일카드 이미지 업로드용 Presigned URL 발급")
@GetMapping("/images/presigned-url")
public ApiResponse<BirthdayCardImageResponse> generatePresignedUrl(@ApiIgnore MemberAuth memberAuth) {
final BirthdayCardImageResponse response
= birthdayCardFacadeService.generatePresignedUrl(memberAuth.getMemberId());

return ApiResponse.success(response);
}

@ApiOperation("생일 축하 카드 보내기")
@PostMapping
public ApiResponse<String> send(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
@Getter
@Value(staticConstructor = "of")
public class BirthdayCardDefaultImagesResponse {
List<BirthdayCardDefaultImageResponse> defaultImages;
List<BirthdayCardImageResponse> defaultImages;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@

@Getter
@Value(staticConstructor = "of")
public class BirthdayCardDefaultImageResponse {
public class BirthdayCardImageResponse {
String imageUrl;
}
8 changes: 7 additions & 1 deletion mashup-member/src/main/resources/member-develop.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
jwt:
secretKey: ENC(EXfj1mGmsws/YLOc87IZoiHu0l+vKqtao+CrUR843UD0xWM9asYfSMWkYLI8CYQHlEeHwAh51Kt+/Zn8tS7n0g==)
golden-danggn-percent: 1
golden-danggn-percent: 1

aws:
s3:
birthday:
bucket-name: ENC(L67K3xOrB7AFVc42ntwiU30LIvXrQgBs3WL7rDEA68adLfqk1mNCgX8Vgi2k+r+KQWbMF4ukynROsDBRbdk0bA==)
expires-in: 120 # 2 minutes
8 changes: 7 additions & 1 deletion mashup-member/src/main/resources/member-local.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
jwt:
secretKey: ENC(EXfj1mGmsws/YLOc87IZoiHu0l+vKqtao+CrUR843UD0xWM9asYfSMWkYLI8CYQHlEeHwAh51Kt+/Zn8tS7n0g==)
golden-danggn-percent: 1
golden-danggn-percent: 1

aws:
s3:
birthday:
bucket-name: ENC(5wfapIYEplDWd9xav8HeC99yHvZKGzVbNfvAYu/G1dJmaD2Xj9B6YwPBGzF1pMcwb6jb5bF4AjlOTG9TM5ASBQ==)
expires-in: 120 # 2 minutes
8 changes: 7 additions & 1 deletion mashup-member/src/main/resources/member-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ jwt:
springfox:
documentation:
enabled: false
golden-danggn-percent: 1
golden-danggn-percent: 1

aws:
s3:
birthday:
bucket-name: ENC(A5LA3eJ87Uq1p1Ym2tcgoK0Tf+xOqiT6kzqA9gAMv6yaKOAKOVCBx9m1YGWZbZ1PED8rR9xbygwydn7hqyKN/Q==)
expires-in: 120 # 2 minutes

0 comments on commit 57f8dfe

Please sign in to comment.