Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 10 additions & 17 deletions src/main/java/umc/codeplay/controller/FileController.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package umc.codeplay.controller;

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import lombok.RequiredArgsConstructor;

import io.swagger.v3.oas.annotations.Operation;
import umc.codeplay.apiPayLoad.ApiResponse;
import umc.codeplay.domain.enums.FileType;
import umc.codeplay.dto.FileResponseDTO;
import umc.codeplay.service.FileService;

Expand All @@ -19,31 +23,20 @@ public class FileController {

private final FileService fileService;

@Operation(
summary = "Download용 Presigned URL 생성",
description = "다운로드를 위한 Presigned URL 생성 - 유효시간 존재")
@GetMapping("/download")
public ApiResponse<FileResponseDTO.DownloadFile> getUrl(
@RequestParam(value = "musicId") Long musicId) {
String downloadUrl = fileService.generateGetPresignedUrl(musicId);
FileResponseDTO.DownloadFile result = new FileResponseDTO.DownloadFile(downloadUrl);
return ApiResponse.onSuccess(result);
}

@Operation(
summary = "Upload용 Presigned URL 생성",
description = "업로드를 위한 Presigned URL 생성 - 유효시간 존재")
@PostMapping("/upload")
public ApiResponse<FileResponseDTO.UploadFile> generateUrl(
@RequestParam(value = "fileType") FileType fileType,
@RequestParam(value = "fileName") String fileName) {

String username = SecurityContextHolder.getContext().getAuthentication().getName();
String newFileName = buildFilename(fileName);
System.out.println(newFileName);
Long musicId = fileService.uploadMusic(newFileName, username);
String newFileName = fileType.getFolderName() + buildFilename(fileName);

Long id = fileType.processUpload(fileService, newFileName, username);
String uploadUrl = fileService.generatePutPresignedUrl(newFileName);
FileResponseDTO.UploadFile result = new FileResponseDTO.UploadFile(uploadUrl, musicId);
return ApiResponse.onSuccess(result);

return ApiResponse.onSuccess(fileType.createResponse(uploadUrl, id));
}
}
39 changes: 39 additions & 0 deletions src/main/java/umc/codeplay/domain/enums/FileType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package umc.codeplay.domain.enums;

import umc.codeplay.dto.FileResponseDTO;
import umc.codeplay.service.FileService;

public enum FileType {
AUDIO {
public String getFolderName() {
return "requestFiles/";
}

public Long processUpload(FileService fileService, String fileName, String username) {
return fileService.uploadMusic(fileName, username);
}

public FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id) {
return new FileResponseDTO.UploadFile(uploadUrl, id, null);
}
},
IMAGE {
public String getFolderName() {
return "profileImgs/";
}

public Long processUpload(FileService fileService, String fileName, String username) {
return fileService.uploadProfile(fileName, username);
}

public FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id) {
return new FileResponseDTO.UploadFile(uploadUrl, null, id);
}
};

public abstract String getFolderName();

public abstract Long processUpload(FileService fileService, String fileName, String username);

public abstract FileResponseDTO.UploadFile createResponse(String uploadUrl, Long id);
}
7 changes: 1 addition & 6 deletions src/main/java/umc/codeplay/dto/FileResponseDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,11 @@

public class FileResponseDTO {

@Getter
@AllArgsConstructor
public static class DownloadFile {
private String downloadS3Url;
}

@Getter
@AllArgsConstructor
public static class UploadFile {
private String uploadS3Url;
private Long musicId;
private Long memberId;
}
}
45 changes: 14 additions & 31 deletions src/main/java/umc/codeplay/service/FileService.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@

import lombok.RequiredArgsConstructor;

import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
import umc.codeplay.apiPayLoad.code.status.ErrorStatus;
Expand Down Expand Up @@ -48,31 +45,6 @@ private static String sanitizeFileName(String fileName) {
return normalizedFileName.replaceAll("\\s+", "_").replaceAll("[^가-힣a-zA-Z0-9.\\-_]", "_");
}

// S3에서 파일을 다운로드할 수 있는 Presigned URL 생성
public String generateGetPresignedUrl(Long musicId) {
try {
Music music =
musicRepository
.findById(musicId)
.orElseThrow(() -> new GeneralHandler(ErrorStatus.MUSIC_NOT_FOUND));

GetObjectRequest getObjectRequest =
GetObjectRequest.builder().bucket(bucketName).key(music.getTitle()).build();

GetObjectPresignRequest presignRequest =
GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(60))
.getObjectRequest(getObjectRequest)
.build();

PresignedGetObjectRequest presignedRequest =
s3Presigner.presignGetObject(presignRequest);
return presignedRequest.url().toString();
} catch (Exception e) {
throw new GeneralHandler(ErrorStatus.AWS_SERVICE_UNAVAILABLE);
}
}

// S3에 파일을 업로드할 수 있는 Presigned URL 생성
public String generatePutPresignedUrl(String fileName) {
try {
Expand All @@ -93,6 +65,20 @@ public String generatePutPresignedUrl(String fileName) {
}
}

// User 레포지토리에 업로드
public Long uploadProfile(String newFileName, String userEmail) {
Member member =
memberRepository
.findByEmail(userEmail)
.orElseThrow(() -> new GeneralHandler(ErrorStatus.MEMBER_NOT_FOUND));

String s3Url =
String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, newFileName);

member.setProfileUrl(s3Url);
return memberRepository.save(member).getId();
}

// music 레포지토리에 업로드
public Long uploadMusic(String newFileName, String userEmail) {
Member member =
Expand All @@ -101,13 +87,10 @@ public Long uploadMusic(String newFileName, String userEmail) {
.orElseThrow(() -> new GeneralHandler(ErrorStatus.MEMBER_NOT_FOUND));

// 저장하는 url은 유효시간이 없는 public
// TODO: 업로드에만 presigned 사용할지 아님 다운로드시에도 사용할지에 따라 변경해야함.
String s3Url =
String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, newFileName);
Music newMusic = Music.builder().title(newFileName).musicUrl(s3Url).member(member).build();

return musicRepository.save(newMusic).getId();
}

// TODO: 필요시 직접 업로드 방법 구현 필요
}
Loading