From 2652fc14882aca8e988f0c1663e0a49f2fecf304 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 17:46:13 +0900 Subject: [PATCH 1/7] =?UTF-8?q?[Refactor,=20Feat]=20s3=20=EC=97=85?= =?UTF-8?q?=EB=A1=9C=EB=93=9C/=EB=8B=A4=EC=9A=B4=EB=A1=9C=EB=93=9C=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20presigned=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 13 +-- .../apiPayLoad/code/status/ErrorStatus.java | 3 +- .../java/umc/codeplay/config/AWSConfig.java | 35 +++++--- .../codeplay/controller/FileController.java | 37 ++++++++ .../umc/codeplay/controller/HealthCheck.java | 15 +--- .../umc/codeplay/domain/enums/AccessType.java | 3 + .../umc/codeplay/dto/FileResponseDTO.java | 20 +++++ .../umc/codeplay/service/FileService.java | 83 ++++++++++++++++++ .../java/umc/codeplay/service/S3Service.java | 87 ------------------- src/main/resources/application-prod.yml | 4 +- src/main/resources/application.yml | 4 +- 11 files changed, 182 insertions(+), 122 deletions(-) create mode 100644 src/main/java/umc/codeplay/controller/FileController.java create mode 100644 src/main/java/umc/codeplay/domain/enums/AccessType.java create mode 100644 src/main/java/umc/codeplay/dto/FileResponseDTO.java create mode 100644 src/main/java/umc/codeplay/service/FileService.java delete mode 100644 src/main/java/umc/codeplay/service/S3Service.java diff --git a/build.gradle b/build.gradle index 0341b86..63a437d 100644 --- a/build.gradle +++ b/build.gradle @@ -31,7 +31,7 @@ dependencies { compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' - // mysql 사용시 주석 해제 + // mysql implementation 'org.springframework.boot:spring-boot-starter-data-jpa' runtimeOnly 'com.mysql:mysql-connector-j' @@ -44,8 +44,11 @@ dependencies { testImplementation 'io.rest-assured:rest-assured:5.3.1' testRuntimeOnly 'com.h2database:h2' + // validation + implementation 'org.springframework.boot:spring-boot-starter-validation' + // 스웨거 - implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.4.0' // 스프링 시큐리티 implementation 'org.springframework.boot:spring-boot-starter-security' @@ -56,11 +59,9 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - // validation - implementation 'org.springframework.boot:spring-boot-starter-validation' - // s3 - implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' + implementation(platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.1.1")) + implementation("io.awspring.cloud:spring-cloud-aws-starter-s3") } tasks.named('test') { diff --git a/src/main/java/umc/codeplay/apiPayLoad/code/status/ErrorStatus.java b/src/main/java/umc/codeplay/apiPayLoad/code/status/ErrorStatus.java index c215100..aef257b 100644 --- a/src/main/java/umc/codeplay/apiPayLoad/code/status/ErrorStatus.java +++ b/src/main/java/umc/codeplay/apiPayLoad/code/status/ErrorStatus.java @@ -25,7 +25,8 @@ public enum ErrorStatus implements BaseErrorCode { ID_OR_PASSWORD_WRONG(HttpStatus.BAD_REQUEST, "AUTH401", "아이디 혹은 비밀번호가 잘못되었습니다."), INVALID_REFRESH_TOKEN(HttpStatus.BAD_REQUEST, "AUTH402", "유효하지 않은 리프레시 토큰입니다."), - AWS_SERVICE_UNAVAILABLE(HttpStatus.BAD_REQUEST, "AWS400", "AWS S3에 파일을 업로드할 수 없습니다."); + AWS_SERVICE_UNAVAILABLE(HttpStatus.BAD_REQUEST, "AWS400", "AWS S3에 파일을 업로드할 수 없습니다."), + AWS_METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, "AWS405", "해당 method는 허용되지 않습니다."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index f521913..516e435 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -4,10 +4,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import com.amazonaws.auth.AWSStaticCredentialsProvider; -import com.amazonaws.auth.BasicAWSCredentials; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.AmazonS3ClientBuilder; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.presigner.S3Presigner; @Configuration public class AWSConfig { @@ -22,13 +23,23 @@ public class AWSConfig { private String region; @Bean - public AmazonS3Client amazonS3Client() { - final BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); - - return (AmazonS3Client) - AmazonS3ClientBuilder.standard() - .withRegion(region) - .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) - .build(); + public S3Presigner s3Presigner() { + Region awsRegion = Region.of(region); + return S3Presigner.builder() + .region(awsRegion) + .credentialsProvider( + StaticCredentialsProvider.create( + AwsBasicCredentials.create(accessKey, secretKey))) + .build(); + } + + @Bean + public S3Client s3Client() { + Region awsRegion = Region.of(region); + AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); + return S3Client.builder() + .region(awsRegion) + .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + .build(); } } diff --git a/src/main/java/umc/codeplay/controller/FileController.java b/src/main/java/umc/codeplay/controller/FileController.java new file mode 100644 index 0000000..187ecb0 --- /dev/null +++ b/src/main/java/umc/codeplay/controller/FileController.java @@ -0,0 +1,37 @@ +package umc.codeplay.controller; + +import org.springframework.web.bind.annotation.*; + +import lombok.RequiredArgsConstructor; + +import software.amazon.awssdk.http.SdkHttpMethod; +import umc.codeplay.apiPayLoad.ApiResponse; +import umc.codeplay.dto.FileResponseDTO; +import umc.codeplay.service.FileService; + +import static umc.codeplay.service.FileService.buildFilename; + +@RestController +@RequestMapping("/files") +@RequiredArgsConstructor +public class FileController { + + private final FileService fileService; + + @GetMapping("download/{fileName}") + public ApiResponse getUrl(@PathVariable String fileName) { + String preSignedUrl = fileService.generatePreSignedUrl(fileName, SdkHttpMethod.GET); + FileResponseDTO.DownloadFile result = new FileResponseDTO.DownloadFile(preSignedUrl); + + return ApiResponse.onSuccess(result); + } + + @PostMapping("upload/{fileName}") + public ApiResponse generateUrl(@PathVariable String fileName) { + String newFileName = buildFilename(fileName); + String url = fileService.generatePreSignedUrl(newFileName, SdkHttpMethod.PUT); + FileResponseDTO.UploadFile result = new FileResponseDTO.UploadFile(newFileName, url); + + return ApiResponse.onSuccess(result); + } +} diff --git a/src/main/java/umc/codeplay/controller/HealthCheck.java b/src/main/java/umc/codeplay/controller/HealthCheck.java index 0b9da00..ff66ff8 100644 --- a/src/main/java/umc/codeplay/controller/HealthCheck.java +++ b/src/main/java/umc/codeplay/controller/HealthCheck.java @@ -1,13 +1,13 @@ package umc.codeplay.controller; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import lombok.RequiredArgsConstructor; import io.swagger.v3.oas.annotations.Hidden; -import umc.codeplay.service.S3Service; @Hidden @RestController @@ -15,18 +15,9 @@ @RequiredArgsConstructor public class HealthCheck { - private final S3Service s3Service; - // 연결 확인 용 @GetMapping("") public ResponseEntity healthCheck() { return ResponseEntity.ok("UMC 7th CodePlay Well Connected!"); } - - // s3 업로드 테스트 용 - @PostMapping("/s3") - public ResponseEntity s3HealthCheck(@RequestPart(value = "file") MultipartFile file) { - final String s3Url = s3Service.uploadFile(file); - return ResponseEntity.ok("S3 FIle is uploaded! : " + s3Url); - } } diff --git a/src/main/java/umc/codeplay/domain/enums/AccessType.java b/src/main/java/umc/codeplay/domain/enums/AccessType.java new file mode 100644 index 0000000..fd72ed4 --- /dev/null +++ b/src/main/java/umc/codeplay/domain/enums/AccessType.java @@ -0,0 +1,3 @@ +package umc.codeplay.domain.enums; + +public enum AccessType {} diff --git a/src/main/java/umc/codeplay/dto/FileResponseDTO.java b/src/main/java/umc/codeplay/dto/FileResponseDTO.java new file mode 100644 index 0000000..27e44a4 --- /dev/null +++ b/src/main/java/umc/codeplay/dto/FileResponseDTO.java @@ -0,0 +1,20 @@ +package umc.codeplay.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +public class FileResponseDTO { + + @Getter + @AllArgsConstructor + public static class DownloadFile { + private String s3URL; + } + + @Getter + @AllArgsConstructor + public static class UploadFile { + private String newFileName; + private String s3URL; + } +} diff --git a/src/main/java/umc/codeplay/service/FileService.java b/src/main/java/umc/codeplay/service/FileService.java new file mode 100644 index 0000000..3a67899 --- /dev/null +++ b/src/main/java/umc/codeplay/service/FileService.java @@ -0,0 +1,83 @@ +package umc.codeplay.service; + +import java.text.Normalizer; +import java.time.Duration; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; + +import software.amazon.awssdk.http.SdkHttpMethod; +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; +import umc.codeplay.apiPayLoad.exception.handler.GeneralHandler; + +@Service +@RequiredArgsConstructor +public class FileService { + + @Value("${cloud.aws.s3.bucket}") + private String bucketName; + + private final S3Presigner s3Presigner; + + // 타임스탬프_파일명 형식으로 파일 이름 저장 + public static String buildFilename(String filename) { + return String.format("%s_%s", System.currentTimeMillis(), sanitizeFileName(filename)); + } + + // 특수 문자나 공백 등을 정리 + private static String sanitizeFileName(String fileName) { + String normalizedFileName = Normalizer.normalize(fileName, Normalizer.Form.NFC); + return normalizedFileName.replaceAll("\\s+", "_").replaceAll("[^a-zA-Z0-9.\\-_]", ""); + } + + // 파일 업로드(HTTP PUT) 또는 다운로드(HTTP GET)를 위한 Presigned URL 생성 + public String generatePreSignedUrl(String fileName, SdkHttpMethod method) { + + return switch (method) { + case GET -> generateGetPresignedUrl(fileName); + case PUT -> generatePutPresignedUrl(fileName); + default -> throw new GeneralHandler(ErrorStatus.AWS_SERVICE_UNAVAILABLE); + }; + } + + // S3에서 파일을 다운로드할 수 있는 Presigned URL 생성 + private String generateGetPresignedUrl(String fileName) { + GetObjectRequest getObjectRequest = + GetObjectRequest.builder().bucket(bucketName).key(fileName).build(); + + GetObjectPresignRequest presignRequest = + GetObjectPresignRequest.builder() + .signatureDuration(Duration.ofMinutes(60)) + .getObjectRequest(getObjectRequest) + .build(); + + PresignedGetObjectRequest presignedRequest = s3Presigner.presignGetObject(presignRequest); + return presignedRequest.url().toString(); + } + + // S3에 파일을 업로드할 수 있는 Presigned URL 생성 + private String generatePutPresignedUrl(String fileName) { + PutObjectRequest putObjectRequest = + PutObjectRequest.builder().bucket(bucketName).key(fileName).build(); + + PutObjectPresignRequest presignRequest = + PutObjectPresignRequest.builder() + .signatureDuration(Duration.ofMinutes(60)) + .putObjectRequest(putObjectRequest) + .build(); + + PresignedPutObjectRequest presignedRequest = s3Presigner.presignPutObject(presignRequest); + return presignedRequest.url().toString(); + } + + // TODO: 필요시 직접 업로드 방법 구현 필요 +} diff --git a/src/main/java/umc/codeplay/service/S3Service.java b/src/main/java/umc/codeplay/service/S3Service.java deleted file mode 100644 index 1c58580..0000000 --- a/src/main/java/umc/codeplay/service/S3Service.java +++ /dev/null @@ -1,87 +0,0 @@ -package umc.codeplay.service; - -import java.io.ByteArrayInputStream; -import java.io.IOException; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import lombok.RequiredArgsConstructor; - -import com.amazonaws.AmazonClientException; -import com.amazonaws.services.s3.AmazonS3Client; -import com.amazonaws.services.s3.model.ObjectMetadata; -import com.amazonaws.services.s3.model.PutObjectRequest; -import com.amazonaws.util.IOUtils; -import umc.codeplay.apiPayLoad.code.status.ErrorStatus; -import umc.codeplay.apiPayLoad.exception.handler.GeneralHandler; - -@Service -@RequiredArgsConstructor -@Transactional -public class S3Service { - - @Value("${cloud.aws.s3.bucket}") - private String bucket; - - private final AmazonS3Client amazonS3Client; - - /* - s3에 파일 업로드 - */ - public String uploadFile(MultipartFile file) { - if (file.getOriginalFilename() == null || file.getOriginalFilename().isEmpty()) { - throw new GeneralHandler(ErrorStatus._BAD_REQUEST); - } - - final String fileName = newFileName(file.getOriginalFilename()); - - ObjectMetadata objectMetadata = new ObjectMetadata(); - try { - objectMetadata.setContentLength(file.getSize()); - objectMetadata.setContentType(file.getContentType()); - - /* - TODO: 용량 문제가 생긴다면 아래 ByteArrayInputStream 방식을 변경해야함 - 1. 임시파일 방식으로 변경 - 2. 가능한 용량 limit 설정 - */ - byte[] bytes = IOUtils.toByteArray(file.getInputStream()); - ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); - - PutObjectRequest putObjectRequest = - new PutObjectRequest(bucket, fileName, inputStream, objectMetadata); - amazonS3Client.putObject(putObjectRequest); - - inputStream.close(); - - } catch (AmazonClientException | IOException e) { - throw new GeneralHandler(ErrorStatus.AWS_SERVICE_UNAVAILABLE); - } - - return amazonS3Client.getUrl(bucket, fileName).toString(); - } - - /* - s3 업로드시 파일 이름 변경 - */ - private String newFileName(String fileName) { - - final String FILE_EXTENSION_SEPARATOR = "."; - final String now = String.valueOf(System.currentTimeMillis()); - - int fileExtensionIndex = fileName.lastIndexOf(FILE_EXTENSION_SEPARATOR); - if (fileExtensionIndex == -1) { - return fileName - + "_" - + System.currentTimeMillis(); // No extension found, just add timestamp - } - - final String fileExtension = fileName.substring(fileExtensionIndex); - final String originalFileName = fileName.substring(0, fileExtensionIndex); - - return originalFileName + "_" + now + fileExtension; - } -} diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 38f8888..0a322cc 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -32,8 +32,8 @@ cloud: aws: s3: bucket: ${S3_BUCKET} - stack.auto: false - region.static: ${AWS_DEFAULT_REGION} + region: + static: ${AWS_DEFAULT_REGION} credentials: accessKey: ${AWS_ACCESS_KEY_ID} secretKey: ${AWS_SECRET_ACCESS_KEY} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2baf714..b4abbeb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -32,8 +32,8 @@ cloud: aws: s3: bucket: ${S3_BUCKET} - stack.auto: false - region.static: ${AWS_DEFAULT_REGION} + region: + static: ${AWS_DEFAULT_REGION} credentials: accessKey: ${AWS_ACCESS_KEY_ID} secretKey: ${AWS_SECRET_ACCESS_KEY} From a9d7d45b255a5af5e9fa00a222e789b68419dccd Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 18:01:54 +0900 Subject: [PATCH 2/7] =?UTF-8?q?[fix]=20swagger=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?=EB=B0=8F=20=EC=97=90=EB=9F=AC=20=EC=BD=94=EB=93=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/umc/codeplay/config/AWSConfig.java | 19 +++++++++---------- .../codeplay/controller/FileController.java | 13 +++++++++---- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index 516e435..fadb624 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -7,7 +7,6 @@ import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.presigner.S3Presigner; @Configuration @@ -33,13 +32,13 @@ public S3Presigner s3Presigner() { .build(); } - @Bean - public S3Client s3Client() { - Region awsRegion = Region.of(region); - AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); - return S3Client.builder() - .region(awsRegion) - .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) - .build(); - } + // @Bean + // public S3Client s3Client() { + // Region awsRegion = Region.of(region); + // AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); + // return S3Client.builder() + // .region(awsRegion) + // .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + // .build(); + // } } diff --git a/src/main/java/umc/codeplay/controller/FileController.java b/src/main/java/umc/codeplay/controller/FileController.java index 187ecb0..f6e9e76 100644 --- a/src/main/java/umc/codeplay/controller/FileController.java +++ b/src/main/java/umc/codeplay/controller/FileController.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; +import io.swagger.v3.oas.annotations.Operation; import software.amazon.awssdk.http.SdkHttpMethod; import umc.codeplay.apiPayLoad.ApiResponse; import umc.codeplay.dto.FileResponseDTO; @@ -18,16 +19,20 @@ public class FileController { private final FileService fileService; - @GetMapping("download/{fileName}") - public ApiResponse getUrl(@PathVariable String fileName) { + @Operation(summary = "Download용 Presigned URL 생성", description = "다운로드를 위한 Presigned URL 생성") + @GetMapping("/presigned/download") + public ApiResponse getUrl( + @RequestParam(value = "filename") String fileName) { String preSignedUrl = fileService.generatePreSignedUrl(fileName, SdkHttpMethod.GET); FileResponseDTO.DownloadFile result = new FileResponseDTO.DownloadFile(preSignedUrl); return ApiResponse.onSuccess(result); } - @PostMapping("upload/{fileName}") - public ApiResponse generateUrl(@PathVariable String fileName) { + @Operation(summary = "Upload용 Presigned URL 생성", description = "업로드를 위한 Presigned URL 생성") + @PostMapping("/presigned/upload") + public ApiResponse generateUrl( + @RequestParam(value = "filename") String fileName) { String newFileName = buildFilename(fileName); String url = fileService.generatePreSignedUrl(newFileName, SdkHttpMethod.PUT); FileResponseDTO.UploadFile result = new FileResponseDTO.UploadFile(newFileName, url); From 4e1698e44dadd28b4ecd8b2b9ecea6d49df9dba4 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 18:07:42 +0900 Subject: [PATCH 3/7] =?UTF-8?q?[Fix]=20aws=20=EC=84=B8=ED=8C=85=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/umc/codeplay/config/AWSConfig.java | 24 ++++++++----------- src/main/resources/application-prod.yml | 2 -- src/main/resources/application.yml | 2 -- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index fadb624..9c479be 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -7,6 +7,7 @@ import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; +import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.presigner.S3Presigner; @Configuration @@ -18,27 +19,22 @@ public class AWSConfig { @Value("${cloud.aws.credentials.secretKey}") private String secretKey; - @Value("${cloud.aws.region.static}") - private String region; - @Bean public S3Presigner s3Presigner() { - Region awsRegion = Region.of(region); return S3Presigner.builder() - .region(awsRegion) + .region(Region.AP_SOUTH_2) .credentialsProvider( StaticCredentialsProvider.create( AwsBasicCredentials.create(accessKey, secretKey))) .build(); } - // @Bean - // public S3Client s3Client() { - // Region awsRegion = Region.of(region); - // AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); - // return S3Client.builder() - // .region(awsRegion) - // .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) - // .build(); - // } + @Bean + public S3Client s3Client() { + AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); + return S3Client.builder() + .region(Region.AP_SOUTH_2) + .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) + .build(); + } } diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 0a322cc..d07b115 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -32,8 +32,6 @@ cloud: aws: s3: bucket: ${S3_BUCKET} - region: - static: ${AWS_DEFAULT_REGION} credentials: accessKey: ${AWS_ACCESS_KEY_ID} secretKey: ${AWS_SECRET_ACCESS_KEY} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b4abbeb..7057595 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -32,8 +32,6 @@ cloud: aws: s3: bucket: ${S3_BUCKET} - region: - static: ${AWS_DEFAULT_REGION} credentials: accessKey: ${AWS_ACCESS_KEY_ID} secretKey: ${AWS_SECRET_ACCESS_KEY} From 91b3723de360bd7196bc28d45931a59243557a37 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 18:22:39 +0900 Subject: [PATCH 4/7] =?UTF-8?q?[Fix]=20=EC=93=B8=EB=AA=A8=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 5f0530d..afa7405 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -11,7 +11,6 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} S3_BUCKET: ${{ secrets.S3_BUCKET }} JWT_SECRET: ${{ secrets.JWT_SECRET }} From 23c0602bfd711a00fca68b23a87799a38ee0bb48 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 18:37:39 +0900 Subject: [PATCH 5/7] =?UTF-8?q?[Fix]=20s3client=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/umc/codeplay/config/AWSConfig.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index 9c479be..7e2d636 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -7,7 +7,6 @@ import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; import software.amazon.awssdk.regions.Region; -import software.amazon.awssdk.services.s3.S3Client; import software.amazon.awssdk.services.s3.presigner.S3Presigner; @Configuration @@ -28,13 +27,4 @@ public S3Presigner s3Presigner() { AwsBasicCredentials.create(accessKey, secretKey))) .build(); } - - @Bean - public S3Client s3Client() { - AwsBasicCredentials awsCredentials = AwsBasicCredentials.create(accessKey, secretKey); - return S3Client.builder() - .region(Region.AP_SOUTH_2) - .credentialsProvider(StaticCredentialsProvider.create(awsCredentials)) - .build(); - } } From 635774568bd737f1109033d5479ba3b8aef5d350 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sat, 25 Jan 2025 18:48:28 +0900 Subject: [PATCH 6/7] =?UTF-8?q?[Fix]=20aws=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=EB=B3=80=EC=88=98=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-test.yml | 1 + src/main/java/umc/codeplay/config/AWSConfig.java | 9 ++++++--- src/main/resources/application-prod.yml | 11 ++++++++--- src/main/resources/application.yml | 11 ++++++++--- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index afa7405..5f0530d 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -11,6 +11,7 @@ jobs: env: AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: ${{ secrets.AWS_DEFAULT_REGION }} S3_BUCKET: ${{ secrets.S3_BUCKET }} JWT_SECRET: ${{ secrets.JWT_SECRET }} diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index 7e2d636..5dda8f2 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -12,16 +12,19 @@ @Configuration public class AWSConfig { - @Value("${cloud.aws.credentials.accessKey}") + @Value("${spring.cloud.aws.credentials.accessKey}") private String accessKey; - @Value("${cloud.aws.credentials.secretKey}") + @Value("${spring.cloud.aws.credentials.secretKey}") private String secretKey; + @Value("${spring.cloud.aws.region.static}") + private String region; + @Bean public S3Presigner s3Presigner() { return S3Presigner.builder() - .region(Region.AP_SOUTH_2) + .region(Region.of(region)) .credentialsProvider( StaticCredentialsProvider.create( AwsBasicCredentials.create(accessKey, secretKey))) diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index d07b115..893e0bc 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -28,13 +28,18 @@ spring: use_sql_comments: true default_batch_fetch_size: 1000 # 배치 크기 설정 (성능 최적화) + cloud: + aws: + credentials: + accessKey: ${AWS_ACCESS_KEY_ID} + secretKey: ${AWS_SECRET_ACCESS_KEY} + region: + static: ${AWS_DEFAULT_REGION} + cloud: aws: s3: bucket: ${S3_BUCKET} - credentials: - accessKey: ${AWS_ACCESS_KEY_ID} - secretKey: ${AWS_SECRET_ACCESS_KEY} jwt: secret: ${JWT_SECRET} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7057595..61b70f5 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -28,13 +28,18 @@ spring: use_sql_comments: true default_batch_fetch_size: 1000 # 배치 크기 설정 (성능 최적화) + cloud: + aws: + credentials: + accessKey: ${AWS_ACCESS_KEY_ID} + secretKey: ${AWS_SECRET_ACCESS_KEY} + region: + static: ${AWS_DEFAULT_REGION} + cloud: aws: s3: bucket: ${S3_BUCKET} - credentials: - accessKey: ${AWS_ACCESS_KEY_ID} - secretKey: ${AWS_SECRET_ACCESS_KEY} jwt: secret: ${JWT_SECRET} \ No newline at end of file From a60a73c874417e2a86eea93c9263d11ec46ee226 Mon Sep 17 00:00:00 2001 From: 2020147542 Date: Sun, 26 Jan 2025 14:43:33 +0900 Subject: [PATCH 7/7] =?UTF-8?q?[Fix]=20aws=20s3=20=ED=99=98=EA=B2=BD=20?= =?UTF-8?q?=EB=B3=80=EC=88=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/umc/codeplay/config/AWSConfig.java | 4 ++-- src/main/java/umc/codeplay/service/FileService.java | 2 +- src/main/resources/application-prod.yml | 11 ++++------- src/main/resources/application.yml | 11 ++++------- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/java/umc/codeplay/config/AWSConfig.java b/src/main/java/umc/codeplay/config/AWSConfig.java index 5dda8f2..dea3721 100644 --- a/src/main/java/umc/codeplay/config/AWSConfig.java +++ b/src/main/java/umc/codeplay/config/AWSConfig.java @@ -12,10 +12,10 @@ @Configuration public class AWSConfig { - @Value("${spring.cloud.aws.credentials.accessKey}") + @Value("${spring.cloud.aws.credentials.access-key}") private String accessKey; - @Value("${spring.cloud.aws.credentials.secretKey}") + @Value("${spring.cloud.aws.credentials.secret-key}") private String secretKey; @Value("${spring.cloud.aws.region.static}") diff --git a/src/main/java/umc/codeplay/service/FileService.java b/src/main/java/umc/codeplay/service/FileService.java index 3a67899..bb85e45 100644 --- a/src/main/java/umc/codeplay/service/FileService.java +++ b/src/main/java/umc/codeplay/service/FileService.java @@ -23,7 +23,7 @@ @RequiredArgsConstructor public class FileService { - @Value("${cloud.aws.s3.bucket}") + @Value("${spring.cloud.aws.s3.bucket}") private String bucketName; private final S3Presigner s3Presigner; diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index 893e0bc..8a6d67e 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -30,16 +30,13 @@ spring: cloud: aws: + s3: + bucket: ${S3_BUCKET} credentials: - accessKey: ${AWS_ACCESS_KEY_ID} - secretKey: ${AWS_SECRET_ACCESS_KEY} + access-key: ${AWS_ACCESS_KEY_ID} + secret-key: ${AWS_SECRET_ACCESS_KEY} region: static: ${AWS_DEFAULT_REGION} -cloud: - aws: - s3: - bucket: ${S3_BUCKET} - jwt: secret: ${JWT_SECRET} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 61b70f5..c321666 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -30,16 +30,13 @@ spring: cloud: aws: + s3: + bucket: ${S3_BUCKET} credentials: - accessKey: ${AWS_ACCESS_KEY_ID} - secretKey: ${AWS_SECRET_ACCESS_KEY} + access-key: ${AWS_ACCESS_KEY_ID} + secret-key: ${AWS_SECRET_ACCESS_KEY} region: static: ${AWS_DEFAULT_REGION} -cloud: - aws: - s3: - bucket: ${S3_BUCKET} - jwt: secret: ${JWT_SECRET} \ No newline at end of file