Skip to content

Commit

Permalink
[merge] S3 presignedUrl 적용해서 createdRecord 수정
Browse files Browse the repository at this point in the history
[refactor] S3 presignedUrl 적용해서 createdRecord 수정
  • Loading branch information
sebbbin authored Jul 15, 2024
2 parents bfe2a64 + 87f84ee commit 19148eb
Show file tree
Hide file tree
Showing 14 changed files with 86 additions and 61 deletions.
3 changes: 2 additions & 1 deletion src/main/java/org/recordy/server/keyword/domain/Keyword.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.stream.Collectors;

public enum Keyword {

Expand Down Expand Up @@ -38,6 +39,6 @@ public static List<Keyword> decode(String utf8Bytes) {

return Arrays.stream(keywords)
.map(Keyword::valueOf)
.toList();
.collect(Collectors.toList());
}
}
14 changes: 4 additions & 10 deletions src/main/java/org/recordy/server/record/controller/RecordApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,10 @@ public interface RecordApi {
description = "유저가 레코드를 생성하는 API입니다. 파일과 함께 레코드 정보를 전송합니다.",
responses = {
@ApiResponse(
responseCode = "201",
responseCode = "200",
description = "레코드가 성공적으로 생성되었습니다.",
content = @Content(
mediaType = MediaType.APPLICATION_JSON_VALUE,
schema = @Schema(
implementation = Record.class
)
mediaType = MediaType.APPLICATION_JSON_VALUE
)
),
@ApiResponse(
Expand Down Expand Up @@ -77,12 +74,9 @@ public interface RecordApi {
)
}
)
ResponseEntity<Record> createRecord(
public ResponseEntity<Void> createRecord(
@UserId Long uploaderId,
@RequestPart RecordCreateRequest request,
@RequestPart MultipartFile thumbnail,
@RequestPart MultipartFile video
) ;
@RequestBody RecordCreateRequest request);

@Operation(
summary = "레코드 삭제 API",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,49 @@
import org.recordy.server.record.domain.usecase.RecordCreate;
import org.recordy.server.record.service.RecordService;
import org.recordy.server.record_stat.service.RecordStatService;
import org.recordy.server.record.service.S3Service;
import org.recordy.server.record.service.dto.FileUrl;
import org.springframework.data.domain.Slice;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;


@RequiredArgsConstructor
@RequestMapping("/api/v1/records")
@RestController
public class RecordController implements RecordApi {

private final RecordService recordService;
private final RecordStatService recordStatService;
private final S3Service s3Service;

@GetMapping("/presigned-url")
public ResponseEntity<FileUrl> getPresignedUrls() {
return ResponseEntity
.status(HttpStatus.OK)
.body(new FileUrl(
s3Service.generatePresignedUrl("videos/"),
s3Service.generatePresignedUrl("thumbnails/")
));
}

@Override
@PostMapping
public ResponseEntity<Record> createRecord(
public ResponseEntity<Void> createRecord(
@UserId Long uploaderId,
@RequestPart RecordCreateRequest request,
@RequestPart MultipartFile thumbnail,
@RequestPart MultipartFile video
) {
RecordCreate recordCreate = RecordCreate.of(uploaderId, request);
Record record = recordService.create(recordCreate, File.of(video, thumbnail));
@RequestBody RecordCreateRequest request) {
RecordCreate recordCreate = RecordCreate.from(uploaderId, request);
Record record = recordService.create(recordCreate, new File(request.fileUrl().videoUrl(), request.fileUrl().thumbnailUrl()));

return ResponseEntity
.status(HttpStatus.CREATED)
.body(record);
.ok()
.build();
}


@Override
@DeleteMapping("/{recordId}")
public ResponseEntity<Void> deleteRecord(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
public record RecordCreateRequest(
String location,
String content,
String keywords) {
String keywords,
FileUrl fileUrl
) {
}
30 changes: 12 additions & 18 deletions src/main/java/org/recordy/server/record/domain/File.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
package org.recordy.server.record.domain;

import org.springframework.web.multipart.MultipartFile;
public record File (
String videoUrl,
String thumbnailUrl) {

import java.util.UUID;

public record File(
MultipartFile video,
MultipartFile thumbnail
) {

public static File of(MultipartFile video, MultipartFile thumbnail) {
return new File(video, thumbnail);
public File(String videoUrl, String thumbnailUrl) {
this.videoUrl = videoUrl;
this.thumbnailUrl = thumbnailUrl;
}

public String generateFileName(MultipartFile file) {
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
return UUID.randomUUID() + extension;
public String getVideoUrl() {
return videoUrl;
}

public String getVideoFileName() {
return generateFileName(video);
public String getThumbnailUrl() {
return thumbnailUrl;
}

public String getThumbnailFileName() {
return generateFileName(thumbnail);
public static File of(String videoUrl, String thumbnailUrl) {
return new File(videoUrl, thumbnailUrl);
}
}
2 changes: 2 additions & 0 deletions src/main/java/org/recordy/server/record/domain/Record.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.recordy.server.record.domain;

import java.time.LocalDateTime;

import jakarta.persistence.Column;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@

import org.recordy.server.keyword.domain.Keyword;
import org.recordy.server.record.controller.dto.request.RecordCreateRequest;
import org.recordy.server.record.service.dto.FileUrl;

import java.util.List;

public record RecordCreate(
long uploaderId,
String location,
String content,
List<Keyword> keywords
List<Keyword> keywords,
FileUrl fileUrl
) {

public static RecordCreate of(Long uploaderId, RecordCreateRequest recordCreateRequest) {
return new RecordCreate(
uploaderId,
recordCreateRequest.location(),
recordCreateRequest.content(),
Keyword.decode(recordCreateRequest.keywords())
Keyword.decode(recordCreateRequest.keywords()),
recordCreateRequest.fileUrl()
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
public interface S3Service {

// command
public String getPresignUrl(String filename);
String uploadFile(byte[] fileData, String fileName) throws IOException;

String generatePresignedUrl(String directory);
String getPresignUrl(String filename);
// query


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package org.recordy.server.record.service.dto;

import jakarta.persistence.Column;

public record FileUrl(
String videoUrl,
String thumbnailUrl
) {
public static FileUrl of(String videoUrl, String thumbnailUrl) {
return new FileUrl(videoUrl, thumbnailUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,36 @@

import lombok.RequiredArgsConstructor;
import org.recordy.server.common.message.ErrorMessage;
import org.recordy.server.record.service.S3Service;
import org.recordy.server.record.exception.RecordException;
import org.recordy.server.record.service.FileService;
import org.recordy.server.record.domain.File;
import org.recordy.server.record.service.dto.FileUrl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;

import java.io.IOException;
import java.util.UUID;

@RequiredArgsConstructor
@Service
public class FileServiceImpl implements FileService {

private final S3Service s3Service;
private final S3Client s3Client;

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

@Override
public FileUrl save(File file) {
try {
String videoFileName = file.getVideoFileName();
String thumbnailFileName = file.getThumbnailFileName();

String videoUrl = s3Service.uploadFile(file.video().getBytes(), "videos/" + videoFileName);
String thumbnailUrl = s3Service.uploadFile(file.thumbnail().getBytes(), "thumbnails/" + thumbnailFileName);
String videoUrl = file.videoUrl();
String thumbnailUrl = file.thumbnailUrl();

return new FileUrl(videoUrl, thumbnailUrl);
} catch (IOException e) {
} catch (Exception e) {
throw new RecordException(ErrorMessage.FAILED_TO_UPLOAD_TO_S3);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.recordy.server.record.repository.RecordRepository;
import org.recordy.server.record.service.FileService;
import org.recordy.server.record.service.RecordService;
import org.recordy.server.record.service.S3Service;
import org.recordy.server.record.service.dto.FileUrl;
import org.recordy.server.record_stat.domain.View;
import org.recordy.server.record_stat.repository.ViewRepository;
Expand All @@ -35,10 +36,12 @@ public class RecordServiceImpl implements RecordService {

private final RecordRepository recordRepository;
private final ViewRepository viewRepository;
private final FileService fileService;
private final UserService userService;
private final S3Service s3Service;
private final FileService fileService;
private final RecordStatService recordStatService;


@Override
public Record create(RecordCreate recordCreate, File file) {
FileUrl fileUrl = fileService.save(file);
Expand All @@ -54,6 +57,7 @@ public Record create(RecordCreate recordCreate, File file) {
.build());
}


@Override
public void delete(long userId, long recordId) {
Record record = recordRepository.findById(recordId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@
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.PutObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;

import java.io.IOException;
import java.time.Duration;
import java.util.UUID;

@Component
@RequiredArgsConstructor
Expand Down Expand Up @@ -48,14 +51,20 @@ public String getPresignUrl(String filename) {
}

@Override
public String uploadFile(byte[] fileData, String fileName) throws IOException {
public String generatePresignedUrl(String directory) {
String fileName = directory + UUID.randomUUID().toString();
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(bucket)
.key(fileName)
.build();

s3Client.putObject(putObjectRequest, RequestBody.fromBytes(fileData));
PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
.signatureDuration(Duration.ofMinutes(10))
.putObjectRequest(putObjectRequest)
.build();

PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);

return getPresignUrl(fileName);
return presignedRequest.url().toString();
}
}
2 changes: 0 additions & 2 deletions src/test/java/org/recordy/server/mock/FakeContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.recordy.server.mock.user.FakeUserRepository;
import org.recordy.server.mock.view.FakeViewRepository;
import org.recordy.server.record.repository.RecordRepository;
import org.recordy.server.record.service.FileService;
import org.recordy.server.record.service.RecordService;
import org.recordy.server.record.service.impl.RecordServiceImpl;
import org.recordy.server.record_stat.repository.BookmarkRepository;
Expand Down Expand Up @@ -73,7 +72,6 @@ public class FakeContainer {
public final AuthTokenService authTokenService;
public final AuthService authService;
public final UserService userService;
public final FileService fileService;
public final RecordService recordService;
public final KeywordService keywordService;
public final RecordStatService recordStatService;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package org.recordy.server.mock.record;

import org.recordy.server.record.domain.File;
import org.recordy.server.record.service.FileService;
import org.recordy.server.record.service.dto.FileUrl;
import org.recordy.server.util.DomainFixture;

public class FakeFileService implements FileService {
public class FakeFileService {

@Override
public FileUrl save(File file) {
Expand Down

0 comments on commit 19148eb

Please sign in to comment.