-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
128 additions
and
0 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
carrotMarket/src/main/java/org/sopt/carrotMarket/external/AwsConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.sopt.carrotMarket.external; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.context.annotation.Configuration; | ||
import software.amazon.awssdk.auth.credentials.SystemPropertyCredentialsProvider; | ||
import software.amazon.awssdk.regions.Region; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
|
||
@Configuration | ||
public class AwsConfig { | ||
|
||
private static final String AWS_ACCESS_KEY_ID = "aws.accessKeyId"; | ||
private static final String AWS_SECRET_ACCESS_KEY = "aws.secretAccessKey"; | ||
|
||
private final String accessKey; | ||
private final String secretKey; | ||
private final String regionString; | ||
|
||
public AwsConfig(@Value("${aws-property.access-key}") final String accessKey, | ||
@Value("${aws-property.secret-key}") final String secretKey, | ||
@Value("${aws-property.aws-region}") final String regionString) { | ||
this.accessKey = accessKey; | ||
this.secretKey = secretKey; | ||
this.regionString = regionString; | ||
} | ||
|
||
|
||
@Bean | ||
public SystemPropertyCredentialsProvider systemPropertyCredentialsProvider() { | ||
System.setProperty(AWS_ACCESS_KEY_ID, accessKey); | ||
System.setProperty(AWS_SECRET_ACCESS_KEY, secretKey); | ||
return SystemPropertyCredentialsProvider.create(); | ||
} | ||
|
||
@Bean | ||
public Region getRegion() { | ||
return Region.of(regionString); | ||
} | ||
|
||
@Bean | ||
public S3Client getS3Client() { | ||
return S3Client.builder() | ||
.region(getRegion()) | ||
.credentialsProvider(systemPropertyCredentialsProvider()) | ||
.build(); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
carrotMarket/src/main/java/org/sopt/carrotMarket/external/S3Service.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package org.sopt.carrotMarket.external; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.web.multipart.MultipartFile; | ||
import software.amazon.awssdk.core.sync.RequestBody; | ||
import software.amazon.awssdk.services.s3.S3Client; | ||
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; | ||
import software.amazon.awssdk.services.s3.model.PutObjectRequest; | ||
|
||
import java.io.IOException; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
@Component | ||
public class S3Service { | ||
|
||
private final String bucketName; | ||
private final AwsConfig awsConfig; | ||
private static final List<String> IMAGE_EXTENSIONS = Arrays.asList("image/jpeg", "image/png", "image/jpg", "image/webp"); | ||
|
||
|
||
public S3Service(@Value("${aws-property.s3-bucket-name}") final String bucketName, AwsConfig awsConfig) { | ||
this.bucketName = bucketName; | ||
this.awsConfig = awsConfig; | ||
} | ||
|
||
|
||
public String uploadImage(String directoryPath, MultipartFile image) throws IOException { | ||
final String key = directoryPath + generateImageFileName(); | ||
final S3Client s3Client = awsConfig.getS3Client(); | ||
|
||
validateExtension(image); | ||
validateFileSize(image); | ||
|
||
PutObjectRequest request = PutObjectRequest.builder() | ||
.bucket(bucketName) | ||
.key(key) | ||
.contentType(image.getContentType()) | ||
.contentDisposition("inline") | ||
.build(); | ||
|
||
RequestBody requestBody = RequestBody.fromBytes(image.getBytes()); | ||
s3Client.putObject(request, requestBody); | ||
return key; | ||
} | ||
|
||
public void deleteImage(String key) throws IOException { | ||
final S3Client s3Client = awsConfig.getS3Client(); | ||
|
||
s3Client.deleteObject((DeleteObjectRequest.Builder builder) -> | ||
builder.bucket(bucketName) | ||
.key(key) | ||
.build() | ||
); | ||
} | ||
|
||
|
||
private String generateImageFileName() { | ||
return UUID.randomUUID() + ".jpg"; | ||
} | ||
|
||
|
||
private void validateExtension(MultipartFile image) { | ||
String contentType = image.getContentType(); | ||
if (!IMAGE_EXTENSIONS.contains(contentType)) { | ||
throw new RuntimeException("이미지 확장자는 jpg, png, webp만 가능합니다."); | ||
} | ||
} | ||
|
||
private static final Long MAX_FILE_SIZE = 5 * 1024 * 1024L; | ||
|
||
private void validateFileSize(MultipartFile image) { | ||
if (image.getSize() > MAX_FILE_SIZE) { | ||
throw new RuntimeException("이미지 사이즈는 5MB를 넘을 수 없습니다."); | ||
} | ||
} | ||
|
||
} |