-
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.
Merge branch 'test' into feature/#23
- Loading branch information
Showing
13 changed files
with
360 additions
and
18 deletions.
There are no files selected for viewing
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
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
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
4 changes: 4 additions & 0 deletions
4
linkmind/src/main/java/com/app/toaster/controller/request/toast/OgRequestDto.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,4 @@ | ||
package com.app.toaster.controller.request.toast; | ||
|
||
public record OgRequestDto(String linkUrl) { | ||
} |
7 changes: 7 additions & 0 deletions
7
linkmind/src/main/java/com/app/toaster/controller/response/parse/OgResponse.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,7 @@ | ||
package com.app.toaster.controller.response.parse; | ||
|
||
public record OgResponse(String titleAdvanced, String imageAdvanced) { | ||
public static OgResponse of(String titleAdvanced, String imageAdvanced){ | ||
return new OgResponse(titleAdvanced, imageAdvanced); | ||
} | ||
} |
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
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
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
Empty file.
49 changes: 49 additions & 0 deletions
49
linkmind/src/main/java/com/app/toaster/external/client/aws/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,49 @@ | ||
package com.app.toaster.external.client.aws; | ||
|
||
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(); | ||
} | ||
} |
125 changes: 125 additions & 0 deletions
125
linkmind/src/main/java/com/app/toaster/external/client/aws/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,125 @@ | ||
package com.app.toaster.external.client.aws; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStream; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.UUID; | ||
|
||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
|
||
import com.app.toaster.exception.Error; | ||
import com.app.toaster.exception.model.BadRequestException; | ||
import com.app.toaster.exception.model.NotFoundException; | ||
|
||
import jakarta.annotation.PostConstruct; | ||
import lombok.RequiredArgsConstructor; | ||
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; | ||
|
||
@Component | ||
public class S3Service { | ||
private final String bucketName; | ||
private final AWSConfig awsConfig; | ||
private static final Long MAX_FILE_SIZE = 5 * 1024 * 1024L; | ||
|
||
|
||
public S3Service(@Value("${aws-property.s3-bucket-name}") final String bucketName, AWSConfig awsConfig) { | ||
this.bucketName = bucketName; | ||
this.awsConfig = awsConfig; | ||
} | ||
|
||
public String uploadImage(MultipartFile multipartFile, String folder) { | ||
final String key = folder + createFileName(multipartFile.getOriginalFilename()); | ||
final S3Client s3Client = awsConfig.getS3Client(); | ||
|
||
validateFileSize(multipartFile); | ||
|
||
PutObjectRequest request = PutObjectRequest.builder() | ||
.bucket(bucketName) | ||
.key(key) | ||
.contentType(multipartFile.getContentType()) | ||
.contentLength(multipartFile.getSize()) | ||
.contentDisposition("inline") | ||
.build(); | ||
|
||
try { | ||
RequestBody requestBody = RequestBody.fromBytes(multipartFile.getBytes()); | ||
s3Client.putObject(request, requestBody); | ||
return key; | ||
} catch(IOException e) { | ||
throw new NotFoundException(Error.NOT_FOUND_IMAGE_EXCEPTION, Error.NOT_FOUND_IMAGE_EXCEPTION.getMessage()); | ||
} | ||
} | ||
|
||
public List<String> uploadImages(List<MultipartFile> multipartFileList, String folder) { | ||
final S3Client s3Client = awsConfig.getS3Client(); | ||
List<String> list = new ArrayList<>(); | ||
for (int i = 0; i < multipartFileList.size(); i++) { | ||
String key = folder + createFileName(multipartFileList.get(i).getOriginalFilename()); | ||
PutObjectRequest request = PutObjectRequest.builder() | ||
.bucket(bucketName) | ||
.key(key) | ||
.contentType(multipartFileList.get(i).getContentType()) | ||
.contentLength(multipartFileList.get(i).getSize()) | ||
.contentDisposition("inline") | ||
.build(); | ||
|
||
try { | ||
RequestBody requestBody = RequestBody.fromBytes(multipartFileList.get(i).getBytes()); | ||
s3Client.putObject(request, requestBody); | ||
list.add(key); | ||
} catch(IOException e) { | ||
throw new NotFoundException(Error.NOT_FOUND_IMAGE_EXCEPTION, Error.NOT_FOUND_IMAGE_EXCEPTION.getMessage()); | ||
} | ||
} | ||
return list; | ||
} | ||
|
||
// 파일명 (중복 방지) | ||
private String createFileName(String fileName) { | ||
return UUID.randomUUID().toString().concat(getFileExtension(fileName)); | ||
} | ||
|
||
// 파일 유효성 검사 | ||
private String getFileExtension(String fileName) { | ||
if (fileName.length() == 0) { | ||
throw new NotFoundException(Error.NOT_FOUND_IMAGE_EXCEPTION, Error.NOT_FOUND_IMAGE_EXCEPTION.getMessage()); | ||
} | ||
ArrayList<String> fileValidate = new ArrayList<>(); | ||
fileValidate.add(".jpg"); | ||
fileValidate.add(".jpeg"); | ||
fileValidate.add(".png"); | ||
fileValidate.add(".JPG"); | ||
fileValidate.add(".JPEG"); | ||
fileValidate.add(".PNG"); | ||
String idxFileName = fileName.substring(fileName.lastIndexOf(".")); | ||
if (!fileValidate.contains(idxFileName)) { | ||
throw new BadRequestException(Error.BAD_REQUEST_FILE_EXTENSION, Error.BAD_REQUEST_FILE_EXTENSION.getMessage()); | ||
} | ||
return fileName.substring(fileName.lastIndexOf(".")); | ||
} | ||
|
||
// 이미지 삭제 | ||
public void deleteImage(String key) throws IOException { | ||
final S3Client s3Client = awsConfig.getS3Client(); | ||
|
||
s3Client.deleteObject((DeleteObjectRequest.Builder builder) -> | ||
builder.bucket(bucketName) | ||
.key(key) | ||
.build() | ||
); | ||
} | ||
|
||
private void validateFileSize(MultipartFile image) { | ||
if (image.getSize() > MAX_FILE_SIZE) { | ||
throw new BadRequestException(Error.BAD_REQUEST_FILE_SIZE, Error.BAD_REQUEST_FILE_SIZE.getMessage()); | ||
} | ||
} | ||
} |
Oops, something went wrong.